docs(skills): document mutate-last idempotency contract (#744)#745
Merged
Conversation
Addresses the audit question in #744: should `recovery: terminal` errors cache on replay, or keep release-all-errors? Audit conclusion: keep release-all-errors (most AdCP terminals are state-dependent; caching would return stale errors post-remediation). Document the handler-author implication that #743 widened the surface for. - skills/build-seller-agent: new "mutate last" paragraph in the idempotency section, with broken-vs-correct budget-approval example and guidance for partial-write paths. - skills/build-creative-agent: swap the now-stale "throw surfaces as SERVICE_UNAVAILABLE" rationale (invalidated by #743's auto-unwrap) for the still-true claim-release rationale. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced Apr 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Audit from #744 (should
recovery: terminalerrors cache instead of release the idempotency claim?) — conclusion: keep release-all-errors, document the handler-author contract that #743 widened the surface for.Audit reasoning
create-adcp-server.ts:1865-1936): success →idempotency.save; any error (isError: trueenvelope OR throw) →idempotency.release.recovery: terminalcatalog is mostly state-dependent —ACCOUNT_SUSPENDED,BUDGET_EXHAUSTED,ACCOUNT_PAYMENT_REQUIRED,ACCOUNT_SETUP_REQUIREDall flip after out-of-band remediation. Caching them would return stale errors for the full replay TTL — worse UX than re-executing.UNSUPPORTED_FEATUREandACCOUNT_NOT_FOUNDare truly immutable, and re-executing them is cheap (capability check, lookup).await db.insert(...); throw adcpError(...)) is a handler-correctness issue, not a dispatcher issue. feat(server): auto-unwrap thrown adcpError envelopes in dispatcher #743 blessesthrow adcpError(...)as a supported path, which widens that surface — so the mutate-last contract needs to be explicit in the skill corpus.Changes
skills/build-seller-agent/SKILL.mdidempotency section — extends the existing "only caches successful responses" bullet with the terminal-catalog rationale, then adds a new "Handler contract: mutate last" paragraph with a workedbudgetApprovedbroken-vs-correct example and guidance for rare partial-write paths (natural-key upsert,ctx.store.get→ merge).skills/build-creative-agent/SKILL.md:367— swaps the now-stale "throw adcpError(...)bypasses the envelope and surfaces SERVICE_UNAVAILABLE" comment (invalidated by feat(server): auto-unwrap thrown adcpError envelopes in dispatcher #743's auto-unwrap) for the still-true claim-release rationale.@adcp/client), docs-only.What's NOT in this PR
compliance/cache/latest/universal/idempotency.yaml. That file is machine-synced fromadcontextprotocol/adcpvianpm run sync-schemas— any local edit is clobbered on the next sync. Locking error-claim-release semantics in as a spec-level conformance invariant belongs upstream. Filed as adcontextprotocol/adcp#2760 — proposes either a newerror_claim_releasephase (usingcomply_test_controllerto force a terminal error, then retrying with the same key + different payload, asserting the second request executes) or a narrative-bullet + reviewer-checklist variant if the controller hook is too invasive.Test plan
npm run typecheckclean (pre-push hook)npm run build:libclean (pre-push hook)Related
🤖 Generated with Claude Code