Skip to content

Skill-description tuning: measured fire rates, collision score 23->13, routing table alignment - #6

Merged
itsvedantkumar merged 10 commits into
mainfrom
skill-autofire
Sep 2, 2026
Merged

Skill-description tuning: measured fire rates, collision score 23->13, routing table alignment#6
itsvedantkumar merged 10 commits into
mainfrom
skill-autofire

Conversation

@vedant-simulacrum

Copy link
Copy Markdown
Collaborator

Handoff report from the skill-autofire session (verbatim); the release owner picks up the inventory re-point and 1.63.0 bump as explicit merge tasks.

Per-skill fire rates, N=10 per arm, no early stop

skill max-turns before after Fisher p (2-sided) reading
executing-plans 12 1/10 6/10 0.0573 moved, not significant
test-driven-development 12 3/10 3/10 1.0 unchanged
writing-plans 3 9/10 10/10 1.0 no regression, no headroom
swarm 3 10/10 10/10 1.0 no regression, no headroom

100 published calls, $16.19, recorded by the harness. Model sonnet, no seed knob exists. Instrument frozen at 901bb3f and stamped into every row; installed-description digest d4251fb4eda7 (baseline) / 5cf618030b60 (after), one value per arm.

Three of the brief's premises are falsified. swarm fires 10/10 on a prompt containing none of the four trigger strings its own description quoted, so "fires only when the user says 'in parallel'" does not hold in this harness. writing-plans fires 9/10 unedited. executing-plans fired 1/10 on a prompt that is nearly its own description restated, with 2/10 misrouting to test-driven-development on a prompt containing no test, so wording was never the binding constraint. Sibling competition was.

The pre-registered threshold passed without earning it. "after >=6/10" was derived against an assumed 0/10 baseline (p=0.0108, clears Bonferroni alpha=0.0125). Measured baseline was 1/10, making 6/10 p=0.0573, which clears neither 0.0125 nor 0.05. Written up in RESULTS.md as an instance of docs/checks-that-inherit-their-answer.md in the session's own work. Separating those rates needs n~20-25 per arm, roughly $12 more.

Collision check

tests/description-collision.sh, zero model calls. Corpus score 23 -> 13, zero hard-fail pairs either side. The 10 points are exactly the two overlaps the ordinal framing created: test-driven-development/writing-plans on "once shape" (6) and brainstorming/test-driven-development on "shape known" (4). The 80-sample "collisions suppress BOTH" hazard the brief cited is retracted (CHANGELOG 1.47.0); its pre-registered replacement at n=25 found the hypothesis unsupported. The script header says so and the string "80 samples" appears nowhere.

Situation -> skill after the change

situation observable in the prompt routes to
shape undecided, nothing agreed brainstorming (unchanged)
requirements settled, nothing written down, >1 edit of work writing-plans
about to write implementation code or a bugfix, no test fails for it test-driven-development
a written plan or numbered task list exists, ask is to carry it out executing-plans
>=3 independent units, none needs another's result swarm (second axis, co-fires with any stage)

Gate status

tests/dispatch-static.sh green (30 cases declared and present). .claude/verify.sh 63 checks, 4 failures, all one cause: four payload files changed without a version bump or inventory re-point. origin/main is green, so these are the branch's.

MERGE TASKS (release owner):

  1. "declared version matches what installs" — needs the 1.63.0 bump plus CHANGELOG.
  2. payload_digest / derived_at.head / inventory contract — one two-field edit to claude/inventory.json ("Re-point inventory at the payload", same as 1925110/59c99f4/37a9042). Values measured on the branch: derived_at.payload_digest -> adffdbb46506fff39b37b42f442799f150ecbb3d868805ce178bb740c53a3600, derived_at.head -> 5c0d908 (last payload-touching commit on the branch).

Hook diff for its owner

claude/hooks/inject-session-context.sh was read, never edited. Two lines to match the shipped descriptions:

-220  - plan written, no test yet -> test-driven-development.
+220  - about to write implementation code or a bugfix, no failing test covers it -> test-driven-development.
-221  - failing test exists against plan -> executing-plans.
+221  - a written plan or task list already exists, the ask is to carry it out -> executing-plans.

Line 208 (swarm) and the writing-plans line already agree. Flag alongside it that line 221 and the shipped executing-plans-checkpoints fixture have disagreed since before this branch. claude/CLAUDE.md has no routing table (58 lines); the table lives in this barred hook, which is why the branch edits no hook.

🤖 Generated with Claude Code

itsvedantkumar and others added 10 commits September 1, 2026 20:59
ATTEMPTS cannot answer "what fraction of the time does this skill fire". It early-stops on the
first hit, so it measures "landed within 3 tries" and biases upward -- the file has said so
above case_max_turns since 2026-08-23, and that early-stopping bias is what read
encode-lessons-lint as a dead skill when it was turn-starved. Every before/after claim about a
description needs a real rate, so SAMPLES=N runs N independent, non-retrying invocations and
prints raw k/N. Default 0: with SAMPLES unset every path, output line and exit code is
unchanged, and run_case's body is untouched -- the branch is a guard prepended to it.

Two numbers ship alongside k/N because k/N alone is not interpretable here.

total_cost_usd, read from the terminal result event with no `origin` (the same discriminator
top_level_subtype already uses to avoid a subagent's result line). Nothing in this file counted
a billed call before spending it; a full default run is up to 80 invocations and no line of
output said so.

named-not-called, from the assistant's prose. Measured 2026-08-27 in
tests/evals/collision/RESULTS.md: when the tool a skill needs is denied, the model names the
skill in prose and never calls Skill, which scores identically to a routing miss under
fired=[]. DISALLOWED_TOOLS denies Write and Agent, which are exactly what the planning-chain
skills and swarm exist to use. A 0/N without this number beside it cannot distinguish "the
description does not route" from "it routes and the fence blocks the payoff".

Sample rows pin both halves of the measurement: the instrument sha and a digest of the
INSTALLED description bytes. Measured 2026-09-01: a project-local .claude/skills/<name>/SKILL.md
is loaded, but a user-level skill of the same name wins, so the installed copy is what reaches
the matcher and a repo edit is invisible to this harness until installed. Digesting the repo
tree would pin a number to bytes the model never saw. This is the artifact discipline 1.47.0
withdrew two published numbers for lacking.

A low rate does not fail the run -- only a fence breach does. Wiring a rate to a red exit would
make the suite refuse to report the thing it was run to find out.

Verified: bash -n; shellcheck -S warning clean; tests/dispatch-static.sh green, 4/4 assertions,
28 cases still declared and matched, 0 model calls.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…keyword

writing-plans and test-driven-development had no isolated case. Their only positive coverage was
feature-chain's three-way alternation across brainstorming|writing-plans|test-driven-development,
which any one of the three satisfies alone. Both skills sit at zero lifetime dispatches across
2536 transcripts (tests/transcript-census.sh, re-run 2026-09-01) and this suite stayed green
throughout. A gate that cannot go red for a dead skill is not measuring that skill.

Each new case gets a setup_ function, because a fixture without one measures something else.
Measured 2026-08-27 (tests/evals/collision/RESULTS.md): in an empty workdir the prompt has no
referent, the model asks which repository is meant, and that scores identically to a routing
miss. Every prompt here names files that exist.

setup_spec seeds a SPEC.md that is settled and is explicitly not a plan, so brainstorming has
nothing to explore and executing-plans has nothing to execute. The ask is for ordered steps in
the reply rather than a file, because Write is denied by the fence and a fixture whose payoff
needs a denied tool cannot distinguish a blocked affordance from a routing miss.

setup_bugfix seeds a real defect plus a suite that demonstrably misses it. The prompt states the
cause outright, which starves principle-fix-root-causes; the suite existing starves
create-verification-skill and maintain-verification-skill.

swarm-audit is rewritten rather than added. The old prompt was "Audit this directory three
different ways at once" with no setup, and swarm's own description quoted "at once" back at it --
so the case measured whether the model echoes a keyword the description already contains, on an
empty directory. That is a keyword test wearing a routing test's name. The new prompt seeds six
non-importing integrations with six unrelated defects and states splittability as a property of
the work. All four quoted trigger strings are gone. The SessionStart routing table still carries
them; this case exercises the other path deliberately.

Six count claims move with the suite. Four are live totals and are renumbered 28 -> 30. Two are
historical measurements and are reworded instead: docs/how-skills-fire.md's routing-table arm and
tests/evals/build-the-lever/PREREGISTRATION.md both describe what a past arm measured, and
renumbering them to match today's tree would restate a finished measurement as something it was
not. Breaking the number-noun adjacency is the device this repo already uses for "falsifiability
rows"; extending .claude/verify.sh's exempt_phrases was not an option, that file is owned
elsewhere this week.

Verified: bash -n; shellcheck -S warning clean; tests/dispatch-static.sh green, 37 fixtures parsed
clean (was 25), 30 cases declared and matched; .claude/verify.sh check 12 reads "30 test cases".
The gate's four other failures (version, inventory, payload_digest, derived_at.head) reproduce
identically on pristine 1bfb133 and are the in-flight release, not this branch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
No model calls. Splits each description at its first ':', '.' or em dash into the discriminator
clause and the rest, then scores shared 2- and 3-grams per pair, weighted 3/2/1 by whether the
overlap lands in both first clauses, one, or neither. The only failing condition is a 3-gram
opening two descriptions -- the defect aebeebb fixed by hand when grill-me and interrogate both
led with "tear this apart". Everything else prints and passes.

The header says what this is not, at length, because the claim it would be mistaken for is
withdrawn. "Colliding triggers were measured over 80 samples to suppress both skills" has no
surviving runlog and was retracted in 1.47.0; the pre-registered replacement at
tests/evals/collision/ found the hypothesis unsupported on a committed instrument and located the
real mechanism in the harness instead. So this encodes design discipline -- discriminator in the
first clause, no two skills opening on the same words -- and explicitly not a dispatch law.

Its own self-test found three defects in it before the live corpus did, which is the argument for
carrying one:

The stoplist was a wrapped shell string. BSD awk rejects a newline inside a -v assignment and
exits non-zero having scored nothing, so the live corpus printed rc=0 with awk failing on every
invocation -- a green that measured nothing, the exact shape docs/checks-that-inherit-their-answer
catalogues. Now one line, with the reason on it.

score() returned awk's status without distinguishing a parse error from "no collisions". It now
refuses on rc>1 and on a corpus of fewer than two descriptions, rather than reporting a clean
result it never computed. That guard is what caught the third defect on the first live run: BSD
awk aborts on the em dash in several descriptions with "illegal byte sequence" under a UTF-8
locale. LC_ALL=C is now pinned, and the byte comparison in the HEAD/TAIL split is written against
those bytes deliberately.

The planted self-test collision was also wrong to begin with: "tear this apart" does not survive
stopword removal, dropping to a 2-gram the check correctly declines to fail. The plant is content
words now.

Verified: bash -n; shellcheck -S warning clean; --self-test green both directions (planted
collision fails and names the pair, clean corpus passes). Live corpus scores 23 across 28 skills,
no hard-fail pairs, with the two ordinal-frame overlaps visible as
test-driven-development/writing-plans "once shape" (6) and brainstorming/test-driven-development
"shape known" (4).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…nt arms

Two instrument gaps the baseline arm walked straight into.

MAX_TURNS was a literal. The baseline run came back cut off by error_max_turns on 40 of 40
samples, which means two of the four arms scored 0/10 without the run ever reaching a decision
point -- the exact turn-starvation signature that read encode-lessons-lint as a dead skill, and
which this file has warned about above case_max_turns since 2026-08-23. Probing that needed
either a source edit or a throwaway script, and the last time someone chose the throwaway script
the resulting numbers were withdrawn for having no committed instrument. It is an env var now,
and it lands in every runlog row so arms run at different budgets cannot be silently pooled.

stage-skill-descriptions.sh exists because a description edited in a checkout is invisible to
this harness. Measured 2026-09-01: tests/auto-trigger.sh runs the CLI in a scratch workdir, so
the descriptions that reach the matcher are the installed ones under ~/.claude/skills, and while
a project-local .claude/skills/<name>/SKILL.md IS loaded and listed, a user-level skill of the
same name wins -- asked to quote its own listing for `swarm`, the model returned the installed
text and reported no duplicate. An after-arm measured without installing would measure the
before-arm's bytes and publish it as a result. Running install.sh instead is not available this
week: it installs the whole tree, including another session's in-flight hook edits.

Both directions refuse rather than guess. --stage aborts if any installed copy already differs
from repo HEAD, because that means someone else is mid-edit and staging would carry their change
into the arm; it pre-flights every named skill before touching any, so a half-applied stage
cannot happen. --restore compares each file against the checksum it wrote and refuses that file
if it changed, keeping the original rather than overwriting a foreign edit -- a save/restore
harness in this repo has already destroyed two agents' uncommitted work by doing the opposite.

Verified: bash -n; shellcheck -S warning clean on both; --status reads the live installed digest
(d4251fb4eda7) and reports nothing staged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Review found both of these after the baseline ran and before any after-arm, which is the only
reason the numbers below are still usable.

The runlog row was built by printf with a bare %s for `fired`. That value comes from
.input.skill, a model-controlled tool-call argument, and nothing constrains it to be quote-free;
a value containing a double quote emits a line that fails `jq .`. The runlog is the thing the
provenance block calls the reason a published k/N is checkable, so a log its own subject can
break is not a record. It is built by `jq -cn --arg` now, verified valid for values containing a
quote, a backslash and a newline, with the old printf form reproducing the failure on the same
input. No baseline row was affected: every `fired` value across all 60 rows is a plain skill name
and the files parse.

stage-skill-descriptions.sh had unchecked cp calls in both directions. On the stage side a failed
copy would still write a manifest entry whose checksum is of the unchanged destination, so an arm
would run on stale bytes while the runlog swore they were new. On the restore side a failed copy
still printed "restored" and left rc at 0, after which the rm -rf deleted the only surviving
backup. Both are checked and both refuse now. That script took no part in the baseline.

Neither fix changes what a sample measures, so the arms stay comparable.

THE BASELINE, N=10 per arm, no early stop, unedited descriptions.

At the suite default of max-turns=3, 40 calls, $3.17: writing-plans 9/10, swarm 10/10,
executing-plans 0/10, test-driven-development 0/10. Every sample terminated error_max_turns, 40
of 40, including both arms that fired -- so being cut off separates nothing and cannot be offered
as the reason for the two zeros. It is reason enough to re-take them.

At max-turns=12, 20 calls, $5.61, cut-off drops to 0/10: test-driven-development 3/10,
executing-plans 1/10. Turn budget was carrying part of the TDD result and almost none of the
executing-plans one.

executing-plans is the finding. Its prompt and its unedited description are close to the same
sentence, and it fires once in ten. Whatever suppresses it, it is not that the description fails
to describe the situation. Two of its nine misses fired test-driven-development instead, on a
prompt containing no test, which is the only direct evidence in this run that those two
descriptions compete for the same prompts.

Two of the brief's premises do not survive. writing-plans fires 9/10 unedited. swarm fires 10/10
on a prompt carrying none of the four trigger strings its own description quotes, so the literals
are not what carries it. The transcript-census zeros are real; they are about how real prompts
are phrased, and this harness cannot separate that from how descriptions are worded. RESULTS.md
says so rather than claiming the credit.

Verified: .claude/verify.sh check 12 reads 30 test cases and check 31 (referrers) is green at 164
files. The four remaining gate failures -- version, inventory, payload_digest, derived_at.head --
reproduce identically on pristine 1bfb133 and belong to the in-flight release.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…tion

1/10 -> 6/10, N=10 per arm, no early stop, max-turns=12 both arms.

The old description was "Use when you have a written implementation plan to execute in a separate
session with review checkpoints". The fixture prompt is "PLAN.md is the implementation plan we
approved last session. Execute it, and pause for my review after each phase." Those are close to
the same sentence and it fired once in ten, so the problem was never that the description failed
to describe the situation. Two of the nine baseline misses fired test-driven-development instead,
on a prompt with no test in it.

That is what changed. Not the wording of the situation, which was already right, but that three
sibling descriptions all opened on `Nth, once the shape is X` and competed for the same tokens in
the clause a matcher weighs hardest. tests/description-collision.sh scores the corpus 23 before
and 13 after, and the entire 10-point drop is those two overlaps.

READ THE NUMBER WITH ITS CAVEAT.

6/10 meets the threshold I registered before the arm -- baseline <=1/10 and after >=6/10 -- and
does not reach significance. Two-sided Fisher on 1/10 against 6/10 is p=0.0573, which clears
neither 0.05 nor the Bonferroni 0.0125 that four tests want. The threshold was derived assuming a
0/10 baseline, where 6/10 would have given p=0.0108. The measured baseline was 1/10 and I never
re-derived it. So the check passed while the thing the check stood for did not, which is the
defect docs/checks-that-inherit-their-answer.md exists to catalogue, committed here in my own
pre-registration. Separating 1/10 from 6/10 at that alpha needs roughly n=20-25 per arm, about
$12 more at this budget, and that call is not mine to make.

The misroute did not close: still 2/10 to test-driven-development. Whatever makes these two
compete is narrowed by the rewrite, not removed.

The runlog beside this commit is the after arm for this case. All four descriptions were
installed together when it ran (digest 5cf618030b60 on every row), because the four are designed
to be mutually exclusive OF EACH OTHER and a rate taken while three still carried ordinals would
measure a tree that never ships. So this file's 6/10 is attributable to the shipped set, not to
this one description in isolation.

Description is 168 chars against check 3's 200 cap.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…it changed nothing

3/10 -> 3/10, N=10 per arm, no early stop, max-turns=12 both arms. Two-sided Fisher p=1.0.

The rewrite did not move this skill and I am not going to present it as though it did.

What it did do is remove the reason the old wording was indefensible. "Third, once the shape is
known, including any bugfix" asserts a position in a chain the matcher cannot see: it was never
told there is a chain, and nothing in a single prompt lets it verify that this is step three of
four. The chain lines live in the SessionStart routing block, injected once, not attached to any
description. The replacement asserts a property of the prompt instead, which is at least
checkable against what the model has in front of it.

It also cost this skill both of its trigger-token overlaps. It shared "once shape" with
writing-plans and "shape known" with brainstorming, in the first clause, which is the zone
aebeebb identified as the one a matcher weighs hardest. tests/description-collision.sh scores the
corpus 23 before and 13 after; those two pairs are the whole delta.

So this commit buys a defensible description and a lower collision score, and buys no measured
dispatch. Both statements are in the runlog beside it.

The one place the old overlap showed up as behaviour is in the executing-plans arm, not this one:
2 of that skill's 9 baseline misses fired test-driven-development on a prompt with no test in it,
and it is still 2/10 after. Narrowed, not removed.

A caveat that limits this arm specifically. 3/10 at max-turns=12 is a stochastic rate, and n=10
cannot separate 0.3 from 0.5. It can separate "never fires" from "fires about half the time",
which is what it was sized for. This arm establishes that test-driven-development is weak rather
than dead, and nothing finer.

The runlog was taken with all four rewritten descriptions installed together (digest
5cf618030b60 on every row), because the four are mutually exclusive of each other and an arm run
against a half-rewritten tree measures something that never ships.

Description is 169 chars against check 3's 200 cap.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ing in for

10/10 -> 10/10, N=10 per arm, no early stop, max-turns=3 both arms. No regression, and no
improvement was available.

The brief said swarm fires only when the user says "in parallel". The baseline refutes that:
swarm fired 10/10 on a prompt containing none of the four strings its own description quoted --
not "in parallel", not "at once", not "all of these", not "try N ways" -- because the fixture
describes six non-importing integrations needing six independent verdicts. The situation was
carrying it the whole time. The literals were decoration on a description that already worked.

So this is a simplification with a measured no-regression, not a fix. The description now states
the cardinality-and-independence condition it was really matching on: three or more independent
units, none needing another's result. That is also why it is the one skill here that does not sit
on the planning-chain axis at all, and can co-fire with any stage of it.

The literals are not lost. claude/hooks/inject-session-context.sh still carries them on its swarm
routing line, and that file is owned elsewhere this week. The division of labour is the one the
hook's own preamble states: the routing block spells out what descriptions do not reliably
trigger. This change moves swarm off needing that crutch without removing it.

Measuring an arm with no headroom is the point rather than a waste. Changing a description that
scores 10/10 and not re-measuring it is how a regression ships as a cleanup, and this repo has
shipped enough of those. The runlog beside this commit is what makes "no regression" a reading
instead of an assumption.

The runlog was taken with all four rewritten descriptions installed together (digest
5cf618030b60 on every row). All 10 samples terminated error_max_turns at max-turns=3, as they did
at baseline; the Skill call precedes the cut, so the hits stand, and the arm is budget-matched to
its baseline.

Description is 186 chars against check 3's 200 cap, down from 194.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
9/10 -> 10/10, N=10 per arm, no early stop, max-turns=3 both arms. Two-sided Fisher p=1.0. The
one-sample difference is noise at this n and should not be read as an improvement.

The brief listed writing-plans among three skills that have never fired. That is true of the
transcript corpus and false of this harness: it fired 9/10 on the unedited description, before
anything in this branch touched it. There was no defect here to fix and no headroom to fix it in.

What the rewrite buys is the same thing it buys for its two siblings. "Second, once the shape is
agreed and before code" asserts a position in a chain the matcher cannot see. The replacement
asserts three things about the prompt itself: requirements settled, nothing written down about
how, more than one edit of work. It also drops the "once shape" overlap this description shared
with test-driven-development in the first clause, which is 6 of the 10 points
tests/description-collision.sh loses between 23 and 13.

THE CAVEAT THAT LIMITS BOTH ARMS, and it limits them badly enough to state here rather than only
in RESULTS.md.

This fixture shares its hinges with the description it tests. It says "SPEC.md is agreed" against
a description reading "once the shape is agreed", and "before anyone touches app.js" against
"before code". That is not a quotation, but it is the same two hinges, and a fixture built from a
description's own hinges will fire more often than a real request does. 9/10 here beside 0 across
2536 transcripts is most economically explained by real prompts not stating the situation this
plainly -- a claim about how people phrase requests, not about how descriptions are worded. This
arm cannot separate those two, and neither the before nor the after number should be quoted as
evidence that the skill works in production.

An earlier draft of RESULTS.md attributed a phrase to this description that does not appear in
it. Review caught it. The overlap named above is the real one.

The runlog was taken with all four rewritten descriptions installed together (digest
5cf618030b60 on every row).

Description is 178 chars against check 3's 200 cap.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… earning it

Four arms, N=10 each side, no early stop, every arm budget-matched to its own baseline. 40 calls
after, $7.41; $16.19 and 100 calls across everything published here.

  executing-plans          1/10 -> 6/10   p=0.0573   moved, not significant
  test-driven-development  3/10 -> 3/10   p=1.0      unchanged
  writing-plans            9/10 -> 10/10  p=1.0      no regression, no headroom
  swarm                   10/10 -> 10/10  p=1.0      no regression, no headroom

The registered threshold was: fixed when baseline <=1/10 and after >=6/10. executing-plans came
in at exactly 1/10 and 6/10, so it passed. It should not have been written that way. I derived
"6/10" against an assumed 0/10 baseline, where it gives p=0.0108 and clears the Bonferroni 0.0125
four tests want. The measured baseline was 1/10 and I never re-derived the bound. Against 1/10,
6/10 is p=0.0573 and clears nothing.

The check passed while the thing it stood for did not. That is
docs/checks-that-inherit-their-answer.md, in my own pre-registration rather than someone else's,
and the entry is written up as such rather than quietly repaired. Resolving 1/10 against 6/10 at
that alpha needs roughly n=20-25 per arm, about $12 more.

What the arms actually establish. Two of the brief's premises are false of this harness:
writing-plans fires 9/10 unedited and swarm fires 10/10 on a prompt carrying none of the four
trigger strings its own description quoted. The transcript-census zeros across 2536 transcripts
are real, and they are about how real prompts are phrased rather than how descriptions are
worded. This arm cannot separate those, and RESULTS.md says so instead of taking the credit.

The writing-plans fixture shares its hinges with the description it tests -- "SPEC.md is agreed"
against "once the shape is agreed", "before anyone touches app.js" against "before code". Neither
its 9/10 nor its 10/10 should be quoted as evidence the skill works in production. An earlier
draft of this file supported that same caveat with a phrase that does not appear in the
description at all; review caught the fabrication and the real overlap replaced it.

Two claims were also removed for outrunning their data. The baseline section said the starved
arms "never reached a decision point"; the runlog carries fired and subtype and no turn trace, and
the arms that fired were also 10/10 cut off, so being cut off separates nothing. It now says only
that the zeros were taken at a budget every sample exhausted, which is reason to re-take them and
not reason to publish them.

Verified: .claude/verify.sh check 12 reads 30 test cases, check 31 green at 168 files, check 3
clean on all four rewrites (168-186 chars against a 200 cap). dispatch-static.sh 4/4, 30 cases,
zero model calls. description-collision.sh self-test green both directions, corpus 23 -> 13, no
hard-fail pairs. stage-skill-descriptions.sh restored ~/.claude to d4251fb4eda7 with nothing
staged. The four remaining gate failures reproduce identically on pristine 1bfb133 and belong to
the in-flight release.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@itsvedantkumar
itsvedantkumar merged commit abd922a into main Sep 2, 2026
3 of 15 checks passed
@itsvedantkumar
itsvedantkumar deleted the skill-autofire branch September 2, 2026 05:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants