Skip to content

Commit e5e325e

Browse files
bokelleyclaude
andcommitted
fix(examples/multi_platform_seller): align mocks with wire contract; storyboard gate now blocking
The two mock platforms behind PlatformRouter (MockGuaranteedPlatform, MockNonGuaranteedPlatform) were silently failing the AdCP storyboard suite since PR #490 — masked by ``continue-on-error: true`` on the CI job. Pre-fix counts: tenant-a 7 passed / 8 failed / 44 skipped (cascade from create failures), tenant-b 12 passed / 6 failed / 41 skipped. Wire-contract alignments: * ``create_media_buy``: read ``packages[].product_id`` (singular, per ``schemas/3.0.6/media-buy/package-request.json``) instead of the non-existent ``packages[].products`` array. ``budget`` is a flat number, not a nested ``{total: ...}``. * ``sync_creatives``: response items use ``{creative_id, action: "created", status: "approved"}`` per ``schemas/3.0.6/creative/sync-creatives-response.json``. The old ``approval_status`` key wasn't a valid field. * ``get_media_buys``: implemented on both mocks (was missing, causing tenant-b's "'media_buys' is a required property"). Echoes ``targeting_overlay`` persisted at create / update time so the ``inventory_list_targeting`` storyboard can verify round-trip. * ``update_media_buy``: validates ``packages[].package_id`` against the buy's persisted packages and raises ``PACKAGE_NOT_FOUND`` (recovery=correctable) on unknown ids; persists ``targeting_overlay`` + ``measurement_terms`` patches for round-trip. * Both mocks now check buyer-proposed ``measurement_terms`` and raise ``TERMS_REJECTED`` when ``max_variance_percent < 5`` or ``measurement_window`` is outside ``c3``/``c7`` — mirrors the v3 reference seller's policy in ``examples/seller_agent.py``. * MockNonGuaranteedPlatform now starts buys in ``pending_creatives`` and advances to ``active`` via ``pending_start`` only after creatives sync, so the ``pending_creatives_to_start`` storyboard passes. The state machine doesn't permit a direct pending_creatives → active jump. * ``MEDIA_BUY_NOT_FOUND`` recovery changed from ``terminal`` to ``correctable`` to match spec semantics — the buyer can retry with a fresh id. Storyboards skipped by capability gate (correct behavior, no change): ``proposal_finalize`` is gated by ``media_buy.supports_proposals``. Neither mock declares it because neither implements the proposal lifecycle. The gate stays as-is until ProposalManager v1.5 ships. CI: drops ``continue-on-error: true`` from the ``storyboard-multi-platform-seller`` job. Future drift in the mocks or the spec now blocks merge. Artifact upload still runs on ``if: always()`` so failures remain debuggable. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent fe8e5b0 commit e5e325e

3 files changed

Lines changed: 517 additions & 87 deletions

File tree

.github/workflows/ci.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -652,10 +652,11 @@ jobs:
652652
runs-on: ubuntu-latest
653653
# Multi-tenant proof: one process, two tenants, one router. Each
654654
# tenant's storyboard runs against its own subdomain
655-
# (tenant-a.localhost / tenant-b.localhost). Non-blocking until
656-
# the storyboard reaches passing — same posture as the
657-
# examples/seller_agent.py job above.
658-
continue-on-error: true
655+
# (tenant-a.localhost / tenant-b.localhost). Blocking gate — both
656+
# tenants must pass the AdCP storyboard suite for the example to
657+
# remain a credible reference. continue-on-error was dropped after
658+
# the mocks were aligned with the wire contract; future drift now
659+
# blocks CI.
659660

660661
steps:
661662
- uses: actions/checkout@v4

0 commit comments

Comments
 (0)