feat(storyboard-lint): negative_path attribute for expect_error steps (#2824)#3226
Conversation
|
Ad-tech-protocol-expert review summary: Verdict: sound-with-caveats ✅ All 32
Recommend renaming
Open verification questions:
Ready for review. |
…3316) The previous workflow filtered PR comments out via `github.event.issue.pull_request == null` with a comment claiming "auto-fix handles those" — but no auto-fix workflow exists, and the slack-routing only routes `/triage` slash commands. PR review feedback (like the reviewer summaries on #3170/#3174/#3225/#3226 earlier today) sat unactioned because nothing else was wired to pick them up. Drop the filter. Route PR comments to the same triage routine, with two adaptations on the payload so the routine can branch: - `is_pr: true|false` flag at the top of the prompt - `pr` block with head_ref, base_ref, draft, state when is_pr=true - MODE directive when is_pr=true: "apply requested fix as a follow-up commit on the PR's head branch, or post a reply if it's a question" Self-loop guard widened to skip comments containing "Fixed by Claude Code" in addition to the existing "Triaged by Claude Code" — so the routine's own follow-up replies on PRs don't re-fire it. Concurrency group already keys on `issue.number`, which GitHub assigns sequentially across both issues and PRs, so PR runs won't collide with issue runs even when numbers happen to match. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Storyboard CI is failing on one step: This looks like a fixture/tag mismatch from the negative_path tagging pass. Please investigate whether While you're in there: the prior review also recommended renaming |
…overnance check for activate_signal Addresses two issues from @bokelley's review of #3226: 1. Renames negative_path value business_rule → payload_well_formed across the entire corpus (26 storyboard steps, lint predicate, storyboard-schema.yaml doc, and test assertions). The new name is broader — auth failures, state conflicts, and governance denials all share the same lint behavior (validate the payload; expect runtime rejection), so the name should describe the payload shape, not the rejection class. 2. Fixes the CI failure on activate_signal_denied: adds governance checking to handleActivateSignal in the training agent (mirrors create_media_buy — if governance plans exist in the session and no governance_context is provided, return GOVERNANCE_DENIED). The signal_marketplace/governance_denied storyboard sets up a $100 plan via sync_plans before calling activate_signal, so the new guard fires correctly. 3. Adds sample_response fixture to activate_signal_denied documenting the expected GOVERNANCE_DENIED error shape. https://claude.ai/code/session_012hzHajMZVRBvPxrs4ogn9U
|
Fixed in fb57329. Three changes: 1. CI fix — Root cause: Also added a 2. Rename Applied across all 26 storyboard steps, the 3. Build + lint
Generated by Claude Code |
|
Thanks for the update — fb57329 looks like a clean resolution. The Generated by Claude Code |
|
Acknowledged — will keep it moving. Generated by Claude Code |
|
Sounds good — ping me if anything needs a follow-up look. _Generated by Claude Code Generated by Claude Code |
|
Will do — thanks for the review, @bokelley! Generated by Claude Code |
…rror steps (#2824) Distinguishes schema_invalid (payload intentionally malformed — skip lint, the default) from business_rule (schema-valid payload rejected for semantic reasons — validate sample_request anyway) on storyboard negative-path steps. Changes: - Update isNegativeStep() in lint-storyboard-sample-request-schema.cjs to branch on negative_path: business_rule before short-circuiting - Document expect_error, negative_path, sample_request_skip_schema in static/compliance/source/universal/storyboard-schema.yaml - Tag all 32 expect_error: true steps in the corpus (26 business_rule, 6 schema_invalid) - Fix fixture drift exposed by business_rule validation: add missing idempotency_key to 6 steps, fix signal destinations type field, and convert content-standards policy→policies array (pre-existing drift from PR #3147) - Add isNegativeStep negative_path branch test to test file https://claude.ai/code/session_019dMkCmDw5ro7hzMQ6iTkKQ
…overnance check for activate_signal Addresses two issues from @bokelley's review of #3226: 1. Renames negative_path value business_rule → payload_well_formed across the entire corpus (26 storyboard steps, lint predicate, storyboard-schema.yaml doc, and test assertions). The new name is broader — auth failures, state conflicts, and governance denials all share the same lint behavior (validate the payload; expect runtime rejection), so the name should describe the payload shape, not the rejection class. 2. Fixes the CI failure on activate_signal_denied: adds governance checking to handleActivateSignal in the training agent (mirrors create_media_buy — if governance plans exist in the session and no governance_context is provided, return GOVERNANCE_DENIED). The signal_marketplace/governance_denied storyboard sets up a $100 plan via sync_plans before calling activate_signal, so the new guard fires correctly. 3. Adds sample_response fixture to activate_signal_denied documenting the expected GOVERNANCE_DENIED error shape. https://claude.ai/code/session_012hzHajMZVRBvPxrs4ogn9U
fb57329 to
f0d648f
Compare
Summary
Closes #2824
Introduces a
negative_pathattribute on storyboard steps to disambiguate two categories ofexpect_error: truetests:schema_invalid(default, preserves current behavior): payload is intentionally malformed — skip schema validation onsample_requestbusiness_rule: payload is schema-valid but violates a semantic invariant — validatesample_requesteven thoughexpect_erroris set, catching shape driftChanges
scripts/lint-storyboard-sample-request-schema.cjs:isNegativeStep()now returnsfalse(validate) whenexpect_error: trueandnegative_path: business_rule, and returnstrue(skip) for the existing default +schema_invalidcasestatic/compliance/source/universal/storyboard-schema.yaml: documentsexpect_error,negative_path, andsample_request_skip_schemastep-level fieldsexpect_error: truesteps tagged with their classification (26business_rule, 6schema_invalid)idempotency_keyto 6update_media_buy/create_media_buybusiness_rule fixturesdestinations[0]missingtype: "platform"fieldpolicy → policiesarray conversion (pre-existing drift from feat(training-agent): add cursor pagination to list_content_standards, list_collection_lists, list_property_lists #3147)tests/lint-storyboard-sample-request-schema.test.cjs: newisNegativeStep branches on negative_pathtest covering all three code pathsClassification summary (32 steps)
schema_invalid (6): idempotency/missing_key, deterministic-testing/unknown_scenario + missing_params, security/probe_unauth + probe_invalid_api_key + probe_invalid_oauth_token
business_rule (26): state-machine terminal enforcement, governance denial scenarios, invalid_transitions (unknown buy/package/recancel), measurement_terms_rejected, error-compliance date + version + structure tests, schema-validation temporal tests, deterministic-testing resource-lookup + state-transition tests, brand + brand-rights identity lookups, brand-rights expired rights + governance denial, signal-marketplace governance denial
Non-breaking justification
negative_path: schema_invalidpreserves existing behavior — no regressions on day 1Test plan
node --test tests/lint-storyboard-sample-request-schema.test.cjspasses (9/9)node scripts/lint-storyboard-sample-request-schema.cjsexits 0npm run build && npm run typecheckpasseshttps://claude.ai/code/session_019dMkCmDw5ro7hzMQ6iTkKQ
Generated by Claude Code