Skip to content

fix(storyboard): proposal-mode enricher respects fixture's explicit packages#1649

Merged
bokelley merged 1 commit into
mainfrom
bokelley/proposal-mode-respect-explicit-packages
May 10, 2026
Merged

fix(storyboard): proposal-mode enricher respects fixture's explicit packages#1649
bokelley merged 1 commit into
mainfrom
bokelley/proposal-mode-respect-explicit-packages

Conversation

@bokelley
Copy link
Copy Markdown
Contributor

Summary

Follow-up to PR #1603, which introduced proposal-mode in the create_media_buy request enricher by reading context.proposal_id. `context.ts::get_products()` auto-captures `proposals[0].proposal_id` from any `get_products` response that returned `proposals` — essentially every brief flow against a seller that supports proposal-mode discovery.

The enricher fell back to `context.proposal_id` whenever the fixture didn't explicitly set `proposal_id`. That meant a storyboard authoring `packages` directly in `sample_request` would have its packages dropped in favor of the auto-captured proposal — forcing every sales storyboard whose brief returned proposals through the seller's strict proposal-lifecycle validation.

Concrete impact

Surfaced when consuming sellers like `test-agent.adcontextprotocol.org` that enforce proposal-status / IO-acceptance / total_budget rules on `proposal_id`-shaped requests. With this branch's SDK packed locally and consumed by the test-agent's storyboard matrix:

Tenant Before fix (SDK 6.18.0) After fix
/signals ✓ 67 / 58 ✓ 67 / 58
/sales ✗ 50 / 198 (17 storyboards regressed) ✓ 65 / 254 (2 remain — pre-existing storyboard authoring issues, see below)
/governance ✓ 65 / 102 ✓ 65 / 102
/creative ✓ 66 / 118 ✓ 66 / 118
/creative-builder ✓ 60 / 100 ✓ 60 / 100
/brand ✓ 66 / 45 ✓ 66 / 45

Storyboards restored: `sales_guaranteed`, `sales_non_guaranteed`, `schema_validation` (×3), `media_buy_seller` (×11 sub-scenarios), `creative_generative/seller`, and others.

Fix

The enricher reads `context.proposal_id` only when the fixture authors NEITHER `proposal_id` NOR `packages`. Fixture is the storyboard author's intent; respect it.

Fixture Mode chosen
`proposal_id` set proposal-mode
`packages` set, no `proposal_id` package-mode (was: incorrectly proposal-mode via context fallback)
neither proposal-mode if `context.proposal_id` set; else package-mode

Test plan

  • `node --test test/lib/request-builder.test.js` (85/85, 4 new cases)
  • `node --test test/lib/request-builder-jsonschema-roundtrip.test.js test/lib/request-builder-schema-roundtrip.test.js test/lib/storyboard-completeness.test.js` (1731/1731 — no regression on roundtrip / completeness)
  • `node --test test/examples/hello-seller-adapter-proposal-mode.test.js` (3/3 — original PR fix(storyboard): proposal-mode create_media_buy request shape (closes #1600) #1603 integration coverage still passes)
  • `npm pack` + install into adcontextprotocol/adcp test-agent + run `scripts/run-storyboards-matrix.sh` — 5 of 6 tenants meet floors; /sales restored from 50 → 65 clean storyboards. Two remaining failures (`sales_proposal_mode`, `media_buy_seller/proposal_finalize`) are spec-side fixture issues PR fix(storyboard): proposal-mode create_media_buy request shape (closes #1600) #1603 was masking — separate PR will address.

Out-of-scope follow-ups

The two remaining /sales failures are pre-existing storyboard authoring issues that PR #1603's incorrect over-application masked. They live in `adcontextprotocol/adcp` and need fixes there:

  1. `sales_proposal_mode` authors `proposal_id: "balanced_reach_q2"` as a literal in two places. The training-agent's seed proposals don't include that id (it seeds `pinnacle_cross_channel`, `viewpoint_multi_screen`, `sparq_social_amplification`, `novamind_ai_audience`). Switch to `$context.proposal_id` to dynamically follow the brief response, matching the pattern `media_buy_seller/proposal_finalize` already uses.
  2. `media_buy_seller/proposal_finalize` doesn't include `io_acceptance` in the `create_media_buy` fixture, but the test-agent's seed proposals (post-3.0.7) carry `requires_signature: true` insertion orders. Either the fixture needs `io_acceptance`, or the seed needs to differentiate IO-required vs non-IO proposals.

🤖 Generated with Claude Code

…ackages

PR #1603 introduced proposal-mode in the create_media_buy request enricher
by reading context.proposal_id. context.ts::get_products() auto-captures
proposals[0].proposal_id from any get_products response that returned
proposals — essentially every brief flow against a seller that supports
proposal-mode discovery.

The enricher fell back to context.proposal_id whenever the fixture didn't
explicitly set proposal_id. That meant a storyboard authoring `packages`
directly in sample_request would have its packages dropped in favor of
the auto-captured proposal — forcing every sales storyboard whose brief
returned proposals through the seller's strict proposal-lifecycle
validation.

Concrete impact (surfaced when consuming sellers like
test-agent.adcontextprotocol.org that enforce proposal-status /
IO-acceptance / total_budget rules on proposal_id-shaped requests):
sales_guaranteed, sales_non_guaranteed, schema_validation,
media_buy_seller/*, creative_generative/seller, and similar
package-mode storyboards regressed below their step floors with
PROPOSAL_NOT_COMMITTED errors.

Fix: the enricher reads context.proposal_id only when the fixture
authors neither proposal_id nor packages. Fixture intent wins. Existing
hello_seller_adapter_proposal_mode integration coverage continues to
pass (proposal-mode storyboards explicitly author proposal_id).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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