Skip to content

feat(compliance): v3 envelope integrity — schema constraint + storyboard for task_status/response_status prohibition#3045

Merged
bokelley merged 1 commit into
mainfrom
claude/issue-3041-v3-envelope-integrity
Apr 25, 2026
Merged

feat(compliance): v3 envelope integrity — schema constraint + storyboard for task_status/response_status prohibition#3045
bokelley merged 1 commit into
mainfrom
claude/issue-3041-v3-envelope-integrity

Conversation

@bokelley

Copy link
Copy Markdown
Contributor

Closes #3041

Summary

Formalises the normative MUST NOT on task_status and response_status envelope fields (established in #2987 / #3021) as machine-checkable constraints. Two changes:

  1. static/schemas/source/core/protocol-envelope.json — adds "task_status": { "not": {} } and "response_status": { "not": {} } to the properties block. 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.

  2. static/compliance/source/universal/v3-envelope-integrity.yaml — new universal storyboard (interaction_model: "*") that asserts the canonical v3 status field is present on a get_adcp_capabilities response. Field-absence assertions for the two prohibited fields are included as commented-out TODO steps, pending field_absent runner 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. The protocol-envelope.json source schema is what changes — released dist/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 ships field_absent, the machine-checkable enforcement path is the not: {} schema constraint for external schema validators. The storyboard itself (asserting status is present and context is echoed) runs cleanly today.

Immediate enforcement (today): schema-aware validators using protocol-envelope.json directly.
Deferred enforcement: @adcp/client runner field_absent check type — needs a separate PR to adcontextprotocol/adcp-client.

Open questions answered in triage

  • Scope: envelope top-level only (domain payload data may carry task_status legitimately)
  • Aliases: only task_status and response_status (MUST NOT per spec); state/phase out of scope
  • Placement: universal/ (not security.yaml; not schema-validation.yaml which is implicitly scoped to sellers)
  • v2 sunset gating: not needed — agents in dual-stack mode that fail this check have a v3 serialiser bug, which is exactly what this check is for

Pre-PR review

  • code-reviewer: approved — blockers resolved (removed field_absent active checks; corrected narrative claim about response_schema path; upgraded changeset to minor). Nits noted: correlation_id separator style, $comment path staleness risk (low).
  • ad-tech-protocol-expert: approved — schema pattern (not: {}), universal/ placement, no v2 gating, and minor changeset type all confirmed sound.

Session: https://claude.ai/code/session_0144VBMThUyhomU346keD32C


Generated by Claude Code

…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
@bokelley bokelley modified the milestones: 3.1.0, 3.0.1 Apr 24, 2026
@bokelley bokelley marked this pull request as ready for review April 24, 2026 20:02
@bokelley bokelley modified the milestones: 3.0.1, 3.1.0 Apr 24, 2026
@bokelley bokelley merged commit 9ff83de into main Apr 25, 2026
14 checks passed
@bokelley bokelley deleted the claude/issue-3041-v3-envelope-integrity branch April 25, 2026 23:51
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>
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>
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.

Conformance check: envelope properties matching /^(task|response)_status$/

2 participants