feat(media-buy): refine[] prefixed ids + optional action (adcp#2775) - #2799
Merged
Conversation
Rename generic `id` → `product_id` / `proposal_id` inside each refine[] scope branch to match AdCP's entity-id convention, and make `action` optional with default "include" so only the non-default verbs (omit, more_like_this, finalize) need to be spelled. Response refinement_applied[] is now a discriminated oneOf echoing the same prefixed ids, with scope + matching id required per branch. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Rename stale `id:` → `proposal_id:` in 8 existing proposal-finalize unit tests that my earlier sweep missed (code-reviewer finding — without this, proposal finalize tests pass for the wrong reason: `op.proposal_id` was undefined, so `previousProposals.find` missed). - Add default-action regression test on proposal scope + assert `refinement_applied.proposal_id` echo. - `get_products.mdx`: collapse the 85-line duplicated refinement walkthrough (which still held the old `id` shape) down to a pointer + minimal example (docs-expert finding — the duplicated block was the most-linked-to section from the rest of the docs). - Trim redundant seller-side MUST from `specification.mdx` in favor of the orchestrator-side "MAY omit" note. - Restore "v3 rc.1" header consistency in `whats-new-in-v3.mdx`. - Changeset: add a note that `additionalProperties: false` now rejects leftover `id` — dx-expert observation to guide migration. - `refinement.mdx`: add SHOULD guidance on cross-checking `refinement_applied` by echoed id rather than positional order alone. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
# Conflicts: # tests/storyboard-sample-request-schema-allowlist.json
Follow-up polish on PR #2799 (adcp#2775): - Add schema-level regression tests for the pre-rename shape (send `{scope: "product", id: "x"}` against the new schema; assert it's rejected AND the error text flags the missing `product_id` / additional `id` so migrators can self-diagnose). Adds a third happy-path test proving the minimal `{scope, product_id}` shape (action-omitted) validates. - `refinement.mdx`: add a dedicated "Troubleshooting: must NOT have additional properties" callout + a "Seller migration" section — the shape change is breaking for sellers too (must echo scope + product_id/proposal_id; must treat missing action as include). - `whats-new-in-v3.mdx`: equal seller-side migration billing in the Typed refinement section — previously framed mostly from the buyer angle. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
# Conflicts: # tests/storyboard-sample-request-schema-allowlist.json
Merged
3 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #2775. Rearchitects the
refine[]array onget_productsto align with AdCP's existing naming conventions and match the shape that storyboard authors were already writing.id→product_idinsidescope: "product",id→proposal_idinsidescope: "proposal". Every other entity id in AdCP is prefixed (media_buy_id,plan_id,creative_id,account_id…) — this was the only island.actionwithdefault: "include"on product and proposal scopes. Authors writing{ scope: "product", product_id: "x", ask: "…" }no longer need the"action": "include"ceremony; the verb appears only when the behavior is non-default (omit/more_like_this/finalize).refinement_applied[]is now a discriminatedoneOfechoing the same prefixed ids, withscope+ the matching id field required per branch so cross-validation is a contract, not a convention.discriminator: { propertyName: "scope" }annotation on both requestrefine[]and responserefinement_applied[]for clean TypeScript / Python / Pydantic narrowed unions.Pre-GA (current version
3.0.0-rc.3), so breaking shape changes are cheap. Documented in the 3.0 release notes with a before/after migration table.Before / after
Touched
get-products-request.json,get-products-response.jsonrefinement.mdx,get_products.mdx,specification.mdx,intro.mdx,media-products.mdx,whats-new-in-v3.mdxtraining-agent/task-handlers.ts+ unit test for theaction-default behaviorrefine-prefixed-ids-optional-action.md(major bump, with migration table)Test plan
npm run build:schemascleannpm run test:schemas✓npm run test:examples✓npm run test:composed✓npm run test:json-schema✓npm run typecheck✓build:compliance✓ (all 7 storyboard lints pass)Related but out of scope
contextfield collision — SI schemas redefine core context as string with semantic meaning #2774 (SIcontextfield collision) — separate PRaccount— author intuition collides withplan_idscoping #2776 (governanceaccountfield) — separate PRcreative-manifest.assetsuses 14-branch anyOf without discriminator — ecosystem-wide validator noise #2777 (creative-manifestanyOf→oneOfdiscriminator) — separate PR🤖 Generated with Claude Code