feat(compliance): v3 envelope integrity — schema constraint + storyboard for task_status/response_status prohibition#3045
Merged
Conversation
…ard for #3041 Formalises the normative MUST NOT on task_status / response_status envelope fields (established in PRs #2987 / #3021) as machine-checkable constraints. Changes: - static/schemas/source/core/protocol-envelope.json: adds "task_status": { "not": {} } and "response_status": { "not": {} } to the properties block. Any schema-aware validator operating on the full v3 protocol envelope will now detect these legacy field names without consulting the prose migration guide. - static/compliance/source/universal/v3-envelope-integrity.yaml: new universal storyboard (interaction_model: "*") asserting the canonical v3 status field is present. field_absent checks for the two prohibited fields are included as commented-out TODO steps pending @adcp/client runner support for that check type. Non-breaking justification: adds new forbidden-property constraints to two field names that were already normatively prohibited (MUST NOT). No conformant v3 implementation uses these fields; existing v3 consumers are unaffected. https://claude.ai/code/session_0144VBMThUyhomU346keD32C
4 tasks
bokelley
added a commit
that referenced
this pull request
Apr 26, 2026
…ce tables The v3-envelope-integrity universal storyboard merged in #3045 without the matching rows in the two doc index tables that the build-time parity lint enforces. Any PR merging with main has been failing the TypeScript Build job at build:compliance with: Universal-storyboard doc parity drift: - docs/building/conformance.mdx: missing rows for `v3_envelope_integrity` - docs/building/compliance-catalog.mdx: missing rows for `v3-envelope-integrity` Adds one row to each table next to schema-validation (the related category) — snake_case YAML id form in conformance.mdx, kebab-case filename slug in compliance-catalog.mdx, matching the conventions the parity lint expects per scripts/lint-universal-storyboard-doc-parity.cjs. Verified locally with `npm run build:compliance` — clean build, 20 universal storyboards detected. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3 tasks
bokelley
added a commit
that referenced
this pull request
Apr 26, 2026
* fix(addie): teach Addie that AAO runs an OAuth 2.1 + OIDC authorization server Escalation #288 (Emma Mulitz / Scope3) — Addie was telling users that AAO doesn't support OAuth and that bearer tokens are the only mechanism. AAO's authorization server has been live at https://agenticadvertising.org/.well-known/oauth-authorization-server with RFC 8414 metadata, RFC 9728 protected-resource metadata for /api and /mcp, RFC 7591 dynamic client registration, and PKCE-protected authorization code flow. Addie's rules had no OAuth section, so she fabricated. Adds a Knowledge section that: - explicitly states AAO supports OAuth 2.1 + OIDC and the well-known URLs, - separates AAO platform auth (OAuth/JWT for /mcp and /api) from AdCP protocol-level bearer + optional HTTP Message Signatures between agents, - points Addie at docs/registry/index.mdx and search_docs for specifics. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(addie): tighten AAO OAuth rule + close doc gap (expert review pass) Applies feedback from prompt-engineer, security, ad-tech-protocol-expert, and docs-expert reviews on the original Escalation #288 fix. Knowledge rule (server/src/addie/rules/knowledge.md): - Replace "do NOT say X" negation primer with positive "common conflation" framing; lift the conflation block to the top of the section so retrieval hits it first. - Update AdCP-protocol-auth characterization to match docs/building/ integration/authentication.mdx — Bearer (3.0 baseline; read-only in 3.1+), RFC 9421 (recommended in 3.0, required for mutating ops in 3.1+), or mTLS. Previous "bearer + optional signing" was stale. - Note that OAuth ALSO appears between agents (sales agents publishing their own AS for operator-account flows) — AAO is one OAuth deployment among many, not "the" OAuth surface for AdCP. - Add bridging line: a buyer that signed into AAO via OAuth still uses a separate seller-issued bearer when calling that seller's AdCP endpoints. - Spell out facts that were missing and would misroute integrators: no client_credentials grant (use a WorkOS org API key for S2S, not /token); no RFC 8707 audience binding enforced (so one JWT covers /mcp and /api); no advertised revocation_endpoint; PKCE mandatory regardless of token_endpoint_auth_method. - Soften "no manual onboarding required" — /register is rate-limited. - Cite both repo-relative path and public URL anchor for the registry reference. - Reciprocal cross-link: append a sentence to "Audit Surfaces in AdCP" pointing back to the new section. Docs (docs/building/integration/authentication.mdx): - Close the gap docs-expert flagged: this page is the canonical "AdCP authentication" landing point but was silent on AAO platform auth. Add a short "Authenticating to AAO Platform Services" section after "Obtaining Credentials" with the well-known URLs, the no-client_credentials caveat, and a link to /docs/registry#authentication. Docs (docs/registry/index.mdx): - Add "or logging in to AAO" so search_docs queries like "AAO login" / "sign in" route to the Authentication section. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(addie): tighten AAO OAuth rule + harden seller-AS trust (review pass 2) Applies second-pass feedback from prompt-engineer, security, ad-tech-protocol- expert, and docs-expert reviews on commit b621c14. Knowledge rule (server/src/addie/rules/knowledge.md): - Split the conflation block into three bullets: (1) AAO platform auth, (2) AdCP protocol auth between agents with the bridging "AAO JWT is not an AdCP credential" line elevated, (3) "Other auth surfaces" covering sales-agent operator-account OAuth and the TMP/webhook signing profiles. Item 2 was overloaded; the bridging fact was buried mid-paragraph. - Add the operator-OAuth wire signal so Addie knows when to expect it: `get_adcp_capabilities.require_operator_auth: true` or a 401 carrying `WWW-Authenticate: Bearer resource_metadata=…` (RFC 9728). - Add seller-AS issuer-pinning guidance — discovered `authorization_servers` must be pinned via adagents.json / out-of-band onboarding, not blindly trusted from the resource itself. Closes the credential-routing risk the security pass flagged. - Use specific signing terms for TMP and webhooks (Ed25519 envelope, HMAC-SHA256 per push_notification_config) so search_docs queries route. - Drop the unverifiable "~20/hr" rate-limit number on /register; the observed limit is at the edge, not application-level. - Drop the revocation_endpoint absence bullet (Addie won't recall it and stating absences invites fabrication). - Trim the audience-binding bullet to one positive sentence ("the same user JWT is accepted on /mcp and /api"); merge with the reach bullet. Docs (docs/building/integration/authentication.mdx): - Add "All AAO endpoints are HTTPS-only" sentence. - Add a Warning callout: when following a sales agent's RFC 9728 PRM for operator-account OAuth, pin the discovered AS issuer against adagents.json. Same threat the rule above guards against. Docs (docs/registry/index.mdx): - Drop "or logging in to AAO" duplication; "signing in" already carries the search query and the doubled phrase read as keyword stuffing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(docs): backfill v3-envelope-integrity rows in universal conformance tables The v3-envelope-integrity universal storyboard merged in #3045 without the matching rows in the two doc index tables that the build-time parity lint enforces. Any PR merging with main has been failing the TypeScript Build job at build:compliance with: Universal-storyboard doc parity drift: - docs/building/conformance.mdx: missing rows for `v3_envelope_integrity` - docs/building/compliance-catalog.mdx: missing rows for `v3-envelope-integrity` Adds one row to each table next to schema-validation (the related category) — snake_case YAML id form in conformance.mdx, kebab-case filename slug in compliance-catalog.mdx, matching the conventions the parity lint expects per scripts/lint-universal-storyboard-doc-parity.cjs. Verified locally with `npm run build:compliance` — clean build, 20 universal storyboards detected. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Closes #3041
Summary
Formalises the normative MUST NOT on
task_statusandresponse_statusenvelope fields (established in #2987 / #3021) as machine-checkable constraints. Two changes:static/schemas/source/core/protocol-envelope.json— adds"task_status": { "not": {} }and"response_status": { "not": {} }to thepropertiesblock. Any schema-aware validator that validates the full v3 protocol envelope will now detect these legacy field names as schema violations without reading the migration guide prose.static/compliance/source/universal/v3-envelope-integrity.yaml— new universal storyboard (interaction_model: "*") that asserts the canonical v3statusfield is present on aget_adcp_capabilitiesresponse. Field-absence assertions for the two prohibited fields are included as commented-out TODO steps, pendingfield_absentrunner support in@adcp/client(see cross-repo dependency below).Non-breaking justification
Adds
not: {}constraints to two property names (task_status,response_status) that were already normatively MUST NOT per the migration guide and task-lifecycle.mdx. No conformant v3 implementation uses these fields; no v3 downstream is broken. Theprotocol-envelope.jsonsource schema is what changes — releaseddist/schemas/versions are unaffected until the next release cycle.Cross-repo dependency
The storyboard's explicit field-absence checks (
field_absent) require a new check type in@adcp/client. Those validations are commented out with TODO markers. Until the runner shipsfield_absent, the machine-checkable enforcement path is thenot: {}schema constraint for external schema validators. The storyboard itself (assertingstatusis present and context is echoed) runs cleanly today.Immediate enforcement (today): schema-aware validators using
protocol-envelope.jsondirectly.Deferred enforcement:
@adcp/clientrunnerfield_absentcheck type — needs a separate PR toadcontextprotocol/adcp-client.Open questions answered in triage
payloaddata may carrytask_statuslegitimately)task_statusandresponse_status(MUST NOT per spec);state/phaseout of scopeuniversal/(notsecurity.yaml; notschema-validation.yamlwhich is implicitly scoped to sellers)Pre-PR review
field_absentactive checks; corrected narrative claim aboutresponse_schemapath; upgraded changeset tominor). Nits noted: correlation_id separator style,$commentpath staleness risk (low).not: {}),universal/placement, no v2 gating, andminorchangeset type all confirmed sound.Session: https://claude.ai/code/session_0144VBMThUyhomU346keD32C
Generated by Claude Code