fix(pin): the pv pin called a runner fault a pinning defect — the classifier existed and nothing asked it - #3216
Merged
Merged
Conversation
…ssifier existed and nothing asked it guard-cargo turned #3212 red with FAIL pv-pin the pin failed to resolve pv (rc=1) — a release cannot be decided by a verifier that did not build. That names a CODE cause. The cause was the host: cargo died with `could not parse/generate dep info at: …/target/debug/deps/regex-<hash>.d` / `No such file or directory (os error 2)`. The proof is in the same job's own log — the NEXT pv row, 39 s later, built the same pv from the same tree and passed. The repo already knew this signature. scripts/cargo_classify.sh ships row C8, "dep info, and the host had 933G free -> ENV", with a committed fixture named log_env_dep_info_contention.txt, written precisely so a dep-info death is not read as ENOSPC and not read as a code defect. The classifier existed, was self-tested, and the pin never called it. The defect is an unasked rule, not a missing one. WHAT CHANGES pv_bin.sh captures its own cargo build, classifies a failure, and prints the shared ENV block instead of "cargo build of aprender-contracts-cli failed". verifier_pin.sh verifier_pin_pv gains rc=3 = "the build did not reach a verdict on this host". rc=1 was answering two different questions with two different responses. check_verifier_pinning.sh rows 4/4b/4c report ENV and count the row as UNMEASURED; the summary says so. Additive — the FAIL line still prints, because a run can carry both a runner fault and a real pinning defect. NOT FAIL-OPEN. Every ENV path still returns non-zero and the job still goes red: a pin that did not resolve decides nothing, whatever killed it. The only thing that changes is which cause is named, and therefore whether the response is "triage the runner and re-run" or "hunt a pinning defect that is not there". NO RETRY, deliberately. The evidence says one retry would have turned this job green, which is the argument against it: a retry converts a measurable runner fault into a slower green, and contention that never reaches a CI verdict is contention nobody schedules against. SIX NEW ROWS, and two of them are the plumbing. LIBS / CLASSIFIER / ENV-LOG / CODE-LOG judge pure functions and would stay green with the pin left entirely unwired — that is how #3207 shipped 26 green rows that recorded nothing. The two PIN-RC rows call verifier_pin_pv for real against a throwaway git repo whose pv_bin.sh reproduces each death, and assert the rc callers switch on. Mutation-verified, all three killed by the row that should kill them: delete the rc=3 arm -> PIN-RC(env) RED, everything else green drop dep-info from the ENV sig -> CLASSIFIER + ENV-LOG + PIN-RC(env) RED widen ENV to match /error/ -> CLASSIFIER + CODE-LOG + PIN-RC(code) RED The third is the fail-open direction and it is caught. Full guard PASS on this tree; bashrs 0 errors on all three files; the shell-lint ratchet does not grow. Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
noahgift
enabled auto-merge
September 13, 2026 12:35
|
§13.11 rung 1 — quorum shadow verdict Shadow mode: this records a verdict and merges nothing. A refusal |
…ipped script check_hardcoded_paths.sh caught it on the first run, correctly: copying the #3212 failure text verbatim put /home/noah/data/actions-runner-2/_work/... into scripts/, and the shipped tier is a DIFFERENTIAL ratchet against main, so one is one too many. Elided to <workdir>. Nothing is lost — the classifier anchors on cargo's own framing (`could not parse/generate dep info`, `(os error 2)`) and never on the path, so all six rows prove exactly what they did before. "Verbatim" was fidelity to the wrong thing. Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #3215
guard-cargoturned #3212 red withThat names a CODE cause for a runner fault. cargo died with
could not parse/generate dep info at: …/deps/regex-<hash>.d/No such file or directory (os error 2), and the proof it was the host is inthe same job's own log: the next pv row, 39 s later, built the same pv from
the same tree and passed.
The repo already knew the signature.
scripts/cargo_classify.shships rowC8 — "dep info, and the host had 933G free -> ENV" — with a committed
fixture
log_env_dep_info_contention.txt, written so a dep-info death is notread as ENOSPC and not read as a code defect. The classifier existed, was
self-tested, and the pin never called it. The defect is an unasked rule.
What changes
pv_bin.shcargo build, classifies a failure, prints the shared ENV block instead ofcargo build of aprender-contracts-cli failedverifier_pin.shverifier_pin_pvgains rc=3 = "the build did not reach a verdict on this host". rc=1 was answering two questions that have two different responsescheck_verifier_pinning.shENVand count the row as UNMEASURED; the summary says soNot fail-open. Every ENV path still returns non-zero and the job still goes
red — a pin that did not resolve decides nothing, whatever killed it. The only
thing that changes is which cause is named, and so whether the response is
"triage the runner and re-run" or "hunt a pinning defect that is not there".
The ENV summary line is additive: the FAIL line still prints, because one run
can carry both a runner fault and a real pinning defect.
No retry, deliberately. The evidence says one retry would have turned this
job green — which is the argument against it. A retry converts a measurable
runner fault into a slower green, and contention that never reaches a CI
verdict is contention nobody schedules against.
Six rows, and two of them are the plumbing
LIBS/CLASSIFIER/ENV-LOG/CODE-LOGjudge pure functions and wouldstay green with the pin left entirely unwired — that is exactly how #3207
shipped 26 green rows that recorded nothing. The two
PIN-RCrows callverifier_pin_pvfor real, against a throwaway git repo whosepv_bin.shreproduces each death, and assert the return code callers switch on.
Mutation-verified — each killed by the row that should kill it:
rc=3armPIN-RC(env)RED, everything else greendep infofrom the ENV signatureCLASSIFIER+ENV-LOG+PIN-RC(env)RED/error/CLASSIFIER+CODE-LOG+PIN-RC(code)REDThe third is the fail-open direction, and it is caught.
What was ruled out, and what was not
Both host cleaners were checked against the 11:59:16–11:59:35Z window and
neither ran:
ci-disk-watchlogged448GB free (trigger below 400GB)at11:59:37Z;
ci-reaperran at 11:01:25Z and 12:04:26Z. What removedtarget/debug/deps/mid-build is not established — this PR is about theverdict, not the cause.
Verification
check_verifier_pinning.shfull run: PASS (rc=0), pv builds and resolvescheck_verifier_pinning.sh --self-test: PASS, 6 new rowsbashrs lint: 0 errors on all three filescheck_bashrs_gate.sh: PASS, 295 filescheck_shell_lint_ratchet.sh: PASS, baseline does not grow🤖 Generated with Claude Code