docs(connect): held webhooks are kept per managed link#23612
Problem
The held-webhooks paragraphs of docs/internals/t3-connect.md say the relay stores offline webhook requests in one Durable Object per environment, deletes them "when no user has the environment linked", and orders and caps them per environment. The relay actually keeps one HookInboxObject per managed link, named by that link's endpoint key (infra/relay/src/worker.ts getByName(endpointKey)). Unlinking clears only that link's inbox, and turning hold_webhooks_while_offline off clears the inboxes of every link the environment's key proves. The doc never mentioned that second case.
Change
Rewrite those paragraphs to match the relay. Held requests are stored, ordered and capped per managed link (endpoint key), so each account that links an environment gets its own inbox. Wake delivers to each of the environment's links. Requests are deleted once answered, after 24 hours, when their link is unlinked, or when the environment turns holding off. The Durable Object rationale now says per-link. Only docs change.
Scope and approval
Fixes #16995 GitCafe: https://git.cafe/pingdotgg/t3code/issues/16995 Triaged bug via the automated issue flow. A maintainer confirmed the mismatch on the issue. The separate path-segment error on lines 7-8 of the same doc is https://git.cafe/pingdotgg/t3code/issues/16988 and is not changed here.
Verification
- Checked every new sentence against
infra/relay/src/worker.ts,hooks/HeldHooks.ts(ownEndpointKeys,setHoldWhileOffline,wake),hooks/HookInboxStore.ts(caps and TTL),http/Api.ts(unlink clear) andenvironments/EnvironmentLinks.ts(setHoldWebhooksWhileOffline). vp test run src/hooks/HeldHooks.test.ts src/http/Api.test.tsininfra/relay: 2 files, 28 tests passed, includingHeldHooks > opting out clears only the caller's own endpointsandrelay environment unlink > drops the unlinked endpoint's held webhooks, even if clearing fails.- Nothing visible changes, so there are no screenshots. A deployed relay with two accounts linking one environment was not exercised.
🤖 Generated with Claude Code (Claude Opus 5.5, T3 Code)
Verification log
- 2026-10-22, docs fact-check at
25691d06ee, read-only (T3 Code, Claude Code):- A, claude-sonnet-5-5: VERDICT: MERGE. Every changed sentence is true against
infra/relay/src(worker.tsgetByName(endpointKey);HookInboxStore.tscaps of 1,000 requests, 100 per hook and 50 MiB per object, 24 h TTL,ORDER BY seq;HeldHooks.tswakeandsetHoldWhileOffline;Api.tsunlink clear). Nothing true was dropped: "when no user has the environment linked" was stale and "when their link is unlinked" replaces it. Low: "which clears every link it proved" uses internal jargon. Nit: "bodies of up to 1 MiB" is a per-request limit, separate from the 50 MiB per-object total. - B, claude-opus-5-5: VERDICT: MERGE. No false claims. One object per link is confirmed, and so are per-object caps, oldest-first delivery with backoff, wake to each of the environment's own endpoint keys, 1 MiB
RELAY_HOOK_MAX_BODY_BYTES, and all four deletion triggers. Low: "proved" is unexplained. Informational: the unlink clear is best effort (logged and swallowed, with the 24 h TTL as backstop), and the TTL only takes effect on the next alarm run. The fit with the docs/internals rules is fine. The Queues 128 KB claim is external and was not checked by either reviewer.
- A, claude-sonnet-5-5: VERDICT: MERGE. Every changed sentence is true against
Checks
- SuccessfulCodeRabbitGitHub
Review completed
- SuccessfulNative fingerprint diffGitHub
- Skipped
- SkippedRemove preview downloadGitHub
- Skipped
- Skipped
- SkippedBuild preview JS bundleGitHub
- SkippedDeploy web previewGitHub
- SkippedEAS PreviewGitHub
- SuccessfulNative fingerprint diffGitHub
- Skipped
- Skipped
- SkippedBuild preview JS bundleGitHub
- Skipped
- SkippedRemove preview downloadGitHub
- SkippedDeploy web previewGitHub
- SkippedEAS PreviewGitHub
- SkippedDeploy web previewGitHub
- SkippedEAS PreviewGitHub
- SkippedBuild preview JS bundleGitHub
- SkippedBuild preview JS bundleGitHub
- SkippedDeploy web previewGitHub
- SkippedEAS PreviewGitHub
- SuccessfulCheckGitHub
- SkippedTestGitHub
- Skipped
- SkippedTest WebGitHub
- SkippedRelease SmokeGitHub
- SkippedRustGitHub
- SkippedBuild and TypecheckGitHub
- SkippedEAS PreviewGitHub
- SuccessfulLabel PR 23612GitHub
- Skipped
- SuccessfulLabel PR sizeGitHub
- Successful
- SuccessfulPrepare PR size configGitHub
- SuccessfulCollect PR targetsGitHub
- Successful
- SuccessfulTest Server 1GitHub
- SuccessfulTest Server 2GitHub
- SuccessfulTest Server 4GitHub
- SuccessfulTest Server 6GitHub
- SuccessfulTest Server 7GitHub
- SuccessfulTest Server 5GitHub
- SuccessfulLintGitHub
- SuccessfulTest Server 3GitHub
- SuccessfulTest Server 8GitHub
- SuccessfulChangesGitHub
- SuccessfulNative fingerprint diffGitHub
Added 2 commits
Approvability
Verdict: Approved at 25691d0
Macroscope's review found this PR approvable — This PR only corrects the T3 Connect documentation to describe held webhooks as being stored and managed per managed link. No executable code, configuration, defaults, or production behavior is changed.
You can add or adjust custom eligibility rules. Learn more.
No actionable comments were generated in the recent review. 🎉
ℹ️ Recent review info
⚙️ Run configuration
- Source mode: Auto
- Repository: pingdotgg/t3code
- Branch: fix/issue-16995
- File: .coderabbit.config.ts
- Commit: 25691d0
- Layers: Repository TS config
- Review profile: CHILL
- Plan: Team
- Run ID:
d86a16ef-58f5-4ed6-8dc5-cb27cf738ba2
📥 Commits
Reviewing files that changed from the base of the PR and between ed3f965e0768f9a77729a17c5145a90ff3ab6210 and 25691d06ee693ee00459f1be834dc9ad6439165b.
📒 Files selected for processing: 1
docs/internals/t3-connect.md
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 0 remain after this review.
📝 Walkthrough
The T3 Connect documentation now describes held webhook storage, ordering, and caps per managed link. It also lists cleanup when a link is unlinked, holding is disabled, a request is delivered, or 24 hours pass.
Changes: Held webhook documentation
Layer / File(s) Summary Per-link storage and cleanup
docs/internals/t3-connect.mdThe documentation describes a separate inbox for each managed link and updates the cleanup conditions and storage rationale. Priority: ⬇️ Low
Estimated code review effort: 1 (Trivial) | ~5 minutes
Change: Other · Severity of issue fixed: Low
Merge Risk: ⚪ Minimal · up to 25691
No actionable merge-blocking risk was identified.
Pre-merge checks: Passed 4
Check name Status Explanation Title check Passed The title clearly and concisely describes the main documentation change: held webhooks are scoped per managed link. Linked Issues check Passed The linked issue #16995requires a documentation-only correction. The diff states that held requests use one Durable Object per managed link, keyed by endpoint key, with separate order and caps. It st…Out of Scope Changes check Passed The pull request changes only docs/internals/t3-connect.md. The changed paragraphs directly implement #16995. No relay behavior, unrelated path correction, or unrelated product change appears in the r…Description check Passed The description includes all required sections. It explains the problem, the documentation change, scope and issue approval, and focused verification results, including the untested deployed scenario. Full details: Linked Issues check
Explanation
The linked issue
#16995requires a documentation-only correction. The diff states that held requests use one Durable Object per managed link, keyed by endpoint key, with separate order and caps. It states delivery to each link and deletion after delivery, 24 hours, unlink, or holding being turned off. The diff also preserves the separate path-segment text, so it does not take on#16988.
Full details: Out of Scope Changes check
Explanation
The pull request changes only docs/internals/t3-connect.md. The changed paragraphs directly implement
#16995. No relay behavior, unrelated path correction, or unrelated product change appears in the reviewed diff.
✨ Finishing Touches
🧪 Generate unit tests (beta)
- Commit to this branch
- Create a new PR
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Comment @coderabbitai help to get the list of available commands.