spec(storyboards): training-agent 5.7 audit fixes (#2627, #2628, #2629)#2631
Merged
Conversation
- brand-rights get_rights: drop mis-assigned brand_id (advertiser vs rights-holder conflation); use buyer_brand for compatibility filtering (#2627) - state-machine recancel_buy: align with NOT_CANCELLABLE vector from invalid_transitions.second_cancel; removes prior "either error or accept" contradiction (#2628, tracks #2619) - storyboard-schema + runner-output-contract: clarify per-step grading in any_of branch sets — non-chosen branches grade not_applicable, not failed (#2629) #2626 filed upstream at adcp-client#689 — storyboard sample_request is already spec-correct; the bogus feedback.satisfaction payload comes from a hardcoded override in @adcp/client request-builder.js. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Restore idempotency_key on state-machine.recancel_buy — per code review, without the key a conformant agent could reject for missing-key rather than NOT_CANCELLABLE, failing the step for the wrong reason (same pattern as schema-validation.create_buy_past_start_reject). - Promote peer_branch_taken to a distinct skip reason in runner-output-contract.yaml (separate from not_applicable). Per protocol + product review, conflating coverage gaps with runtime branch routing hurts dashboard filters and masks real regressions in the accept-branch. Detail shape now canonicalized for downstream parsing. - Remove dead brand_id context_outputs capture in brand-rights/index.yaml (no longer consumed after the buyer_brand fix). - Tighten state-machine.terminal_enforcement narrative so implementers don't over-generalize NOT_CANCELLABLE to non-cancellation transitions (pause/resume on canceled buys still return INVALID_STATE). - Define "aggregation flag" on first use; add authoring constraint that all branch-set peers MUST be optional:true; split runner detection from authoring guidance in storyboard-schema.yaml. - Cross-reference the grading rule from docs/contributing/storyboard- authoring.md so human authors understand why their reject-branch steps grade peer_branch_taken rather than failed. Follow-ups filed separately (not in this PR): - Explicit branch_set: field as first-class schema construct - Known-ambiguities entries for all four bugs - Pre-merge storyboard contradiction lint - Compatibility-filtering validation in brand_rights - second_cancel idempotency_key propagation Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Contributor
Schema Link Check ResultsCommit:
|
This was referenced Apr 21, 2026
…rd-issues # Conflicts: # static/compliance/source/protocols/media-buy/state-machine.yaml
This was referenced Apr 21, 2026
bokelley
added a commit
that referenced
this pull request
Apr 21, 2026
…el idempotency (#2635, #2637) (#2644) * spec(storyboards): Bucket A audit follow-ups — known-ambiguities + second_cancel idempotency - second_cancel (#2637): add idempotency_key to scenarios/invalid_transitions.yaml > double_cancel/second_cancel. Same pattern as the recancel_buy fix in #2631 — without the key, a conformant agent could reject for missing-key (per universal/idempotency.yaml) instead of NOT_CANCELLABLE, failing the step for the wrong reason. - known-ambiguities (#2635): four new entries in known-ambiguities.mdx covering the PR #2631 audit findings (brand_id conflation, re-cancel error code, branch-set grading, SDK request-builder override). Gives implementers hitting pre-fix symptoms on older SDK versions a search target pointing at the canonical resolution. #2636 (brand_rights compatibility-filtering assertion) dropped from Bucket A after discovering two missing primitives: no cross-step comparison validation exists in the storyboard schema, and no conflicting-brand test-kit fixture exists. Filed as follow-ups #2642 (primitive) and #2643 (fixture); #2636 stays open blocked on both. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(known-ambiguities): apply docs-expert review — removal trigger, label normalization, search targets - Preamble now explains entries persist until the fix ships in a tagged SDK / spec release (not when the issue closes), resolving the inconsistency between "#2603 still listed" and the prior "entries are removed when issues close" line. - Normalize the #2603 entry's "Gap closed by" label to "Resolution" so all 8 entries use one vocabulary. - Add the `past_start_handled` aggregation flag as a search target in the branch-set entry (implementers grep for the flag name, not just phase names). - Replace ambiguous "pre-fix runners" / "pre-fix the storyboard" with "before the #NNNN fix" so implementers know which SDK version carries the change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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
Four issues filed from the training-agent 5.7 adoption storyboard audit. Three fix spec/storyboard content; one is upstream-only.
Closes brand_rights storyboard conflates advertiser brand_id with talent brand_id #2627 —
brand-rights/index.yaml>get_rights.sample_requestwas passing the advertiserbrand_id(captured fromget_brand_identity, e.g.,acme_outdoor) intoget_rights.brand_id, which per the request schema filters by rights-holder brand (e.g., talent likedaan_janssen). Two fields, same name, different entities. Dropped the mis-assignment and addedbuyer_brandso compatibility filtering works as specified. Narrative now calls out the two brand_id semantics explicitly. Deadcontext_outputscapture removed after review.Closes Storyboard contradiction: double-cancel. state_machine permits idempotent-accept, invalid_transitions requires NOT_CANCELLABLE #2628 —
state-machine.yaml>recancel_buysaid "either return an error or accept idempotently" with no assertions, whileinvalid_transitions.yaml>second_cancelalready requiredNOT_CANCELLABLE. No single implementation could pass both. Alignedrecancel_buywith theNOT_CANCELLABLEvector — matches the §128/§129 resolution being finalized in spec: pre-GA tightening — re-cancel error code (#2617) + request body well-formedness (#2523) #2619 (cancellation-specific code takes precedence over generic terminal-stateINVALID_STATE). Narrative for the terminal_enforcement phase now clarifies that pause/resume on canceled buys still returnINVALID_STATEso implementers don't over-generalize.Closes schema_validation storyboard: past-start any_of branches reported as step failures #2629 —
schema-validation.yamlpast-start handling has twooptional: truebranches (past_start_reject_path,past_start_adjust_path) both contributing topast_start_handled. A conformant agent picks one path; the other'sexpect_error/field_presentassertion fails because the agent took the opposite behavior, and the runner surfaces the non-taken branch's failure in the summary. Added a new canonical skip reasonpeer_branch_takeninrunner-output-contract.yaml(distinct fromnot_applicable— keeps coverage gaps separable from runtime branch routing in dashboards). Added the per-step grading rule instoryboard-schema.yamlwith authoring constraint (branch-set peers MUST beoptional: true) and runner detection rule. Cross-referenced fromdocs/contributing/storyboard-authoring.md.#2626 — filed upstream, no spec change required
The
sales_catalog_drivenstoryboard'ssample_requestalready sends the spec-conformant fields (performance_index,metric_type,feedback_source). The bogusfeedback.satisfactionpayload comes from a hardcodedprovide_performance_feedbackoverride in@adcp/client'ssrc/lib/testing/storyboard/request-builder.jsthat bypasses the storyboard. Filed at adcontextprotocol/adcp-client#689; commented on #2626 to track.Expert review applied
Second commit (d98f21b) addresses feedback from protocol / product / docs / code reviews:
idempotency_keyonrecancel_buy— without it, a conformant agent could reject for missing-key rather than NOT_CANCELLABLE, failing the step for the wrong reason. Matches the pattern used byschema-validation.create_buy_past_start_reject.peer_branch_takenskip reason (not overloadingnot_applicable) — separates coverage gaps from runtime branch routing for downstream tooling.brand_idcontext_outputscapture in brand-rights (no consumer after the buyer_brand fix).peer_branch_takendetail shape for downstream parsing.optional: true.Follow-ups filed (out of scope for this PR)
branch_set:to first-class storyboard schema constructinvalid_transitions.second_cancelmissing idempotency_key (same pattern as the recancel_buy fix)Test plan
npm run build:compliancesucceeds — compiled storyboards emit todist/compliance/latest/npm run test:unit(precommit) — 631 tests pass (both commits)npm run typecheck— cleannpm run test:error-codes— no new warnings (existing duplicate-key warning onrunner-output-contract.yaml > summaryis pre-existing)npm run test:storyboard-scoping— passesNOT_CANCELLABLEalignment is consistent with spec: pre-GA tightening — re-cancel error code (#2617) + request body well-formedness (#2523) #2619's §128/§129 resolutionpeer_branch_takenas a distinct skip reason is the right direction vs. overloadingnot_applicable🤖 Generated with Claude Code