Context
Now that #317 closed controller_detected: false, end-to-end against examples/seller_agent.py reports 36/47 passing, 5 failed, controller_detected: true. Verified by tracing the runner's calls: the runner only invokes comply_test_controller for simulate_delivery — it does not call seed_product/seed_media_buy/etc. for the media_buy_seller storyboard suite. The 5 failures are real implementation gaps, not seed-wiring issues.
overall_status: partial (36/47, controller_detected: true)
The 5 failures, grouped
Category A — runner expects two named test products in the catalog (2 failures)
The runner uses these product IDs across multiple storyboard scenarios and expects the seller to know them out of the box:
outdoor_display_q2 — used by media_buy_seller/delivery_reporting
sports_preroll_q2 — used by media_buy_seller top-level
DemoSeller's PRODUCTS only includes premium-homepage and run-of-site. Fix: add these two as additional entries to PRODUCTS. Both need full schema-required shape (format_ids, pricing_options, reporting_capabilities, delivery_measurement).
Category B — seller doesn't validate aggressive measurement_terms (1 failure)
media_buy_seller/measurement_terms_rejected proposes a measurement_terms block exceeding what the seller would accept (e.g. impossibly high viewability threshold or restrictive required attributes) and expects:
{ "errors": [{ "code": "TERMS_REJECTED", "recovery": "correctable", ... }] }
DemoSeller.create_media_buy doesn't inspect measurement_terms at all. Fix: add a small validator that rejects viewability_threshold > 80 (or similar threshold) with adcp_error("TERMS_REJECTED", ..., field="measurement_terms").
Category C — targeting_overlay not persisted on packages (2 failures)
media_buy_seller/inventory_list_targeting exercises:
create_media_buy with packages[*].targeting_overlay.property_list.list_id: "acme_outdoor_allowlist_v1"
get_media_buys — runner asserts /media_buys/0/packages/0/targeting_overlay/property_list/list_id matches what was sent.
update_media_buy swaps in acme_outdoor_no_match_v1
get_media_buys — runner asserts the new value persisted.
Today DemoSeller.create_media_buy strips packages down to package_id, product_id, pricing_option_id, budget — targeting_overlay is dropped. Same for the update path.
Fix: preserve targeting_overlay (and any other caller-supplied package fields) on the persisted package state, and surface them on get_media_buys. Symmetric pass-through on update_media_buy.
What was verified manually
seed_product works correctly when called directly (probed via comply_test_controller(scenario="seed_product", ...)); product appears in subsequent get_products. The 2 failures in Category A are NOT seed-wiring bugs — the runner just doesn't call seed_product for these storyboards.
controller_detected: true after 4.2.0 — confirmed by storyboard JSON output.
Verification target
After all three fixes:
overall_status: pass
controller_detected: true
summary.steps_passed: 47
…which lets the storyboard CI job (continue-on-error: true today) promote to required.
References
Context
Now that #317 closed
controller_detected: false, end-to-end againstexamples/seller_agent.pyreports 36/47 passing, 5 failed,controller_detected: true. Verified by tracing the runner's calls: the runner only invokescomply_test_controllerforsimulate_delivery— it does not callseed_product/seed_media_buy/etc. for themedia_buy_sellerstoryboard suite. The 5 failures are real implementation gaps, not seed-wiring issues.The 5 failures, grouped
Category A — runner expects two named test products in the catalog (2 failures)
The runner uses these product IDs across multiple storyboard scenarios and expects the seller to know them out of the box:
outdoor_display_q2— used bymedia_buy_seller/delivery_reportingsports_preroll_q2— used bymedia_buy_sellertop-levelDemoSeller'sPRODUCTSonly includespremium-homepageandrun-of-site. Fix: add these two as additional entries toPRODUCTS. Both need full schema-required shape (format_ids,pricing_options,reporting_capabilities,delivery_measurement).Category B — seller doesn't validate aggressive measurement_terms (1 failure)
media_buy_seller/measurement_terms_rejectedproposes ameasurement_termsblock exceeding what the seller would accept (e.g. impossibly high viewability threshold or restrictive required attributes) and expects:{ "errors": [{ "code": "TERMS_REJECTED", "recovery": "correctable", ... }] }DemoSeller.create_media_buydoesn't inspectmeasurement_termsat all. Fix: add a small validator that rejectsviewability_threshold > 80(or similar threshold) withadcp_error("TERMS_REJECTED", ..., field="measurement_terms").Category C —
targeting_overlaynot persisted on packages (2 failures)media_buy_seller/inventory_list_targetingexercises:create_media_buywithpackages[*].targeting_overlay.property_list.list_id: "acme_outdoor_allowlist_v1"get_media_buys— runner asserts/media_buys/0/packages/0/targeting_overlay/property_list/list_idmatches what was sent.update_media_buyswaps inacme_outdoor_no_match_v1get_media_buys— runner asserts the new value persisted.Today
DemoSeller.create_media_buystrips packages down topackage_id, product_id, pricing_option_id, budget—targeting_overlayis dropped. Same for the update path.Fix: preserve
targeting_overlay(and any other caller-supplied package fields) on the persisted package state, and surface them onget_media_buys. Symmetric pass-through onupdate_media_buy.What was verified manually
seed_productworks correctly when called directly (probed viacomply_test_controller(scenario="seed_product", ...)); product appears in subsequentget_products. The 2 failures in Category A are NOT seed-wiring bugs — the runner just doesn't call seed_product for these storyboards.controller_detected: trueafter 4.2.0 — confirmed by storyboard JSON output.Verification target
After all three fixes:
…which lets the storyboard CI job (
continue-on-error: truetoday) promote to required.References
unreachable→ 36/47 passing