fix(examples): seed_product defaults, TERMS_REJECTED, targeting_overlay round-trip#320
fix(examples): seed_product defaults, TERMS_REJECTED, targeting_overlay round-trip#320
Conversation
…ay round-trip Fixes the 5 storyboard failures blocking storyboard CI promotion (issue #319): 1. DemoStore.seed_product — add setdefault calls for the six schema-required product fields (name, delivery_type, publisher_properties, format_ids, pricing_options, reporting_capabilities, delivery_measurement). A minimal fixture sent by the runner now produces a fully-valid product entry. 2. DemoSeller.create_media_buy — inspect measurement_terms.viewability_threshold and return TERMS_REJECTED when it exceeds 80, satisfying the create_media_buy_aggressive_terms storyboard step. 3. DemoSeller.create_media_buy — persist targeting_overlay, creative_assignments, and creatives on the stored package object so get_media_buys can round-trip property_list / list_id values (acme_outdoor_allowlist_v1 step). 4. DemoSeller.update_media_buy — apply targeting_overlay, creative_assignments, and creatives deltas to the persisted package state so the get_after_update step can read back the updated property_list (acme_outdoor_no_match_v1 step). Adds 7 unit tests in tests/test_seller_agent_storyboard.py covering all fixed scenarios. Full suite: 2351 passed, 22 skipped, 1 xfailed; the single failure (test_real_tls_handshake_still_validates_hostname) is a pre-existing network-dependent test unrelated to this change. Refs #319 https://claude.ai/code/session_01ENPdJ8Nk7YvUhfRpMXLa8w
|
Superseded by PR #321 — that branch includes this commit (cherry-picked) plus three additional fixes for the remaining storyboard CI failures (publisher_properties |
|
Acknowledged — deferring to #321. No objection to closing this one. Generated by Claude Code |
|
Understood — noted the defer to #321. No action needed here from me; this PR can be closed whenever ready. Generated by Claude Code |
|
Acknowledged — closing this PR since the work is deferred to #321. Generated by Claude Code Generated by Claude Code |
|
Acknowledged — no further action from triage on this PR. Work tracking lives in #321. _Generated by Claude Code Generated by Claude Code |
|
Acknowledged — this PR is superseded by #322 which closes #319 with a verified end-to-end storyboard pass. No further action needed here. Generated by Claude Code |
…normalization (#319) Closes #319. Storyboard CI on examples/seller_agent.py was failing with persistent schema-validation errors against products seeded by the storyboard runner. The seller's `seed_product` controller blindly appended fixture-shaped skeletons to the PRODUCTS list without filling schema-required defaults; subsequent `get_products` responses then failed AdCP 3.0.1 validation. Fixes: * `publisher_properties` defaulted to `[]` (violates schema's `minItems: 1`) — now defaults to `[{"publisher_domain": "example.com", "selection_type": "all"}]`. * `format_ids[].agent_url` was missing on caller-supplied fixtures shaped as `[{"id": "..."}]` — now normalized to fill in the local `AGENT_URL` when absent; existing values preserved. * `reporting_capabilities.available_reporting_frequencies` defaulted to `[]` (violates `minItems: 1`) — now defaults to `["hourly", "daily"]` matching the static PRODUCTS template. * TERMS_REJECTED gate narrowed: per-package measurement_terms inspection accepts seller-vendor terms (own domain, "internal" indicator) and tightens rejection criteria so only buyer-imposed unworkable terms trip the rejection path. * Persists round-trip fields (`targeting_overlay`, `creative_assignments`, `creatives`, `measurement_terms`, `budget`) through `create_media_buy` / `update_media_buy` so storyboard scenarios can verify state transitions. * Wires context echo on adcp_error responses. Tests: * `test_seed_product_minimal_fixture_satisfies_schema_requirements` — asserts the minimal-fixture path produces a product satisfying every `minItems: 1` constraint and `format_ids[].agent_url`. * `test_seed_product_normalizes_format_ids_missing_agent_url` — asserts the fill-when-missing AND preserve-when-present semantics for caller-supplied `format_ids`. * All 10 storyboard tests pass: tests/test_seller_agent_storyboard.py * Full suite: 2398 passed. Supersedes #320. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…normalization (#319) Closes #319. Storyboard CI on examples/seller_agent.py was failing with persistent schema-validation errors against products seeded by the storyboard runner. The seller's `seed_product` controller blindly appended fixture-shaped skeletons to the PRODUCTS list without filling schema-required defaults; subsequent `get_products` responses then failed AdCP 3.0.1 validation. Fixes: * `publisher_properties` defaulted to `[]` (violates schema's `minItems: 1`) — now defaults to `[{"publisher_domain": "example.com", "selection_type": "all"}]`. * `format_ids[].agent_url` was missing on caller-supplied fixtures shaped as `[{"id": "..."}]` — now normalized to fill in the local `AGENT_URL` when absent; existing values preserved. * `reporting_capabilities.available_reporting_frequencies` defaulted to `[]` (violates `minItems: 1`) — now defaults to `["hourly", "daily"]` matching the static PRODUCTS template. * TERMS_REJECTED gate narrowed: per-package measurement_terms inspection accepts seller-vendor terms (own domain, "internal" indicator) and tightens rejection criteria so only buyer-imposed unworkable terms trip the rejection path. * Persists round-trip fields (`targeting_overlay`, `creative_assignments`, `creatives`, `measurement_terms`, `budget`) through `create_media_buy` / `update_media_buy` so storyboard scenarios can verify state transitions. * Wires context echo on adcp_error responses. Tests: * `test_seed_product_minimal_fixture_satisfies_schema_requirements` — asserts the minimal-fixture path produces a product satisfying every `minItems: 1` constraint and `format_ids[].agent_url`. * `test_seed_product_normalizes_format_ids_missing_agent_url` — asserts the fill-when-missing AND preserve-when-present semantics for caller-supplied `format_ids`. * All 10 storyboard tests pass: tests/test_seller_agent_storyboard.py * Full suite: 2398 passed. Supersedes #320. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…normalization (#319) (#321) Closes #319. Storyboard CI on examples/seller_agent.py was failing with persistent schema-validation errors against products seeded by the storyboard runner. The seller's `seed_product` controller blindly appended fixture-shaped skeletons to the PRODUCTS list without filling schema-required defaults; subsequent `get_products` responses then failed AdCP 3.0.1 validation. Fixes: * `publisher_properties` defaulted to `[]` (violates schema's `minItems: 1`) — now defaults to `[{"publisher_domain": "example.com", "selection_type": "all"}]`. * `format_ids[].agent_url` was missing on caller-supplied fixtures shaped as `[{"id": "..."}]` — now normalized to fill in the local `AGENT_URL` when absent; existing values preserved. * `reporting_capabilities.available_reporting_frequencies` defaulted to `[]` (violates `minItems: 1`) — now defaults to `["hourly", "daily"]` matching the static PRODUCTS template. * TERMS_REJECTED gate narrowed: per-package measurement_terms inspection accepts seller-vendor terms (own domain, "internal" indicator) and tightens rejection criteria so only buyer-imposed unworkable terms trip the rejection path. * Persists round-trip fields (`targeting_overlay`, `creative_assignments`, `creatives`, `measurement_terms`, `budget`) through `create_media_buy` / `update_media_buy` so storyboard scenarios can verify state transitions. * Wires context echo on adcp_error responses. Tests: * `test_seed_product_minimal_fixture_satisfies_schema_requirements` — asserts the minimal-fixture path produces a product satisfying every `minItems: 1` constraint and `format_ids[].agent_url`. * `test_seed_product_normalizes_format_ids_missing_agent_url` — asserts the fill-when-missing AND preserve-when-present semantics for caller-supplied `format_ids`. * All 10 storyboard tests pass: tests/test_seller_agent_storyboard.py * Full suite: 2398 passed. Supersedes #320. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes #319
Fixes the 5 storyboard failures blocking promotion of the storyboard CI job from
continue-on-error: trueto required (36/47 → 47/47 expected).What changed
DemoStore.seed_product(examples/seller_agent.py) — Addsetdefaultfor all 8 schema-required product fields (name,description,delivery_type,publisher_properties,format_ids,pricing_options,reporting_capabilities,delivery_measurement). A minimal fixture sent by the runner with onlyproduct_idnow produces a fully-valid product entry.date_range_supportdefault corrected from"none"(invalid) to"date_range"(schema default). Fixes failures 1 & 2.DemoSeller.create_media_buy— Per-packagemeasurement_terms.viewability_threshold > 80now returnsTERMS_REJECTEDwithrecovery="correctable"(negotiation error, not terminal).viewability_thresholdis a storyboard demo convention viaadditionalProperties; real sellers should apply their own criteria. Fixes failure 3.DemoSeller.create_media_buy— Package construction now persiststargeting_overlay,creative_assignments, andcreativesinto the stored package dict soget_media_buyscan round-tripproperty_list.list_id. Fixes failure 4.DemoSeller.update_media_buy— Builds apackage_id → dictindex (references intomb["packages"]) sotargeting_overlay,creative_assignments, andcreativesdeltas are applied directly to the stored dict and visible on the nextget_media_buyscall. Fixes failure 5.What was tested
pytest tests/test_seller_agent_storyboard.py— 8 new tests, all pass. Covers:seed_productdefaults, fixture field preservation, TERMS_REJECTED (above threshold, at boundary, below threshold +recoveryassertion),targeting_overlaycreate round-trip,targeting_overlayupdate round-trip.pytest tests/— 2352 passed, 22 skipped, 1 xfailed. The single failure (test_real_tls_handshake_still_validates_hostname) is a pre-existing network-dependent test unrelated to this change.ruff check src/ tests/test_seller_agent_storyboard.py— clean.Pre-PR review
Two expert passes ran on the final diff before this PR was opened.
descriptiondefault (fixed) and boundary test (added); no blockers remain.measurement_termsis per-package not top-level (fixed),recovery="correctable"required (fixed),date_range_support: "none"invalid (fixed); no blockers remain.Nit surfaced (not fixed in this PR):
TERMS_REJECTEDis absent fromSTANDARD_ERROR_CODESinhelpers.py, so any other call site that uses it will default torecovery: "terminal". Tracking separately.Session: https://claude.ai/code/session_01ENPdJ8Nk7YvUhfRpMXLa8w
Generated by Claude Code