Adversarial hunt for broken invariants in the changes since a fixed point. A subagent writes inputs that try to break each property the design promises, and a finding counts only with a test that fails on this head. Use when the user asks for an invariants hunt, to break or stress a change, or to prove that a design holds.
90%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
A review of the diff asks whether the code follows the rules. The hunt asks whether the rules hold: code can implement a rule faithfully and still break a property the design promises, and a reader of the diff will not see it. So the hunt reads the invariants, not the diff, and a finding counts only after it fails on this head.
Run it after code-review is quiet: fixes from that review change the code the hunt runs against.
Pin the target. The fixed point the user gave, or the merge-base with origin/next, confirmed with git rev-parse, and the commit list git log --oneline <fixed-point>..HEAD. The working tree is clean, and nothing else runs against it: no dev server, no E2E, no compile. The hunt edits files and runs tests, and anything else that shares the tree corrupts both.
Write the invariants. From the spec, the design notes and the PR body, write the properties the design promises as claims that a test can falsify. Each one names what stays true and the "regardless of" clause it must survive: input order, timing, failure, concurrency, partial state. Four to eight lines. Add each deferral from earlier reviews of this change as its own line: a deferral is a claim nobody has tested. When the tracker's discussion overrules the spec, save the spec to a file with a dated "Later decisions that supersede lines in this spec" section at the top, one decision per line. The subagent cannot read the tracker, and a stale spec makes it defend a rule that is already gone. Show the list to the user: a wrong invariant is cheaper to correct now than after the hunt.
Dispatch the hunt. One subagent, on the strongest model available, in the background, with the brief below filled in. Nothing else touches the tree until it reports.
Gate on evidence. A finding enters judgement only with all five parts: the invariant, the minimal input, the observed state on this head, the expected state, and a test that fails on this head. Send anything less back with "reproduce or drop". Judge each survivor:
Apply. Apply the accepted hunks from the saved patch by hand, without the held ones. Run the focused suites. Commit them as the pr skill "Commit history" section says.
Record. Add a dated note for each accepted rule change, and for each held design decision, marked open: as a comment on the tracker issue when the spec has one, else in the spec file. The next hunt on this change takes the deferrals as invariants in step 2.
Done when every finding has a verdict, the accepted fixes are committed, and the focused suites pass.
Replace the angle-bracket fields. Keep the rest.
You are reviewing <repo> at commit <sha> on branch <branch>, checked out at <path>. The change
under review is `git log --oneline <fixed-point>..HEAD`. The code lives in <directories>. Read
<design docs> and <spec file> first; the spec file's "Later decisions" section supersedes the body
where they disagree.
Do NOT review the diff for style, naming, comments, or spec conformance. Other reviewers do that.
Your job is to break the design's invariants and to prove each break by executing it.
The design rests on these invariants. Treat each as a claim to falsify:
<numbered invariants, each with its "regardless of" clause>
For each invariant, construct concrete adversarial inputs: <the domain's concrete knobs: specific
values, orderings, sizes, failure injections, concurrency>. Run them, against the unit under test
directly (<pattern file>) or through <harness / integration path>. Try EVERY ordering of small
input sets, not one ordering; write a permutation loop. Read the spec's own rules as suspects: a
rule the code implements faithfully can still break an invariant. Pay particular attention to rules
that landed in separate changes acting together.
Practical rules:
- Focused tests: <command>. Never run the full suite or a type check in parallel with another heavy
process. Run the full relevant directory at most once, at the end.
- You may add probe tests and edit source to apply your fixes, but at the end the working tree must
be exactly as you found it: `git status --short` shows <expected output>. Save your changes as
<patch path> (git diff plus new files via `git add -N`) before reverting. Do not commit, push, or
touch branches. Do not touch <off-limits paths>.
Explore what can reach the changed code before you decide what is impossible: user files and config,
CLI arguments, channel messages, a file system left behind by an interrupted run, events that arrive
out of order, concurrent runs, rejected promises. For each break, name its producer: the user action,
editor, build tool, framework or earlier Storybook run that creates the input. When you cannot name
a producer, keep the finding, say so, and rank it last.
Report only what you reproduced. For each finding: the invariant, the minimal input and its producer, the observed
state on this head, the expected state, and a test that fails on this head. Propose the source fix,
apply all fixes together, confirm the focused suites pass with them and that exactly your new tests
fail without them. List what you tried that held under "Held", one line each. Report nothing you
could not make fail; nothing about style, naming, or comments. Finish with a two-line verdict:
number of confirmed breaks, and whether the change is safe to merge as-is.storybookjs/storybook
44ea08a
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.