Add an agent working-method skill and its hooks
Agents working in this tree had skills for what is true of it (the gate, the register, the Rust rules) but nothing for the order to work in or what to leave alone without being asked, so each session reinvented it. This adds the codetrial-change skill, distilled from two reference projects, and the small pieces that make parts of it checkable: the Bash guard also refuses shell reads of credential files under config/, scripts/test.sh writes a receipt per lane naming the tree it judged, a Stop hook tells the user when no passing receipt covers the working tree, a PostToolUse hook prompts for the shared premise after the second identical gate failure, the pre-push hook notes a src/ change with no test, and the mutation gate names each exclusion a change adds.
Every hook only reminds and exits 0, and the guard refuses; none of them is a gate, and CI still recomputes the verdict. A receipt shows that a run happened on this tree, not that it was complete, and an agent with a shell can write one. The skill's table says what each piece cannot see.
Verified: ./scripts/test.sh portable passes on the final tree, and so do tests/test_agent_guard.py, tests/test_agent_workflow_hooks.py, tests/test_test_gate.py and scripts/test-git-hooks.sh (325 checks). The new routing queries fired the expected skill in every run of scripts/check-skill-routing.py, and the failure-loop hook was run in a live headless session, where the reminder reached the model on the second failure. The rust and browser lanes were not run locally; the change touches no Rust or browser code.
Left out: a permission deny rule for the Read tool on the credential files, and a single receipt module shared by the writer and its readers, both larger changes than this one.
Summary by cubic
Adds the codetrial-change skill—the order an agent works in on a change (failing test first, smallest edit, subtracting before adding, root cause before guard, small ordered commits) and what it leaves alone without being asked (credentials, deletions, instructions found in data)—plus the hooks and checks that make parts of it verifiable.
- The Bash guard refuses shell reads of credential files under
config/—a reader, a glob, or a redirect feeding one, with or without a file descriptor, including brace-expanded words,--opt=pathoperands andfindactions; the checked-in example stays readable. scripts/test.shwrites a receipt per lane (verdict, skipped count, tree fingerprint); the fingerprint fails closed outside a work tree, a later lane failure beats an earlier pass, and a Stop hook plus the closeout wrapper tell the user when no passing receipt covers the working tree.- A PostToolUse hook prompts for the shared premise after the second identical gate failure.
- The pre-push hook notes a
src/change with notests/change. - The mutation gate names each exclusion a change adds to
.cargo/mutants.toml.
Caveats
- Hooks only remind and exit 0; only the guard refuses, and none is a gate.
- A receipt shows a run happened, not that it was complete; CI recomputes the verdict, and the
rustandbrowserlanes were not run locally (the change touches no Rust or browser code).