Skip to content

fix(training-agent): derive media-buy health/impairments from creative status#4737

Closed
bokelley wants to merge 2 commits into
mainfrom
bokelley/pasted-text-task-v2
Closed

fix(training-agent): derive media-buy health/impairments from creative status#4737
bokelley wants to merge 2 commits into
mainfrom
bokelley/pasted-text-task-v2

Conversation

@bokelley

Copy link
Copy Markdown
Contributor

Summary

  • Adds deriveImpairments() in task-handlers.ts that walks each buy's creativeAssignments and surfaces impairments[] entries from session creative status. Wired into handleGetMediaBuys + handleCreateMediaBuy responses. Creative-track only.
  • Adds force.creative_status adapter to buildSalesComplyConfig so storyboards can drive the creative through approved → rejected → processing via comply_test_controller on /sales.
  • Fixes handleSyncCreatives: assignments[] entries now fall back to walking session.mediaBuys when media_buy_id is omitted — per sync-creatives-request.json which marks only creative_id + package_id as required.
  • Bumps @adcp/sdk ^7.6.0 → ^7.7.0 for the creative_approvals[] extractor on the SDK runner's impairment.coherence buy-snapshot walk (ComplyControllerConfig: add force.audience_status + force.catalog_item_status slots adcp-client#1819).

Why

The official dependency-impairment storyboard (#4677 closing #2860) currently fails on /sales at the get_buy_impaired step because the training agent doesn't emit health + impairments[] on get_media_buys. This PR adds the derivation.

Effect

Moves the official scenario from 3P / 1F / 7S to 6P / 1F / 4S on /sales (three previously-skipped steps now pass; same one failure).

Remaining gap

The one remaining get_buy_impaired failure is blocked on adcontextprotocol/adcp-client#1846 — the v6 SalesPlatform.syncCreatives strips assignments[] from the wire request before reaching the platform handler, so the buy never gets the creative assigned and the derivation has nothing to surface. Once #1846 lands, the scenario fully clears without further training-agent changes.

The defensive media_buy_id fallback in handleSyncCreatives is staged for that fix — it's a no-op today (assignments never reach the handler) but kicks in immediately once the SDK pipes them through.

Scope boundary

Test plan

  • npx tsc --project server/tsconfig.json --noEmit — clean
  • TENANT_PATH=sales npx tsx server/tests/manual/run-storyboards.tsmedia_buy_seller/dependency_impairment ✓ 6P / 1F / 4S (was ✗ 3P / 1F / 7S)
  • /sales tenant totals: 355 passed (was 350), 19 failed, 167 skipped — net +3 unblocked, +1 unrelated failure shift, no regressions
  • Full matrix run in CI

Related

🤖 Generated with Claude Code

…e status (unblocks dependency_impairment storyboard)

The `dependency_impairment` storyboard (adcp#4677 closing #2860) exercises
`impairment.coherence` on /sales by forcing a referenced creative to
`rejected` and asserting the buy snapshot flips to `health: impaired`.
Three pieces were missing from the training agent:

- `task-handlers.ts:deriveImpairments()` walks each buy's
  `creativeAssignments` and surfaces `impairments[]` entries from session
  creative status — `resource_type: creative`, `transition: approved →
  rejected`, materially-scoped `package_ids[]` — wired into
  `handleGetMediaBuys` + `handleCreateMediaBuy` responses. Creative-track
  only; audience and catalog_item families remain forward-only on the
  spec today.
- `tenants/comply.ts`: `force.creative_status` adapter added to
  `buildSalesComplyConfig` so storyboards can drive the creative through
  approved → rejected → processing without depending on real seller-side
  review timing. `/sales` already advertises `syncCreatives` +
  `listCreatives` at the platform layer, so the SDK runner can observe
  the offline status transition through normal task responses.
- `task-handlers.ts:handleSyncCreatives`: `assignments[]` entries now
  fall back to walking `session.mediaBuys` when `media_buy_id` is
  omitted — per `sync-creatives-request.json` which marks only
  `creative_id` + `package_id` as required.

`@adcp/sdk` bumped `^7.6.0 → ^7.7.0` for the `creative_approvals[]`
extractor on the SDK runner's `impairment.coherence` buy-snapshot walk
(adcontextprotocol/adcp-client#1819).

Moves the official scenario from `3P / 1F / 7S` to `6P / 1F / 4S` on
`/sales` (three previously-skipped steps now pass; same one failure).
The remaining `get_buy_impaired` failure is blocked on
adcontextprotocol/adcp-client#1846 — the v6 SalesPlatform.syncCreatives
strips `assignments[]` before reaching the platform handler, so the buy
never gets the creative assigned and the derivation has nothing to
surface. Once #1846 lands, the scenario fully clears without further
training-agent changes.

Follow-up audience/catalog tracks tracked in adcp#4674.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…task-v2

# Conflicts:
#	server/src/training-agent/task-handlers.ts
@bokelley

Copy link
Copy Markdown
Contributor Author

Closing — superseded by #4733 which landed yesterday and implements the same fix (concurrent work).

Comparison:

#4733's approach is canonical (matches the spec's "seller MUST surface" framing where the seller actively pushes the impairment, rather than the buyer's reader inferring). The force.creative_status adapter on /sales and the sync_creatives.assignments[] workaround both landed in #4733 too.

After merging main into this branch, net source delta is zero (merge commit f66943c). The branch can stay open as a worktree-cleanup; closing the PR.

Cross-references preserved on follow-up:

@bokelley bokelley closed this May 18, 2026
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