Prove every marker the release box classifies by, or the coverage test goes red - #261
Merged
Merged
Conversation
…t goes red When a pip step in the release-gate box fails, classify_pip_failure decides whether the verdict blames the BOX's network (box_network_unreachable) or the ARTIFACT under test (artifact_install_failed). Both are a FAIL; only the claim differs, and that claim is load-bearing. On 2026-07-27 a run whose link had collapsed to 13 KiB/s aborted twice blaming the artifact, for a wheel that installs in 1.4 seconds on a healthy link. A verdict naming the artifact when the artifact was never reached is a false accusation against a released wheel, and it points the next operator at the wrong repository. The decision rests on two regex alternation lists: 10 artifact markers and 17 transport markers. Measured before this change: 6 of 17 transport alternatives appeared in any test, and ZERO were load-bearing, because each of the three network fixtures matched two or three alternatives at once -- deleting any single transport alternative changed no test result. Of the artifact markers, 4 of 10 appeared and only 2 were load-bearing. A pattern list nobody proved matches is a gate selecting by a value it never grades: a typo, a case change or an upstream rewording silently reclassifies a dead link as a broken wheel. So every alternative in both lists now has captured pip output that matches it and nothing else, and deleting that alternative flips a real verdict. The degraded shapes the incident class is actually about are the ones that had no coverage at all, and they are covered now: a truncated body mid-download, a chunked response whose last chunk never arrives, a middlebox resetting the connection, a connect-phase stall, retries exhausted against a 503-ing index, a captive portal presenting its own certificate, and name resolution failing a second way. Every artifact alternative is graded THROUGH a degrading link, because an artifact-only log classifies as artifact via the default branch and therefore proves nothing. Four mixed shapes are named, including one where the unpack failure prints BEFORE the transport noise, so the ordering rule cannot be passing by reading position. The set-equality test is the part that keeps this true: it parses both lists out of the shipped runner, refuses a list it cannot read rather than reporting an empty one, asserts the counts are non-zero BEFORE any coverage claim, and then asserts the covered set equals the shipped set in both directions. A marker added to the runner without a fixture turns it red by name. Three transport alternatives cannot be proved alone because real pip never prints them without a partner; they are declared as subsumed and proved as pairs, and the declaration is self-guarding -- over-declaring any alternative fails its own deletion assertion. Four reason codes the runner emits were taught by no operator playbook at all, including the two a killed run produces. The playbook now carries them, and a test binds all nineteen emitted codes to it. Nothing here runs Docker, needs a key, or can trigger a box run. The runner and the driver are unchanged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
CONTRACT
When a pip step in the release-gate box fails,
classify_pip_failure(tests/e2e/scripts/e2e-runner.sh) decides whether the verdict blames the box's network (box_network_unreachable, exit 11) or the artifact under test (artifact_install_failed, exit 8). Both are a FAIL. Only the claim differs — and the claim is load-bearing, becausedocs/box-operator.mdanddocs/release-gates.mdteach operators to read theartifact_*family as "the box worked and the artifact did not."On 2026-07-27 that reason was emitted twice for a run whose link had collapsed to 13 KiB/s and which never installed, imported or executed the wheel. The same wheel installs into a clean venv in 1.4 seconds. A verdict naming the artifact when the artifact was never reached is a false accusation against a released wheel, and it points the next operator at the wrong repository.
WORLD — the defect is vacuity in the marker lists, and it is worse than expected
I was briefed that the classifier was "proved only against a dead link, never the degraded one." That is partly stale and this PR does not repeat it —
test_e2e_runner_install_resilience.pyalready proved DNS failure, the read-timeout signature of the 2026-07-27 incident itself, connection-refused, four artifact shapes, and a mixed corrupt-wheel-on-a-dead-link rod.Measured properly, the real hole is worse:
transport_markersartifact_markersZero of seventeen transport alternatives were individually proved. Each of the three network fixtures matched two or three alternatives at once, so deleting any single transport alternative changed no test result.
LOG_ARTIFACT_BUILD_CRASHlikewise carries both build markers, so neither is proved.A pattern list nobody proved matches is a gate selecting by a value it never grades. A typo, a case change, or an upstream pip rewording in any transport alternative silently reclassifies a dead link as a broken wheel — the exact failure this function was written to prevent.
What this adds
Every alternative in both lists now has captured pip output that matches it and nothing else, so deleting that alternative flips a real verdict. The degraded shapes the incident class is actually about had no coverage at all and are covered now:
IncompleteReadChunkedEncodingErrorRemoteDisconnectedmid-downloadConnection abortedConnection reset by peerConnectTimeoutErrorMaxRetryErrorSSLErrorCould not fetch URLgaierror -2)Name or service not knownNetwork is unreachableEvery artifact alternative is graded THROUGH a degrading link, because an artifact-only log classifies as
artifactvia the default branch and therefore proves nothing about the ordering rule. Four mixed shapes are named, including one where the unpack failure prints before the transport noise, so the rule cannot be passing by reading position.The part that keeps it true — the non-vacuity test
It parses both lists out of the shipped runner using the existing extractor, and:
local transport_markers=''raises instead of yielding();artifact);unprovedandorphanedon failure;Three transport alternatives cannot be proved alone because real pip never prints them without a partner (
ReadTimeoutError⇄Read timed out,NewConnectionError⇄Failed to establish a new connection). They are declared subsumed and proved as pairs — drop one, stillnetwork; drop both,artifact— and the declaration is self-guarding: over-declaring any alternative fails its own drop-one assertion.FAILURE — three control rods, run by hand against real bash
Rod A — a marker added to the runner with no fixture:
Rod B — a ONE-LETTER typo in a transport marker (
IncompleteRead→IncompleteReed). A truncated transfer now blames the wheel, and the suite says so:Rod C — empty the transport list. It must RAISE, never pass vacuously:
The runner was restored after each rod (
git diffclean).81 tests pass, including the two protected halves of the existing module, which were left byte-identical.
The gate at harvest
LawGiver pre-gate:
files_checked=3 added_lines_checked=751,gauges unrun=(none), exit 0.Two new files because one measured 650 against a 500-line cap. Split by responsibility: the captured corpus (data, no assertions) and the contract over it.
tests/scriptshas no package total infile-budget.json, so neither adds a draw, and no number was edited.e2e-runner.shande2e-box.share untouched.A doc gap found and closed
Four reason codes the runner emits were taught by no playbook:
artifact_manifest_missingandartifact_wheel_not_mounted(inrelease-gates.mdbut not in the playbook an operator actually opens) andtrap:sigint/trap:sigterm(in neither).docs/box-operator.mdnow carries three one-sentence rows — the trap row states plainly that a killed run says nothing about the artifact — and a test binds all 19 emitted codes to the playbook, with a non-vacuity floor.🔴 What this does NOT do, and why
It does not get the box to a real PASS, and it does not try. Measured on this machine:
dockerpresent (29.6.1), the private fixture checked out — but no.env, noANTHROPIC_API_KEY, and.e2e-runs/has never existed. A real run drivesbonfire runplus a claude-cli observer session against a live key: it spends the operator's money and copies their OAuth credential into a run directory. That is not mine to authorise. Every test here is offline and deterministic; nothing added can trigger a box run.So everything downstream of classification remains unproven by this change: that
install_step's exit 11 reaches the driver's verdict readout, thatemit_failure_verdictwritesbox_network_unreachable:<step>into a realverdict.json, and that the new playbook rows match what a real killed or unmounted run produces. These tests stub the verdict emitter, exactly as the existing module does.Findings for a maintainer
ReadTimeoutErrorandNewConnectionErrorcannot be printed by real pip without their partners, so two of seventeen alternatives are unreachable as a sole cause. If the list is ever shortened, those are the only safe removals, andtest_a_subsumed_transport_alternative_is_really_subsumedis the proof.artifactfall-through, and the documented honest limit (unreachable index + unresolvable dependency ⇒network) all behave exactly as the comment claims.file-budget.jsonself-reports that its gate walks.pyfiles only, so the two.shentries fore2e-runner.sh(declared debt at 968 against a baseline of 779) ande2e-box.share documented but unenforced. A shrink-only ratchet nobody measures is the same class of defect as a marker nobody proved.Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com