Skip to content

feat(training-agent): impairment tracking for media buys (closes #4719)#4733

Merged
bokelley merged 1 commit into
mainfrom
bokelley/ta-impairment-tracking
May 18, 2026
Merged

feat(training-agent): impairment tracking for media buys (closes #4719)#4733
bokelley merged 1 commit into
mainfrom
bokelley/ta-impairment-tracking

Conversation

@bokelley

Copy link
Copy Markdown
Contributor

Summary

When a creative referenced by a media buy's package transitions to rejected, the buy now surfaces health: "impaired" and an impairments[] entry per static/schemas/source/core/impairment.json. When the buyer recovers via assignment swap, the impairment clears and health returns to ok.

Closes the media_buy_seller/dependency_impairment and dependency_impairment_cardinality storyboards added in #4677/#4685 (both clean now, 12P + 19P = 31 steps passing on /sales).

Changes

  • types.tsImpairment interface + MediaBuyState.impairments?: Impairment[].
  • comply-test-controller.tspropagateCreativeImpairment(session, creativeId, prev, next) walks session.mediaBuys, finds buys with dependent packages, appends/removes impairment entries based on transition direction. Called from forceCreativeStatus after the status mutation. Idempotent on re-emission.
  • task-handlers.ts:
    • handleGetMediaBuys mapper emits health ('impaired' iff impairments.length > 0, else 'ok') and impairments[] mapped to the wire shape.
    • handleUpdateMediaBuy recomputes mb.impairments after creative_assignments replacement — drops any creative-impairment whose resource_id is no longer referenced. This is the canonical recovery vector (assignment swap).
  • tenants/comply.tscreative_status adapter wired into the v6 /sales comply config. Was missing; storyboards previously reported force_scenario_unsupported.

Storyboard adjustments

Both dependency_impairment* storyboards originally used inline sync_creatives.assignments[] to bind the creative. The v6 SalesPlatform.syncCreatives(creatives, ctx) signature drops the request-level assignments[] — the platform has no surface for it (filed upstream at adcp-client#1842).

Both storyboards restructured to:

  1. sync_creatives (library only, no assignment)
  2. update_media_buy with packages[].creative_assignments

Both surfaces are equally canonical per the spec — this is a v6-SDK compatibility choice, not a deprecation. The impairment.coherence contract is identical regardless of binding path. Narrative in both scenarios updated to reflect this.

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]. Filed test-design issue at #4732 for scenarios depending on pricing_options[0] discriminator.

Floors

  • /sales: 72:340 → 74:380 (observed 75 clean, 398 steps)
  • Other tenants unchanged — this PR only affects /sales

Reviewed by

  • code-reviewer (no blockers, "ready to push")
  • ad-tech-protocol-expert ("scenarios are spec-conformant"; narrative adjustments applied for canonical-surface framing)

Test plan

  • bash scripts/run-storyboards-matrix.sh — all 6 tenants pass new floors
  • npx tsc --noEmit -p server/tsconfig.json clean
  • dependency_impairment: 12P/0S/0N/A
  • dependency_impairment_cardinality: 19P/0S/0N/A
  • Pre-commit (unit tests + typecheck) green at push time
  • Pre-push storyboard matrix green at push time

🤖 Generated with Claude Code

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>
@bokelley bokelley merged commit 48e140f into main May 18, 2026
19 checks passed
@bokelley bokelley deleted the bokelley/ta-impairment-tracking branch May 18, 2026 10:38
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.

1 participant