8000 Mission layer M9.6: GA4 telemetry (opt-in, informs goals, never a gate) by adeelahmad · Pull Request #71 · adeelahmad/aloop · GitHub
[go: up one dir, main page]

Skip to content

Mission layer M9.6: GA4 telemetry (opt-in, informs goals, never a gate) - #71

Merged
adeelahmad merged 3 commits into
masterfrom
claude/m9-telemetry-9jviy9
Oct 20, 2026
Merged

adeelahmad merged 3 commits into
masterfrom
claude/m9-telemetry-9jviy9

Conversation

@adeelahmad
@adeelahmad adeelahmad commented Oct 20, 2026 •
Copy link
Copy Markdown
Owner

Requested by Adeel · project thread

Before: the mission layer had no way to see real usage; ROADMAP §4.12 listed M9.6 (GA4 telemetry) as open.

After: aloop mission telemetry drafts consent terms, records a human's opt-in, sets up Google Analytics 4 through the Admin API, proves the wiring with a validated debug hit, reads fixed Data API reports scoped to its own stream, and says how much of the next goal usage may drive. Usage never gates anything; the check is structural only.

How:

  • Opt-in. init --uri URL writes a sealed record with the terms (what is measured, why, what agents see, the credential used, Google's verbatim user-data acknowledgement, OAuth scopes). consent --by NAME is a telemetry.consent event naming the terms' sha256. Only role=human events count (a supervisor-written consent is ignored; full provenance rides M9.17). revoke stops agents, deletes the local MP secret, and says plainly that the app's tag keeps sending until it is removed (check names the files still carrying it). A hand-edited record blocks every command; nothing reseals it silently.
  • Setup (Admin API, idempotent). --account/--property pick explicitly; otherwise it finds or creates the property (none or several accounts is the human's call), acknowledges user-data collection, finds or creates the web stream, a Measurement Protocol secret (0600 in .aladdin/state/, never in docs/), and a key event for each active journey's last step. Progress is saved after each step. A lost recorded property asks rather than silently creating a new one. init --force with a new uri drops the old stream.
  • Debug hit. Proves the local secret is live on the stream through the Admin API (the MP validator does not check secrets), then validates every active journey step's event in batches of ≤25 with ENFORCE_RECOMMENDATIONS. No OAuth token goes to the MP endpoint.
  • Reports. Fixed definitions (hashed into every report), every request filtered by streamId: users and journey events over 28 days ending 3 days ago (settled, ≥48h), or realtime as a quick signal. Aggregate dimensions only.
  • Minimum-sample rule (code). Usage drives 0 below 50 users over 28 days, when GA thresholded the data, or for realtime data; else 0.7, with research keeping 0.3. latest_share(cwd) (for M9.11) reads only sealed reports for the current record and stream.
  • Check. Consent covers the current terms; once consented, every active journey step's event is a quoted literal in non-test code of the worker's own worktree; once configured, the page carries the measurement id, key events match the journeys, and a fresh passing debug hit covers the current events.
  • Hardening. --help anywhere and unknown flags never touch the network (64). ALADDIN_GA_BASE accepts loopback only, no userinfo, no proxy, and redirects are refused so the bearer token never leaves.
  • Auth. mission telemetry auth prints one-time steps: a service account the owner can impersonate (gcloud auth application-default login --impersonate-service-account), so there is no 7-day refresh-token expiry and no gcloud client scope block. 401, bad scopes, API-off and 403 each ask with the exact fix.

Evidence: scripts/test/mission-telemetry.test.py (13 checks) against scripts/test/fixtures/fake-ga.py, a threaded loopback fake of the Admin API, Data API and MP validation server (redirect, thresholding, injected MP messages). make test-hosts (includes all mission-* suites), make test, make pycheck, check-tracking.py and readme.test.py pass locally.

Live run on a real Google account is M9.14 (needs the owner's one sign-in).

🤖 Generated with Claude Code

https://claude.ai/code/session_012Ro7iYo3scQt6vAuAWdYpV

mission telemetry init/consent/revoke/auth/setup/debug-hit/report/share/show/check.
Consent is a human event on the exact terms; setup goes through the Admin API
(property, user-data acknowledgement, web stream, MP secret outside docs/, key
events); the debug hit validates journey events; fixed Data API reports read
settled data; the minimum-sample rule decides usage's share. Tests run against
a local fake of the GA APIs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Ro7iYo3scQt6vAuAWdYpV
@adeelahmad adeelahmad self-assigned this Oct 20, 2026
Consent counts only human events and must match the sealed terms;
reports and the debug hit are scoped to the recorded stream; redirects
are refused so the token never leaves loopback; --help and unknown
flags never touch the network; the emit check scans the worker's own
worktree; revoke deletes the local secret and names the live tag.
Sign-in moves to service-account impersonation (no 7-day refresh).
The suite grows to 13 checks against the fake GA.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012Ro7iYo3scQt6vAuAWdYpV
@adeelahmad
adeelahmad marked this pull request as ready for review October 20, 2026 02:49
@adeelahmad
adeelahmad merged commit 5a7e524 into master Oct 20, 2026
5 checks passed
adeelahmad pushed a commit that referenced this pull request Oct 20, 2026
events emit now refuses telemetry.consent like every approval, so the
telemetry test's forged consent is refused and then appended directly;
it is still ignored as non-human.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012rsDo9GYzNx8tXucywZHnA
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merg 3BE1 ing this pull request may close these issues.

2 participants

0