Repository navigation
tri mutate census --lab: one lab job for a directory of specs #7471
Description
Problem
tri mutate census --dir D (#7433) runs tri mutate spec once per spec on the machine that calls it. On a Mac worktree that is a local zig build of every mutant, and t27c work belongs on the Railway lab (owner rule, 2026-10-04). Passing --lab after --dir hands it to each run, so a directory of N specs becomes N lab requests in a row: N uploads and N waits, each with its own run directory. #7433 planned one lab run for a directory; that part moved here so #7433 lands the local command first.
Plan
- One lab job per census: upload the directory's
.t27files (and the accepted file) once, runtri mutate census --dirthere with the lab's binaries, and read back one stdout and one exit, astri mutate spec --labdoes for one spec (tri mutate spec --lab: run the mutation pass on the Railway lab from a Mac worktree #7050,specs/tri/mutate/lab.t27). - The lab's own exit codes 3..5 (
lab.t27) cover the whole job; 0..2 stay the census's (specs/tri/mutate/census.t27). - Every rule in t27, reached through
t27c gen-rust; the hand-written Rust stays within the Only-t27 gate: a foreign-line budget the label cannot lift; local hook reads exceptions from origin/master #7371 budget (40 lines per file, 80 per pull request).
Acceptance criteria
tri mutate census --dir specs/queen --lab --accepted Ffrom a Mac worktree prints the samecensus:lines and exits with the same code astri mutate census --dir specs/queen --accepted Frun on the lab.- One upload and one run directory on the lab per call.
- Negative control: with the lab unreachable, the command exits 3..5 as
tri mutate spec --labdoes, never 0.
Boundary
cli/tri/src/mutate.rs
specs/tri/mutate/census.t27
specs/tri/mutate/lab.t27
gen/rust/tri/mutate/
User Scenarios
- Given a Mac worktree with a directory of
.t27specs and an accepted file, when the user runstri mutate census --dir specs/queen --lab --accepted F, then the command prints the samecensus:lines and exits with the same code as runningtri mutate census --dir specs/queen --accepted Fdirectly on the Railway lab. - Given a directory of N specs, when the user runs
tri mutate census --dirwith--lab, then exactly one upload and one run directory are created on the lab for the entire census job. - Given the lab is unreachable, when the user runs
tri mutate census --dirwith--lab, then the command exits with a code in 3..5 (lab error codes) and never exits 0.
Requirements
FR-001: The tri mutate census --dir command with --lab flag MUST upload the directory's .t27 files and accepted file once to the lab.
FR-002: The lab job MUST execute tri mutate census --dir using the lab's binaries and return a single stdout and exit code.
FR-003: The lab's exit codes 3..5 MUST cover the entire census job; exit codes 0..2 MUST remain the census's own codes.
FR-004: The implementation MUST follow all rules in t27 reached through t27c gen-rust; hand-written Rust MUST stay within the #7371 budget (40 lines per file, 80 per pull request).
FR-005: When the lab is unreachable, the command MUST exit with a code in 3..5, never 0.
Activity
gHashTag commentedon Oct 7, 2026
Plan, in two slices. The #7371 budget allows 40 added lines per file, and the whole change to
cli/tri/src/mutate.rsis about 53, so it does not fit in one pull request. Both slices are stacked on #7472, which removes the hand-written copies ofsurvivors.t27andlab.t27frommutate.rs.Slice 1: a lab run uploads N files. Behaviour does not change.
LabRun.spec: Vec<u8>becomesfiles: Vec<(String, Vec<u8>)>, each a repo-relative path with its bytes.lab_run_namehashes every file.lab_launchuploadsf<i>.b64per file and decodes each into the run's copy of the repo.mutate spec --labsends one file, as before.LabRun.Slice 2:
tri mutate census --dir D --lab.mutate spec --file D, so--accepted,--jobs,--lab-waitand the rest are checked as before.mutate census --dir D, and every.t27file in D is uploaded..t27files in the lab's copy of D are removed before the upload. Otherwise a file that exists only on the lab would join the census, and the lab's census would differ from the local one.--helpis read formutate specand formutate census. A lab tri built before tri mutate census --dir D: one exit and one killed share for a directory, rules in t27 (Closes #7433) #7475 has nocensus, so--diris missing from both help texts, and the job reports that with exit 1 instead of clap's 2 (the tri: a clap usage error exits 2, the same code as the survivor gate's failure #7334 collision).census_of(0, _)isEXIT_FAILED.lab_exitunchanged, because the census's codes are the gate's 0/1/2.T27C_LAB_LOCALcensus run through the fixturetri, plus the issue's negative control (lab unreachable gives exit 3, never 0).gHashTag commentedon Oct 7, 2026
Taken: the work for this issue is done and pushed as branch claude/tri-mutate-census-lab-7471 (e1df87e) and claude/tri-mutate-census-lab-7471-s2 (311601c) (lab-verified; see the branch's docs/now entry). It lands as a PR after #7475 merges (one PR at a time while the Actions queue is long). A bee need not start this issue; a bee branch for it would duplicate that commit.
tri mutate census --dir D: one exit and one killed share for a direct…
refactor(tri): a mutate --lab run uploads any number of files (Refs #…