fix(compliance): assert governance_context echo + gate governance_approved/conditions (#5716)#5719
fix(compliance): assert governance_context echo + gate governance_approved/conditions (#5716)#5719bokelley wants to merge 1 commit into
Conversation
…roved/conditions (#5716) governance_approved and governance_conditions previously asserted only response_schema on their terminal create_media_buy step, so a seller that never consulted its registered governance agent still passed — the governance handshake those scenarios are named for went untested. Add `envelope_field_present: governance_context` (a token only a seller that called check_governance can echo) to each, and gate both on media_buy.governance_aware (mirroring governance_denied/_recovery from #5676) so sellers without outbound governance consultation grade not_applicable instead of newly false-failing. Note: governance conditions have no dedicated wire field on the buy; the governance_context token is the correlation/propagation mechanism (per protocol-envelope.json), so the token echo is the assertable handshake signal. Closes #5716 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
There was a problem hiding this comment.
The gate is right. The assertion it's bolted to is unsound — it grades a seller→buyer echo the spec never requires, so it false-fails conformant sellers. ad-tech-protocol-expert: unsound, with cited spec divergence.
The block
The terminal create_media_buy step now asserts envelope_field_present: governance_context on the response envelope. No normative text requires a seller to echo governance_context back to the buyer on that response.
The token-flow contract (docs/governance/campaign/specification.mdx:696-699) is explicit about the seller obligation:
Seller: receives
governance_contextin the envelope, stores it alongside the media buy, and includes it on all subsequentcheck_governancecalls for that media buy's lifecycle.
Buyer→seller→governance-agent forwarding. Not seller→buyer echo on the buy response. The schema agrees: governance_context is not in the envelope required array — only status is (static/schemas/source/core/protocol-envelope.json:61-62) — and create-media-buy-response.json defines no governance field on any of its response shapes.
The clincher is internal. The existing governance/index.yaml storyboard lists governance_context: echoed back as un-graded expected: prose (line 544), then deliberately omits it from its graded validations[] (lines 576-586 — response_schema, field_present: context, field_value: context.correlation_id). Whoever wrote that storyboard already knew the echo is not a gradeable invariant. This PR promotes that prose into a hard assertion without the normative basis the prose lacked.
What breaks for adopters: a governance-aware seller that calls check_governance, gets approved, persists the token, and forwards it on subsequent lifecycle calls — but does not echo it on the create_media_buy response — is fully conformant and newly false-fails both scenarios. That's spec drift on the compliance grading surface, gated capability or not.
The PR's own framing concedes the gap: it notes there is no wire field for governance conditions on the buy, then reaches for the envelope token as a proxy. The token is a real correlation key — at the governance agent, on check_governance calls. It is not a buy-response echo signal.
Things I checked
requires_capability: { path: media_buy.governance_aware, equals: true }is byte-identical to the #5676 precedent (governance_denied.yaml:17-19);media_buy.governance_awareis real (get-adcp-capabilities-response.json:214,default: false), soequals: trueskips only non-declaring sellers — no gate-equals-default trap. This half is sound.code-reviewer: clean.envelope_field_presentis a valid check kind (runner-output-contract.yaml:47); the appendedvalidationsentry's indentation matches the existingresponse_schemaentry; storyboard lints resolve the path. The YAML is correct — the defect is semantic, not structural.- Changeset exists (
.changeset/5716-governance-handshake-assertions.md,patch) — appropriate for a compliance-config change. Not the issue.
How to unblock
Keep the requires_capability gate — that half mirrors #5676 correctly and ships as-is. Replace the governance_context echo with a handshake signal that is normatively grounded under this gate. Two options the expert surfaced:
- Assert
planned_deliverypresence — its schema description (create-media-buy-response.json:90-92) says it is "Present when the account has governance_agents," which is an actual conformant-seller invariant. - Assert the governance call out-of-band via the governance agent's
get_plan_audit_logs.
If the WG genuinely wants the seller to echo governance_context on the buy response, that's a normative MUST in the spec + a field on create-media-buy-response.json first — then the assertion. Assertion-first inverts the order.
One open question worth confirming regardless of path: does envelope_field_present at runtime inspect the response envelope or the request envelope? If the latter, the check is vacuously true (the buyer always attaches the token on the request) and tests nothing — a different defect, same line.
Requesting changes on the echo assertion. The gate is good; this is one targeted swap away from approvable.
|
Closing per Argus's review — the objection is correct, confirmed against the spec. The
So a conformant seller that consults governance but doesn't echo the token would have newly false-failed. The capability gate half ( The deeper issue: the happy-path scenarios can't deterministically prove consultation via the buy response, and they predate the spec's two-phase intent/purchase token flow ( |
Closes #5716.
Problem
governance_approvedandgovernance_conditionsasserted onlyresponse_schemaon their terminalcreate_media_buystep. Since storyboard grading is deterministicvalidations[]only (theexpected:prose is documentation, not graded), a seller that registers a governance agent but never callscheck_governancecreates a schema-valid buy and passes both — the governance handshake those scenarios are named for went untested.(
governance_denied/governance_denied_recoverywere already safe — they carry hardexpect_error+error_code: GOVERNANCE_DENIEDassertions a non-consulting seller can't fake, and #5676 gated them.)Fix
For both scenarios:
check: envelope_field_present, path: governance_contextto the terminal step.governance_contextis the token issued bycheck_governance(protocol-envelope.json), so only a seller that actually consulted the registered governance agent can echo it. (envelope_field_presentis implemented in@adcp/sdk@9.0.0-beta.31, added per Storyboard authoring: response_schema_ref vs envelope-level field assertions in v3-envelope-integrity #3429.)requires_capability: { path: media_buy.governance_aware, equals: true }, mirroring fix(compliance): add media_buy.governance_aware capability + gate governance_denied (#5665) [Option A] #5676, so sellers without outbound governance consultation gradenot_applicableinstead of newly false-failing.On the "conditions" half of the issue
The issue asked to also assert conditions propagation. There is no dedicated wire field for governance conditions on the buy (
create-media-buy-response.json,core/media-buy.json, andcore/package.jsonhave none). Thegovernance_contexttoken is the propagation/correlation mechanism (protocol-envelope.json: "primary correlation key for audit and reporting across the governance lifecycle"), with conditions retrievable at the governance agent. So the token echo is the correct assertable handshake signal. If the WG wants an explicit conditions field on the buy, that's a separate schema-modeling decision.Validation
Targeted storyboard lints pass:
lint-storyboard-check-enum(✓envelope_field_present),lint-storyboard-validations-paths(✓governance_contextpath),sdk-runner-capability-gates(✓ gate resolves). Full pre-commit suite green.Note: the gate keys
equals: truewhile the schema default isfalse, so the only sellers skipped are those that don't declare governance support — the intended skip, not the gated-value-equals-default trap.🤖 Generated with Claude Code