Webhook docs#128
Conversation
khaliqgant
commented
May 9, 2026
- webhooks for agents
📝 WalkthroughWalkthroughThis PR adds documentation for the webhooks-for-agents architecture, updates the relayfile-v1-spec diagram to include relaycast notifications, adds a new docs/webhooks-for-agents.md page describing ingestion/normalization/journaling/VFS/Relaycast flows, updates site content, and adds three completed trajectory records plus an updated trajectories index. ChangesWebhooks-for-Agents Architecture Documentation
Estimated code review effort🎯 1 (Trivial) | ⏱️ ~3 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.trajectories/completed/2026-05/traj_5v9cm2tk0ngw.md:
- Line 31: Remove the duplicated sentence fragment that repeats the phrase
"Resolved Cloud PR 511 merge by preserving branch by-state cataloging exports,
taking main layout tests, and bumping relayfile adapters to 0.2.2 for delete
writeback exports" so the chapter bullet contains only a single instance of that
statement; edit the .trajectories/completed/2026-05/traj_5v9cm2tk0ngw.md content
to delete the redundant copy and leave the phrase once.
In @.trajectories/completed/2026-05/traj_bwiry6f64438.json:
- Line 19: The committed trajectory metadata contains a machine-specific
absolute path in the "projectId" field; replace the value of projectId with a
repo-relative value like "." or remove the projectId entry entirely from the
artifact to avoid leaking user-specific paths, and re-generate/commit the
cleaned trajectory so the VCS history does not contain the local absolute path.
In @.trajectories/index.json:
- Around line 253-265: The "path" values for traj_5v9cm2tk0ngw and
traj_bwiry6f64438 currently contain absolute local paths with a username; update
those entries so the "path" fields use repo-relative paths (e.g.
".trajectories/completed/2026-05/traj_5v9cm2tk0ngw.json" and
".trajectories/completed/2026-05/traj_bwiry6f64438.json") to match the format
used by other index entries and avoid leaking environment details.
In `@docs/relayfile-v1-spec.md`:
- Line 71: The fenced code block opened at the triple backticks on line 71 in
docs/relayfile-v1-spec.md lacks a language spec causing markdownlint MD040;
update the opening fence to include a language (e.g., change ``` to ```text) so
the block becomes a labeled text block and preserves the existing content and
closing fence.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 6c22fd80-972a-4f77-9ca7-37a0ce9415ac
📒 Files selected for processing (10)
.trajectories/completed/2026-05/traj_5v9cm2tk0ngw.json.trajectories/completed/2026-05/traj_5v9cm2tk0ngw.md.trajectories/completed/2026-05/traj_bwiry6f64438.json.trajectories/completed/2026-05/traj_bwiry6f64438.md.trajectories/completed/2026-05/traj_mi7u0mbgiwk5.json.trajectories/completed/2026-05/traj_mi7u0mbgiwk5.md.trajectories/index.jsondocs/relayfile-v1-spec.mddocs/webhooks-for-agents.mdsite/CONTENT.md
| ### 1. Work | ||
| *Agent: default* | ||
|
|
||
| - Resolved Cloud PR 511 merge by preserving branch by-state cataloging exports, taking main layout tests, and bumping relayfile adapters to 0.2.2 for delete writeback exports: Resolved Cloud PR 511 merge by preserving branch by-state cataloging exports, taking main layout tests, and bumping relayfile adapters to 0.2.2 for delete writeback exports |
There was a problem hiding this comment.
Remove duplicated sentence fragment in chapter bullet
Line 31 repeats the same phrase twice, which hurts readability of the trajectory record. Keep only one copy of the statement.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.trajectories/completed/2026-05/traj_5v9cm2tk0ngw.md at line 31, Remove the
duplicated sentence fragment that repeats the phrase "Resolved Cloud PR 511
merge by preserving branch by-state cataloging exports, taking main layout
tests, and bumping relayfile adapters to 0.2.2 for delete writeback exports" so
the chapter bullet contains only a single instance of that statement; edit the
.trajectories/completed/2026-05/traj_5v9cm2tk0ngw.md content to delete the
redundant copy and leave the phrase once.
| }, | ||
| "commits": [], | ||
| "filesChanged": [], | ||
| "projectId": "/Users/khaliqgant/Projects/AgentWorkforce/relayfile", |
There was a problem hiding this comment.
Remove local absolute path from committed trajectory metadata
Line 19 leaks machine-specific path data (/Users/...) and embeds user-identifying info in VCS history. Use a repo-relative value (e.g., ".") or omit projectId from committed artifacts.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.trajectories/completed/2026-05/traj_bwiry6f64438.json at line 19, The
committed trajectory metadata contains a machine-specific absolute path in the
"projectId" field; replace the value of projectId with a repo-relative value
like "." or remove the projectId entry entirely from the artifact to avoid
leaking user-specific paths, and re-generate/commit the cleaned trajectory so
the VCS history does not contain the local absolute path.
| "traj_5v9cm2tk0ngw": { | ||
| "title": "Address cloud PR 511 feedback", | ||
| "status": "completed", | ||
| "startedAt": "2026-05-09T20:08:19.736Z", | ||
| "completedAt": "2026-05-09T20:14:24.560Z", | ||
| "path": "/Users/khaliqgant/Projects/AgentWorkforce/relayfile/.trajectories/completed/2026-05/traj_5v9cm2tk0ngw.json" | ||
| }, | ||
| "traj_bwiry6f64438": { | ||
| "title": "Fix Cloud PR 511 Next build", | ||
| "status": "completed", | ||
| "startedAt": "2026-05-09T20:18:13.403Z", | ||
| "completedAt": "2026-05-09T20:20:02.156Z", | ||
| "path": "/Users/khaliqgant/Projects/AgentWorkforce/relayfile/.trajectories/completed/2026-05/traj_bwiry6f64438.json" |
There was a problem hiding this comment.
Normalize trajectory paths to repo-relative values
Lines 258 and 265 add absolute local paths with usernames, which leak environment details and make the index non-portable across machines/CI. Store .trajectories/... relative paths consistently (as done in other entries).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In @.trajectories/index.json around lines 253 - 265, The "path" values for
traj_5v9cm2tk0ngw and traj_bwiry6f64438 currently contain absolute local paths
with a username; update those entries so the "path" fields use repo-relative
paths (e.g. ".trajectories/completed/2026-05/traj_5v9cm2tk0ngw.json" and
".trajectories/completed/2026-05/traj_bwiry6f64438.json") to match the format
used by other index entries and avoid leaking environment details.
|
|
||
| ## 6. High-Level Architecture | ||
|
|
||
| ``` |
There was a problem hiding this comment.
Add a language to the fenced architecture block (markdownlint MD040).
Line 71 opens a fenced block without a language. Please use a language like text to satisfy linting and keep docs CI clean.
Proposed fix
-```
+```text
External Provider Webhooks
|
v
...
-```
+```🧰 Tools
🪛 markdownlint-cli2 (0.22.1)
[warning] 71-71: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/relayfile-v1-spec.md` at line 71, The fenced code block opened at the
triple backticks on line 71 in docs/relayfile-v1-spec.md lacks a language spec
causing markdownlint MD040; update the opening fence to include a language
(e.g., change ``` to ```text) so the block becomes a labeled text block and
preserves the existing content and closing fence.
…webhook burden Documents what an agent must do today to receive webhooks (8 steps, per provider, still ends up with a raw blob). Contrasts with relayfile's model where the agent exposes no endpoints, verifies no signatures, and registers with no providers — it connects to its workspace and events arrive. Provider complexity lives in the relayfile catalog once, not in every agent team's codebase repeatedly. https://claude.ai/code/session_01Lbmw1Cj23tw8LovrfFpv24
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/webhooks-for-agents.md`:
- Around line 13-24: The diagram and accompanying paragraph are ambiguous about
whether Nango or Hookdeck terminates provider traffic first; update the flow
block and the explanatory text so they consistently state the ingress order
(choose and document one canonical flow, e.g., "Provider -> Hookdeck edge
gateway -> Nango webhook endpoint -> Cloud webhook ingress" if Hookdeck is the
true edge, or the reverse if Nango must handle auth/signature first), and
explicitly indicate where provider retries, signature verification, and
connection attribution occur; edit the diagram lines ("Nango webhook endpoint",
"Hookdeck edge gateway") and the paragraph that begins "Nango remains useful
for..." to clearly assign responsibilities (edge termination/retries to
Hookdeck, auth/signature/attribution to Nango, and Cloud to verify/journal) so
there is no ambiguity.
- Around line 64-89: The doc mixes cased variants like "relayfile", "Relayfile",
and "relayfile's"; normalize every occurrence to the canonical product casing
"RelayFile" (use "RelayFile's" where possessive is needed) so all references in
the page are consistent, including headings and inline mentions such as the
section titled "The Relayfile Difference" and all occurrences in the bullet list
and paragraphs.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: dda6e14f-2c54-478c-a6f7-c17ea9d6c4b1
📒 Files selected for processing (1)
docs/webhooks-for-agents.md
| ```text | ||
| Provider webhook | ||
| -> Nango webhook endpoint | ||
| -> Hookdeck edge gateway | ||
| -> Cloud webhook ingress | ||
| -> durable raw event journal | ||
| -> provider-aware normalization workers | ||
| -> RelayFile VFS updates | ||
| -> Relaycast agent notifications | ||
| ``` | ||
|
|
||
| Nango remains useful for provider auth, connection attribution, provider-specific webhook URLs, and forwarded webhook signatures. Hookdeck absorbs webhook delivery risk before traffic reaches Cloud. Cloud verifies Nango signatures and journals each event before any business logic runs. RelayFile turns normalized events into files, revisions, relations, and replayable sync history. Relaycast can broadcast the meaningful parts to agent teams. |
There was a problem hiding this comment.
Clarify Nango vs Hookdeck ingress order to avoid architecture ambiguity.
The current flow shows Nango -> Hookdeck, but the text also frames Hookdeck as the edge ingress. This ambiguity can lead to incorrect implementation boundaries (who terminates provider traffic first, where retries/signatures are handled).
Suggested doc patch
-Provider webhook
- -> Nango webhook endpoint
- -> Hookdeck edge gateway
+Provider webhook
+ -> Hookdeck edge gateway
+ -> Nango connection attribution/signature context
-> Cloud webhook ingress
-> durable raw event journal
-> provider-aware normalization workers
-> RelayFile VFS updates
-> Relaycast agent notifications-Nango remains useful for provider auth, connection attribution, provider-specific webhook URLs, and forwarded webhook signatures. Hookdeck absorbs webhook delivery risk before traffic reaches Cloud.
+Nango remains useful for provider auth, connection attribution, provider-specific webhook URL management, and forwarded signature context. Hookdeck is the public ingress and absorbs webhook delivery risk before traffic reaches Cloud.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/webhooks-for-agents.md` around lines 13 - 24, The diagram and
accompanying paragraph are ambiguous about whether Nango or Hookdeck terminates
provider traffic first; update the flow block and the explanatory text so they
consistently state the ingress order (choose and document one canonical flow,
e.g., "Provider -> Hookdeck edge gateway -> Nango webhook endpoint -> Cloud
webhook ingress" if Hookdeck is the true edge, or the reverse if Nango must
handle auth/signature first), and explicitly indicate where provider retries,
signature verification, and connection attribution occur; edit the diagram lines
("Nango webhook endpoint", "Hookdeck edge gateway") and the paragraph that
begins "Nango remains useful for..." to clearly assign responsibilities (edge
termination/retries to Hookdeck, auth/signature/attribution to Nango, and Cloud
to verify/journal) so there is no ambiguity.
| Cloudflare's agents documentation shows what receiving a webhook requires without relayfile: | ||
|
|
||
| 1. Expose an HTTP endpoint with a public URL | ||
| 2. Verify the provider's HMAC signature — different header name, algorithm, and format per provider | ||
| 3. Return HTTP 200 within seconds to prevent the provider from retrying | ||
| 4. Extract an entity identifier from the URL, headers, or JSON body to route the right agent instance | ||
| 5. Persist the raw payload to a database | ||
| 6. Deduplicate against already-processed event IDs | ||
| 7. Parse the raw JSON and implement provider-specific logic to understand what changed | ||
| 8. Broadcast relevant state changes to connected clients | ||
|
|
||
| This is per provider. GitHub, Stripe, Slack, Jira, Linear, and Notion all use different signature headers, different retry behaviors, different payload schemas, and different registration flows. Each provider requires its own endpoint, its own verification logic, and its own parsing code. | ||
|
|
||
| After all of that, the agent still only knows "the HTTP delivery arrived." It has a raw JSON blob. It still has to figure out what changed, which of its working files are affected, and what to do next. | ||
|
|
||
| Most teams building agent products implement this once, get it mostly right, and never revisit it. The result is a brittle custom pipeline that handles two or three providers, has no replay capability, and breaks silently when providers change their schemas. | ||
|
|
||
| ## The Relayfile Difference: No Webhooks for the Agent | ||
|
|
||
| From the agent's perspective, relayfile eliminates webhook infrastructure entirely. | ||
|
|
||
| The agent does not expose endpoints. It does not verify signatures. It does not register with providers. It does not write deduplication logic or build routing tables. | ||
|
|
||
| The agent connects to its workspace. When something changes in an external system — a Jira issue is updated, a GitHub PR is merged, a Linear ticket is reassigned — the agent receives a structured notification through the workspace's existing connection. The affected files are already updated in the VFS. The event is already in the journal. The agent reads what changed and acts. | ||
|
|
||
| The entire provider-specific layer — endpoint registration, signature verification, retry handling, payload normalization, entity routing — is handled by the relayfile pipeline once, and never surfaces to the agent at all. |
There was a problem hiding this comment.
Use consistent product casing (RelayFile) throughout the page.
There are mixed forms (relayfile, Relayfile, relayfile's) that should be normalized to RelayFile for consistency.
Suggested doc patch
-Cloudflare's agents documentation shows what receiving a webhook requires without relayfile:
+Cloudflare's agents documentation shows what receiving a webhook requires without RelayFile:
-## The Relayfile Difference: No Webhooks for the Agent
+## The RelayFile Difference: No Webhooks for the Agent
-The entire provider-specific layer ... is handled by the relayfile pipeline once...
+The entire provider-specific layer ... is handled by the RelayFile pipeline once...
-This is the correct split: the complexity lives in relayfile's provider catalog once...
+This is the correct split: the complexity lives in RelayFile's provider catalog once...🧰 Tools
🪛 LanguageTool
[style] ~85-~85: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...s. It does not register with providers. It does not write deduplication logic or b...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/webhooks-for-agents.md` around lines 64 - 89, The doc mixes cased
variants like "relayfile", "Relayfile", and "relayfile's"; normalize every
occurrence to the canonical product casing "RelayFile" (use "RelayFile's" where
possessive is needed) so all references in the page are consistent, including
headings and inline mentions such as the section titled "The Relayfile
Difference" and all occurrences in the bullet list and paragraphs.