Skip to content

feat(router): agent_guide_fetched analytics + dashboard recorder exclusion - #162

Merged
khaliqgant merged 3 commits into
mainfrom
feat/router-guide-analytics
Oct 8, 2026
Merged

khaliqgant merged 3 commits into
mainfrom
feat/router-guide-analytics

Conversation

@khaliqgant

@khaliqgant khaliqgant commented Oct 8, 2026 •

Copy link
Copy Markdown
Member

Router half of phase 1 of relay-agent's docs/ANALYTICS_BRIEF.md (relay-agent #11). Companion: AgentWorkforce/relay-agent#15.

What

  • Binding: ARELAY_ANALYTICS → Analytics Engine dataset arelay_agent_analytics (same dataset relay-agent writes).
  • agent_guide_fetched: written once per external GET that content-negotiated to /u/<handle>/agent.md (arelay.to, www.arelay.to, agentrelay.com/u/) and only after the upstream guide answered 2xx. HTML, HEAD, direct /u/<handle>/agent.md paths (no double count), Worker subrequests (cf-worker), redirects, 404, 410 and upstream errors write nothing. A 2xx guide implies the Registry resolved a known handle.
  • Schema: identical ordered v1 layout (router/src/analytics.ts) — delivery not_applicable, outcome none, latency -1, writer router. Same daily HMAC visitor pseudonym, with a known-answer digest pinned in both repos.
  • Privacy / fail-closed: no URL, query, grant, IP, UA or header value is written; without ANALYTICS_VISITOR_HASH_SECRET or the binding nothing is written; write failures never change the response.
  • Recorder: isAgentPageRequestPath now covers /u/<handle>/dashboard and subpaths, so the dashboard and any ?grant= exchange URL are never cloned or recorded (tested with a grant sentinel).
  • Deploy: deploy-router.yml syncs ANALYTICS_VISITOR_HASH_SECRET atomically: only present secrets are written to a 0600 file in $RUNNER_TEMP, passed to wrangler deploy --secrets-file (additive; omitted secrets are kept), and removed in an always() step. The existing wait-for-web-deploy gate (ci(router): deploy the router only after this commit's web deploy succeeds #154) is unchanged.

Tests

router/test/guide-analytics.test.ts covers both hosts, HTML, HEAD, subrequests, 301/302/404/410/500/503, no secret, no binding, throwing writes, sentinel privacy, dashboard and grant recorder exclusion, schema parity, client classes, cf.country vs spoofed headers, and pseudonym rotation. Router: 127 tests pass and tsc is clean.

🤖 Generated with Claude Code


Note

Medium Risk
Touches every proxied guide request path and deploy-time secret handling; analytics is best-effort but recorder exclusions change what traffic is stored for replay.

Overview
Adds server-side agent_guide_fetched analytics on the edge router: after a content-negotiated external GET reaches /u/<handle>/agent.md and the upstream returns 2xx, the worker writes one v1 Analytics Engine point (client class, cf.country, daily HMAC visitor pseudonym) via new router/src/analytics.ts and the ARELAY_ANALYTICS binding. HTML/HEAD, direct guide URLs, Worker subrequests, and non-2xx responses are skipped; missing secret or binding fails closed without affecting responses.

Traffic recorder exclusions widen: the whole /u/ namespace is treated as agent-page traffic (covering dashboards), and any URL with a grant query param is never cloned—so dashboard bearer tokens stay out of the replay corpus.

Deploy now optionally syncs ANALYTICS_VISITOR_HASH_SECRET through a short-lived 0600 JSON file and wrangler deploy --secrets-file, with cleanup in an always() step.

Reviewed by Cursor Bugbot for commit 2f5e0e9. Bugbot is set up for automated code reviews on this repo. Configure here.


Summary by cubic

Adds server-side analytics to the router: one agent_guide_fetched data point is written per external GET that negotiated to /u/<handle>/agent.md and got a 2xx upstream. HTML, HEAD, direct guide paths, Worker subrequests, redirects, 404/410, and upstream errors write nothing; the schema matches relay-agent's v1 layout, including the daily HMAC visitor pseudonym and a client class and country read from the original request's cf, never from caller-controlled headers.

The traffic recorder now skips the entire /u/ namespace and any URL carrying a grant parameter, so dashboard requests and grant exchange URLs are never cloned or recorded. Analytics fail closed: no binding or no secret means no writes, and write failures never alter the response.

Deploy

  • deploy-router.yml syncs ANALYTICS_VISITOR_HASH_SECRET atomically via a 0600 secrets file in $RUNNER_TEMP, passed to wrangler deploy --secrets-file and removed in an always() step.

Written for commit 2f5e0e9. Summary will update on new commits.

View guided diff Turn on auto-fix


Agent Relay sessions

  • claude session 8fa30995 · opened via gh pr create · last active 2026-10-08

The router's half of relay-agent docs/ANALYTICS_BRIEF.md (phase 1):

- ARELAY_ANALYTICS binding to the shared arelay_agent_analytics dataset.
- One agent_guide_fetched data point per external GET that negotiated to
  /u/<handle>/agent.md and whose upstream answered 2xx; HTML, HEAD, direct
  guide paths, Worker subrequests, redirects, 404, 410 and errors write
  nothing. Same ordered v1 schema and daily HMAC visitor pseudonym as
  relay-agent, with a pinned known-answer test.
- Fails closed (no write) without ANALYTICS_VISITOR_HASH_SECRET or the
  binding; never changes a response.
- The traffic recorder now excludes /u/<handle>/dashboard (and subpaths), so
  dashboard requests and ?grant= URLs are never cloned or recorded.
- deploy-router.yml syncs ANALYTICS_VISITOR_HASH_SECRET atomically via
  wrangler deploy --secrets-file from a 0600 runner-temp file, removed in an
  always() cleanup.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Session-Id: 8fa30995-3394-4357-aadf-23aee1464578
@coderabbitai

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a02e9a39-94f2-4661-96e9-6341bceeffcc
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-08T06:54:48.523351Z c481f18 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

1 flag not posted on this PR by your GitHub settings — view it in Devin Review. (Configure)

Devin Review

Comment thread router/index.ts Outdated
…order

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Session-Id: 8fa30995-3394-4357-aadf-23aee1464578

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed against the latest diff

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

Comment thread .github/workflows/deploy-router.yml

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 5 files

View guided diff | Turn on auto-fix | Re-trigger cubic

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit ccac57e. Configure here.

Comment thread router/index.ts
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Session-Id: 8fa30995-3394-4357-aadf-23aee1464578
@khaliqgant
khaliqgant merged commit bdf187e into main Oct 8, 2026
5 checks passed
@khaliqgant
khaliqgant deleted the feat/router-guide-analytics branch October 8, 2026 07:33
@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

Preview deployed!

Environment URL
Web https://84ddc36e-agentrelay-web.agent-workforce.workers.dev

This is a Cloudflare Workers preview version of this PR's build.

khaliqgant added a commit that referenced this pull request Oct 8, 2026
…ommit (#165)

* ci(router): accept a later successful web deploy that includes this commit

A newer push supersedes a queued web deploy in its concurrency group, so a
router run waiting for its own commit's web deploy saw it cancelled and gave
up (#162's router never shipped). Ship once any successful web deploy of this
commit or a descendant exists; still refuse if this commit's own web deploy
failed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* ci(router): deploy the accepted revision; a lookup error never releases

- Check out the revision whose web deploy succeeded (this commit or the later
  one that contains it), so router and pages always match.
- Only look for a later deploy after this commit's own deploy was read and
  is not a failure; a transient lookup error just retries.
- An identical SHA is accepted through the same path.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* ci(router): a failed gh api lookup replaces the value instead of appending

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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 merging this pull request may close these issues.

1 participant