docs+compliance: terminal-buy carve-out (#4635) + dependency-impairment storyboard (#2860)#4677
Merged
Merged
Conversation
….coherence health-iff rule Original lifecycle.mdx text only addressed the impairments[] reporting relaxation on terminal buys; the impairments[] ↔ health biconditional was not explicitly relaxed. The @adcp/sdk 7.6.0 runner (adcp-client#1801) already evaluates all three rules only against non-terminal buys; this makes the spec text match. Closes #4635. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New media_buy_seller/dependency_impairment scenario — the cross-resource exercise that drives non-NA grading of the impairment.coherence invariant landed in #2859. Five phases against the comply_test_controller sandbox: 1. setup — create active buy with creative assignment, force creative to approved baseline 2. baseline_healthy — get_media_buys reports health: ok, impairments[] empty 3. transition_offline — force_creative_status flips creative to rejected 4. verify_impaired — get_media_buys reports health: impaired with a matching impairments[] entry (resource_type, resource_id, package_ids, transition.to all asserted) 5. recover_and_verify — force creative back to approved, verify health returns to ok and impairments[] clears (exercises the biconditional both directions — stale impairments fail this phase and the invariant) Wired into protocols/media-buy/index.yaml#requires_scenarios so every media-buy seller storyboard run grades it. Sellers without comply_test_controller force_creative_status grade not_applicable. Creative-track only today. Audience-track and catalog-track follow once the controller adds force_audience_status / force_catalog_item_status. Closes #2860. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three rounds of expert review (protocol, docs, product). Must-fix items
addressed:
Docs (lifecycle.mdx, compliance-catalog.mdx):
- Pull health-iff out of the inverse paragraph into its own named rule.
'Out of scope' had referenced 'three rules' but only two were headlined.
- Tighten terminal-buy carve-out: spell out seller permission ('MAY leave
impairments[] and health in whatever state held at the terminal
transition') and buyer posture ('MUST NOT treat post-terminal drift as
a coherence violation'). Replaces the looser 'biconditional likewise
relaxes' framing.
- Align on 'iff' across both docs. Drop 'biconditional' and 'bidirectional
biconditional' (terms-of-art drift across adjacent docs).
Storyboard (dependency_impairment.yaml):
- Add field_present asserts for the required impairment fields
(impairment_id, reason_code, observed_at — all required per
impairment.json but the per-step checks weren't catching their absence).
- Add field_value assert that impairments[0].package_ids[0] matches the
buy's package_id — without this, a seller could list a different package
and still pass the impairment-present check.
- Add field_value_or_absent: [] for impairments on baseline and recovery
phases — health: ok with non-empty impairments[] should fail the
health-iff rule, and the per-step check catches it independently of the
cross-resource invariant.
- Align narrative on 'health-iff rule' (was 'bidirectional biconditional').
Deferred to follow-ups (filed separately):
- Cardinality assertion with a second creative (inverse-rule under
cardinality pressure).
- Swap-assignment recovery variant (more realistic than approved →
rejected → approved on the same creative_id).
- not_applicable escape valve for sellers that propagate via webhook with
no health field on the buy.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 17, 2026
This was referenced May 17, 2026
Closed
bokelley
added a commit
that referenced
this pull request
May 18, 2026
… (#4733) When a creative referenced by a media buy's package transitions to rejected, the buy now surfaces `health: impaired` and an `impairments[]` entry. When the buyer recovers via assignment swap (update_media_buy replacing the offline creative with an approved sibling), the impairment clears and health returns to ok. Closes the dependency_impairment + dependency_impairment_cardinality storyboards added in #4677/#4685. - types.ts: Impairment interface + MediaBuyState.impairments - comply-test-controller.ts: propagateCreativeImpairment walks session.mediaBuys on forceCreativeStatus, appending on approved→rejected and removing on the inverse; idempotent on re-emission - task-handlers.ts: - get_media_buys emits health + impairments mapped to wire shape - update_media_buy recomputes impairments after creative_assignments replacement; drops any whose resource_id is no longer referenced - tenants/comply.ts: wire force_creative_status adapter on /sales (was missing, storyboards reported force_scenario_unsupported) Scenario fixes: - Both dependency_impairment storyboards restructure sync_creatives + inline assignments into sync_creatives + update_media_buy. v6 SalesPlatform.syncCreatives doesn't expose request-level assignments to the platform (filed upstream at adcp-client#1842). Both surfaces are spec-canonical; this is a v6-SDK compatibility choice, not a deprecation. - dependency_impairment_cardinality also needs bid_price: 10.0 on its packages because its brief lands on an auction pricing_option as products[0].pricing_options[0] (test-design issue filed at #4732). Sales floor lifts from 72:340 to 74:380. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 18, 2026
bokelley
added a commit
to adcontextprotocol/adcp-client
that referenced
this pull request
May 18, 2026
…] in impairment.coherence Closes two gaps in the storyboard runner's `impairment.coherence` invariant exposed by the dependency-impairment storyboard (adcontextprotocol/adcp#2860 / adcontextprotocol/adcp#4677): 1. **Audience leg of the inverse rule is now graded.** The buy-side reference lives at `packages[*].targeting_overlay.audience_include[]` — a stable, spec-defined field that lets the runner traverse buy → audience the same way it traverses buy → creative. `audience_exclude` is intentionally excluded — suspending an exclude-audience does not prevent the buy from serving. The inverse check is now parameterised over both reference sets (creative + audience); a suspended audience referenced by a non-terminal buy that doesn't list it in `impairments[]` now produces a `violation: 'inverse'` failing result, mirroring creative coverage. `audience` is removed from `INVERSE_DEFERRED_FAMILIES`; the `not_applicable` hint that used to fire on every audience offline transition stops firing — audience observations flow into the graded path. 2. **`creative_approvals[]` is now walked on buy snapshots.** The `get-media-buys-response.json` package shape uses `creative_approvals[]` (per spec) — different from `core/package.json`'s `creative_assignments[]` (the request-side shape). `readBuySnapshot` previously only walked the latter, which made the inverse rule for creative grade silent on conformant `get_media_buys` snapshots. Now it walks both. This was the bug that masked the v6 SalesPlatform gap surfaced in #1846 — without this extractor, the inverse rule grades silent on a properly-shaped buy snapshot even when the creative is referenced. Test coverage: 6 new tests — 5 audience inverse coverage cases (graded propagation, exclude-doesn't-count, terminal carve-out, recovery clears, paired with health-iff) + 1 creative_approvals extraction case. Existing deferred-family test loop moves audience out and asserts the graded behaviour. The onEnd partial-coverage summary still flags catalog_item and event_source — their per-buy reference shapes remain unstable. No behaviour change for storyboards that already propagate impairments correctly — they previously graded `not_applicable` for audience offline observations and now grade `pass` instead. Storyboards that observed an audience transition without propagating it to a buy snapshot previously graded silent (with a `not_applicable` notice) and now FAIL with a structured `impairment_coherence_violation` hint pointing at the offline audience. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
bokelley
added a commit
to adcontextprotocol/adcp-client
that referenced
this pull request
May 18, 2026
…] in impairment.coherence (#1848) * feat(testing): grade audience inverse rule + walk creative_approvals[] in impairment.coherence Closes two gaps in the storyboard runner's `impairment.coherence` invariant exposed by the dependency-impairment storyboard (adcontextprotocol/adcp#2860 / adcontextprotocol/adcp#4677): 1. **Audience leg of the inverse rule is now graded.** The buy-side reference lives at `packages[*].targeting_overlay.audience_include[]` — a stable, spec-defined field that lets the runner traverse buy → audience the same way it traverses buy → creative. `audience_exclude` is intentionally excluded — suspending an exclude-audience does not prevent the buy from serving. The inverse check is now parameterised over both reference sets (creative + audience); a suspended audience referenced by a non-terminal buy that doesn't list it in `impairments[]` now produces a `violation: 'inverse'` failing result, mirroring creative coverage. `audience` is removed from `INVERSE_DEFERRED_FAMILIES`; the `not_applicable` hint that used to fire on every audience offline transition stops firing — audience observations flow into the graded path. 2. **`creative_approvals[]` is now walked on buy snapshots.** The `get-media-buys-response.json` package shape uses `creative_approvals[]` (per spec) — different from `core/package.json`'s `creative_assignments[]` (the request-side shape). `readBuySnapshot` previously only walked the latter, which made the inverse rule for creative grade silent on conformant `get_media_buys` snapshots. Now it walks both. This was the bug that masked the v6 SalesPlatform gap surfaced in #1846 — without this extractor, the inverse rule grades silent on a properly-shaped buy snapshot even when the creative is referenced. Test coverage: 6 new tests — 5 audience inverse coverage cases (graded propagation, exclude-doesn't-count, terminal carve-out, recovery clears, paired with health-iff) + 1 creative_approvals extraction case. Existing deferred-family test loop moves audience out and asserts the graded behaviour. The onEnd partial-coverage summary still flags catalog_item and event_source — their per-buy reference shapes remain unstable. No behaviour change for storyboards that already propagate impairments correctly — they previously graded `not_applicable` for audience offline observations and now grade `pass` instead. Storyboards that observed an audience transition without propagating it to a buy snapshot previously graded silent (with a `not_applicable` notice) and now FAIL with a structured `impairment_coherence_violation` hint pointing at the offline audience. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(impairment.coherence): reframe audience_exclude as serviceability not safety Spec review caught a framing issue: prior comments described the exclusion of audience_exclude as "doesn't prevent the buy from serving" which is true but conflates serviceability with safety. An offline exclude-audience can still silently break the suppression promise — that's a separate (forward-looking) signal class, not a reason to call excludes harmless. Also drops temporal "previously"/"prior to adcp#2860" framing from comments per CLAUDE.md and trims the #1846 internal-bug reference from the public changeset. No behaviour change. 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.
Two 3.1.0 follow-ups from the #4601 cluster — finishing the impairment.coherence rollout.
Issues closed
impairment.coherence)Commits
docs(compliance): make terminal-buy carve-out explicit for impairment.coherence health-iff rule— original lifecycle.mdx only relaxed the impairments[] reporting requirement on terminal buys; theimpairments[]↔healthbiconditional was not explicitly relaxed. The runner in@adcp/sdk7.6.0 (adcp-client#1801) already evaluates all three rules only against non-terminal buys; the spec text now matches. Mirrored on compliance-catalog.mdx.feat(compliance): dependency-impact end-to-end storyboard (#2860)— newmedia_buy_seller/dependency_impairmentscenario with five phases against the comply test controller's sandbox:approvedbaselineget_media_buysreportshealth: ok,impairments[]emptyforce_creative_statusflips creative →rejectedget_media_buysreportshealth: impairedwith a matchingimpairments[]entry (resource_type, resource_id, package_ids, transition.to all asserted)approved, verifyhealth: okandimpairments[]clears (exercises the biconditional both directions)Wired into
protocols/media-buy/index.yaml#requires_scenariosso every media-buy seller storyboard run grades it. Sellers withoutcomply_test_controller force_creative_statusgradenot_applicable.Test plan
build:compliance✓test:schemas✓ /test:storyboard-{doc-parity,scoping,validations-paths,sample-request-schema,response-schema,check-enum,branch-sets,test-kits,context-entity,contradictions,provides-state-for,auth-shape,advisory-expiry,raw-mode-required}✓test:storyboard-context-output-pathshas a pre-existing failure onsales-guaranteed/index.yamlunrelated to this PR (confirmed by stashing changes; same# fail 1). Should be filed/fixed separately.Rollout notes
force_audience_status/force_catalog_item_statussupport in the compliance test controller.🤖 Generated with Claude Code