← board

testmgr --pin gates with the FULL tier by default

# tools/testmgr.py, run_pin(), ~line 2581
tier = args.tier or "full"

python3 tools/testmgr.py --pin therefore runs --tier full — 2305 jobs, every cross target — before it stabilizes and pins. Two operators (the human at the terminal and the agent) both killed it as a hang; it was not hanging, it was doing an hour of work that nothing asked for.

Why this is a defect and not a preference

run_pin's own docstring quotes the decision it then contradicts:

(stabilize-fast, not stabilize -- user, 2026-08-09: all-target verification belongs to a RELEASE, not to a pin.)

The stabilize half honours that and runs stabilize-fast (~35–41s measured). The gate half above it still defaults to all-target, so the cost the 2026-08-09 decision removed came back through the other door — and this time with the repo lock held, which the code states plainly:

The repo lock is held for the WHOLE pin, gate included: a concurrent [build] ... (nothing else may build meanwhile).

So the default blocks every other lane for the duration. That is precisely the "other tracks — and the human — are BLOCKED while a pin runs" cost CLAUDE.md weighs when it tells Track A to use stabilize-fast.

Measured, 2026-08-13

step time
make stabilize-fast (self → next → fixedpoint, byte-identical) 41s
make pin (symlink move + freeze 7 builtin RTL sources) 0.07s
testmgr --pin's gate at the default tier full — 2305 jobs, never allowed to finish
gate.sh quick (the documented PIN GATE) ~30s

The gap this leaves today

Neither available option is the one an operator wants:

"Cheap gate, fast pin" is what the pin philosophy already describes, and it is the combination you cannot currently ask for by default. (v267 was pinned via the first option on 2026-08-13; the safety came from the operator having run gate.sh quick, make test-nilpy and --tier limited 1801/1801 beforehand, not from the command.)

Proposed fix

Default --pin's gate to quick, and keep --tier full as the explicit opt-in for a RELEASE pin:

tier = args.tier or "quick"

That matches tools/gate.sh quick being named THE pin gate in CLAUDE.md, keeps --pin --tier full available for a release, and leaves the checkpointing (gated_sha) untouched. Worth deciding alongside it:

Workaround until then

python3 tools/testmgr.py --pin --tier quick--tier IS honoured with --pin (it is only required for a plain run), so the gated fast pin exists today; it is just not what the bare command does.

Gate

tools/testmgr.py --tier full green (Track T's own gate for tooling changes), with the tool exercised the way Track T's rules prescribe — QUICK tiers and a scratch bare repo, never long runs. Assert both directions: the bare --pin gates quick, and --pin --tier full still gates full.

Also noticed, trivial and separate

tools/trackt.py is not executable — tools/trackt.py health answers "Permission denied" and needs python3 tools/trackt.py health. A chmod +x, worth folding into whatever touches Track T's tooling next rather than its own ticket.

FIXED 2026-08-13 — by the agent that wrote the defect

Accepted in full; the report is correct and the reasoning is the one that should have been applied when --pin was written the day before. run_pin quoted the 2026-08-09 decision in its own docstring and then contradicted it one branch later.

Verified both directions end to end, with the gate child's argv captured rather than executed: bare → --tier quick, --tier full--tier full. Pinned as a case in tools/devtest_pin_atomic.py, run against a scratch tree per Track T's "QUICK tiers and a scratch repo, never long runs" rule.

Log