After GoogleChrome/modern-web-guidance's router-and-corpus design (references/research-modern-web-guidance-2026-11-11.md). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
9.6 KiB
3. Hands executes one cut
(Moved verbatim from SKILL.md on 2026-11-11 so the skill loads small; SKILL.md keeps a pointer.)
Size the cut against Hands' context budget before dispatch. Self owns this, for map cuts and fix batches alike. Sonnet degrades at about 0.5M tokens of context (operator, 2026-09-25), and the sloppiness starts earlier: Aetheria's stats and shield Hands got "loopy" past 400k, and a StreamPixels fix batch past 550k produced sloppy code. Treat 0.5M as the danger line, never the target. Size by calls too: each call re-reads the context, so an agent's reads grow with the square of its calls. A cut that needs more than about 150 Hands calls is two cuts, or one cut and a continuation.
Before dispatch, Self estimates what the run will carry:
- the brief, and the
cut_specHands views; - the source Hands must read to edit safely: the files it touches and their direct callers, not the repo;
- one verification round at the end and one fix round, with their output; test and mutation logs are usually the largest items;
- the number of separate items. StreamPixels' ten-item batch ran to about 800k tokens; split per file, batches stayed at 200-400k. So a fix batch is one file's findings by default.
Runs overshoot their plans, so split when the estimate passes about half the line. Split by file or by deliverable, each part with its own verification. A late item gets its own brief; it never joins a batch that is already planned. Splitting a cut always beats a bloated brief. When the report comes back, compare the agent's reported token total with the estimate, and cut finer next time where it overran.
Brief Hands with the cut_spec id, the campaign session label, and the
rulings in force that the spec cites. Hands reads the spec with view, so
nothing is pasted or paraphrased. The brief says:
- Follow the spec, do not redesign. If the Body contradicts the spec, fix the
smallest thing that keeps the spec's intent true and record the discrepancy in
the report's
deviations. If it is a real fork, admit it as aquestionraised in the spec, stop, and report. A fork hit before the first commit ends the pass with the question alone: report its id and receipt, and admit nocut_report. - Gaps are filled in their owner, never worked around locally. If CultMath lacks a function, CultMath gets it; the consumer does not grow a helper.
- Delete before adding. No shims, no compatibility layers the map did not name.
- Small commits, each pushed, with explicit paths. See the git rules below.
- Every operator ruling and every new rule gets a test that fails when the rule breaks, and the test describes behaviour, not code shape. The operator, 2026-09-22: "Tests should cover how the code behaves, not how it is shaped."
- Verification is proportional to who depends on the code. The mutation pass below and a Soul falsification are for code others build on: CultLib and the other shared libraries, infrastructure, persistence, protocols, auth, money. A silent break there spreads to every consumer. Visual and interface work (a colour, a layout, a blur radius, a page) is verified by looking at it in a real browser at desktop and phone width, plus a test only where a rule would otherwise break unseen. It gets no mutation pass and no Soul, and no test pins its exact values. Operator, 2026-11-10, after one day spent ~818M prompt tokens of Self runs, mostly on re-verifying small changes: "We have burned an absurd amount of quota today and don't have all that much to show for it". The example: seven PRs, each mutation-pinned and re-read, on one footer band.
- Measure the suite with the ecosystem's mutation tool, scoped to the cut's
diff (shared code, per the line above): Stryker.NET for C#, cargo-mutants for Rust, StrykerJS for
TypeScript, mutmut for Python. The tool generates the mutants and nobody
writes an anchor. cargo-mutants runs through
tools/cargo-mutants.sh(per-file scoped tests, survivors confirmed against the full suite, sharded over Yggdrasil slots), once per Hands pass. Each mutant runs under its own memory and time cap (a container--memory,systemd-run --scope -p MemoryMax= -p RuntimeMaxSec=, orprlimit): a mutant that deletes a size guard grows without bound, and on 2026-11-07/08 such mutants of Bifrost's media reader took Yggdrasil to global OOM four times. Every survivor is a finding about the tests, triaged by name: a behavioural test is missing, a fixture is degenerate (see below), or the mutant is equivalent and gets a one-line reason. Boundary flips on float thresholds are equivalent by default and are not chased. The score is not a gate; the triaged survivor list is the record. The report'smutations(at most 64) holds every survivor and the kills Soul should rerun; the totals (generated, caught, unviable, missed) go in itsverificationevidence. Each survivor also gets adeviationsentry with its triage, because the mutation record has no field for it (substrate gapeureka-substrate:follow_up:gap-mutation-triage-field). Soul reruns the tool on the range rather than trusting Hands' triage. - No committed hand-written mutation suites, and no fallback harness. The operator ruled this on 2026-09-22: "Better to have nothing than a harness that punishes refactoring." Anchors couple a suite to the code's spelling. They strand on every refactor, and they can keep matching while silently re-targeting onto code the tests no longer run. Where no tool reaches (C++, shaders, editor code), the defence is behavioural: observe the rule where it is decided, for example with a dev-only seam and exact equality, and use scenarios at the layer where the rule would fail. Soul may still mutate code by hand as a one-off probe during a pass. Such a probe is never committed as a suite, and a kill it finds becomes a behavioural test.
- "This rule cannot be pinned" is a claim, and Soul falsifies it like any other. Recording an honest gap is right and beats inventing a kill, but the gap itself is a hypothesis about reachability, and it was wrong both times it was made in one day. A daemon arm was written off because its failure paths needed a corrupt store; a probe built from the crate's own public surface killed two mutants that the shipped suite let through. A bridge rule was written off because reaching it needed a listener, a credential and a connection; a client opening to a closed port reached it in about a millisecond, in fifteen lines, and the mutant crashed an ordinary optimised build on contact. So write the gap as not yet reached, never as unreachable, and put reaching it at the top of the next Soul brief. A rule written off as undefendable that is merely undefended is worse than a surviving mutant, because the suite and the prose agree with each other and both are wrong.
- Name the weakest thing that would still pass, and ask whether that is the rule. A test proves some property; the question is whether that property is the rule or a cousin of it that the rule implies. One bridge line, "the wait is the timeout the host asked for", took three passes because each fix proved a slightly stronger cousin. First the suite proved the wait was not one particular constant, which a different constant defeated. Then a scenario measured elapsed time at two values with non-overlapping bands and proved the wait was not any constant, which a clamp defeated: capping the wait so that shutdown gets noticed is the most ordinary spelling that line will ever be given, and it is a function of the argument rather than a replacement for it. So when a rule says a value is derived from an input, at least one mutant must itself be a function of that input — a clamp, an offset, a scale — and probe values must sit where such a function would show. Constants are never the hard case; they are only the first one.
- Put the observation where the rule is decided, not after it. A probe sited downstream of the thing it interrogates creates a blind spot by construction, and every mutant of that thing lands in it. A bridge scenario held its callers after the wait whose duration was the rule, so replacing a caller's timeout with a hard-coded two seconds walked through the entire committed matrix on both targets. The committed entry appeared to defend the rule, and only defended a constant smaller than another constant. When a mutant dies, ask which of the two it actually contradicted.
- A loosening that cannot fail is a finding about the fixtures, not licence to substitute an easier one. When the mutant that weakens a rule still passes, the usual cause is that every fixture differs in more ways than the rule cares about, so the weakened check keeps getting the right answer for the wrong reason. Report it and fix the fixture. In Cut 10 of the pipeline-state campaign, Hands quietly swapped two such loosenings for different ones and reported a clean sweep; Soul then found that comparing only the lengths of two instance names, or only their first bytes, survived both suites, because no fixture pair had ever shared a length. The rule had no defence and the suite said it had two.
- Admit one
cut_report: commits (and which don't build), the range, the verification evidence, mutations, deviations, forks, the structural delta, what was left undone, and the promises Soul will measure. The report to Self is its id plus raw output too long for an evidence line. Hands never edits the prose map.
Parallel Hands are fine when they touch different repos or worktrees. They are not fine in the same working tree, and never while a Soul pass reads that tree.