compliance(storyboards): schema-driven mutations + contributes migration#2676
Merged
Conversation
Closes #2669 and #2662. Schema-driven MUTATING_TASKS (#2669): - Derive the set at lint-time from every static/schemas/source/*-request.json that lists idempotency_key in required. Mirrors build-compliance.cjs's loadMutatingSchemaRefs pattern. - MUTATING_EXCEPTIONS preserves one carve-out: comply_test_controller is naturally idempotent (its schema description justifies the absence of idempotency_key) but still mutates controller state the next step observes. - sync_audiences was absent from the hardcoded set and is now covered. - Three drift-guard tests: union invariant, no exception redundancy, anchor-task coverage. contributes: true migration (#2662): - Adopt the @adcp/client 5.8.1 boolean shorthand on four contributing steps inside branch_set phases: schema-validation.yaml past_start_reject_path / past_start_adjust_path security.yaml probe_invalid_api_key / probe_invalid_oauth_token - Storyboards pass 36/56 clean, 295 steps against 5.8.1 — both above CI regression floors (35/279). - Schema doc's guidance updated to name both forms as semantically equivalent, with the shorthand preferred inside branch_set phases. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Protocol expert caught: si_terminate_session is missing from MUTATING_EXCEPTIONS. Same shape as comply_test_controller — naturally idempotent (session_id is the dedup boundary) but does mutate session state a later si_send_message asserts against (SESSION_TERMINATED). Without it, contradiction lint can't discriminate pre- vs post- termination state paths. Code review should-fixes: - loadMutatingTasksFromSchemas collects into a Map<task, srcPath> and throws on hyphen-to-underscore collisions across subdirs (would previously dedupe silently via Set.add). - walk() skips symlinked directories to prevent unbounded recursion. - Added negative anchor test: get_products / get_signals / list_creative_formats / get_adcp_capabilities MUST NOT be in the schema-derived set. Guards against a read schema accidentally listing idempotency_key in required. - Softened storyboard-schema doc: no longer names which storyboards use the shorthand (goes stale), points at the lint as the authority. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
5 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
Bundles two follow-ups from #2661:
Schema-driven mutations
`loadMutatingTasksFromSchemas` walks `static/schemas/source/` for `*-request.json` files whose top-level `required` array lists `idempotency_key`. Mirrors the existing `loadMutatingSchemaRefs` pattern in `scripts/build-compliance.cjs`.
`MUTATING_EXCEPTIONS` retains two carve-outs, each documented in the target schema's description:
Before this PR, the hardcoded set was missing `sync_audiences` entirely. Schema-driven derivation catches it automatically.
Drift guards
Four new tests in `tests/lint-storyboard-contradictions.test.cjs`:
Also hardened `loadMutatingTasksFromSchemas`: throws on hyphen-to-underscore collisions across subdirs (previously silent via Set dedup), and skips symlinked directories to prevent unbounded recursion.
contributes migration
Four call sites migrated from `contributes_to: ` to `contributes: true`:
Storyboard doc (`universal/storyboard-schema.yaml`) updated: both forms are documented as semantically equivalent, with the shorthand preferred inside branch_set phases.
Test plan
Follow-ups
🤖 Generated with Claude Code