Skip to content

Read the walk's own infra fault as data, and drop a matcher arm nothing produces - #7482

Merged
briansrls merged 3 commits into
mainfrom
session/quiet-ferret-16-infra-typed
Jul 31, 2026
Merged

briansrls merged 3 commits into
mainfrom
session/quiet-ferret-16-infra-typed

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Jul 30, 2026 •

Copy link
Copy Markdown
Contributor

Sibling of #7476, found by searching for the same shape elsewhere: a typed fact formatted into prose, then recovered by grepping that prose.

The round-trip

handle.join() returning Err(_) means a claim thread panicked — the walk knows this, as a bool. That bool became format!("batch=N infra=thread_panic"), and falsifier_failure_mode recovered the classification with d.contains("infra=").

The panic payload is genuinely lost (Err(_) discards it). But that a thread panicked is not, so it now travels as InfraFault::ClaimThreadPanicked { batch_index }, and falsifier_failure_mode_with_faults consults it before any text path runs. The rendered line goes back to being for humans.

A deletion I made and then retracted

An earlier revision deleted the d.contains("failed to spawn") arm, on the grounds that no producer reachable from this input emits it. That was wrong, twice over, and the arm is restored.

The evidence was truncated. My grep for producers ended in head -5, and I read five results as the whole population. There are 24, one of them inside claim_executor.rs itself ("[floor-memory] heartbeat thread failed to spawn: {e}").

And the reasoning was wrong independently of the evidence: gunbc.ci_failure_class declares ProcessSpawnFailure a live signature whose match text is spawn_outcome_log_fragment(SpawnFailed) = "failed to spawn", cited to extdeps.rust.std_process. Editing one side of a fork on surface-local evidence widens the divergence rather than closing it.

The fork this surfaced — the larger finding

gunbc.ci_failure_class already models this properly. InfraSignature is a closed sum whose match text is derived from cited upstream authorities — errno_strerror(EAGAIN), spawn_outcome_log_fragment(SpawnFailed), the sccache fragments, runner_lifecycle_log_fragment(ShutdownReceived) — each carrying an infra_signature_origin naming where the text comes from and an infra_signature_site saying whether it is build-log or job-signal text.

The seed's falsifier_failure_mode is a hand-typed fork of it, and the fork is the one that runs: classify_failure_reason has no production consumer — only witness tests reach it. The grounded authority is inert while the ungrounded copy is live, which is exactly the coverage-by-illusion tier DESIGN §6 names.

This PR does not close that fork — it records it, because closing it is a different change (making the seed resolve and call gunbc.ci_failure_class, the way claim_executor already resolves gunbc.floor_component_receipt).

Also fixes a live main red

Unrelated to the above, but caught by it. cargo test --bin claim_executor does not compile on clean main.

#7470 added the finalization_record test helper with a ClaimResult literal; #7476 added the required budget_refusal field. Both merged, git saw no textual conflict, and CI runs no cargo test — so nothing caught it. Verified by stashing this branch's diff and building unmodified origin/main: E0063 at claim_executor.rs:4526. My field made it required, so the one-line fix rides here.

Worth noting the gap beyond the fix: two crates of Rust tests are unguarded by CI, so a compile break can sit on main indefinitely. That is the same gap review 45231 caught by hand last round.

Verified by execution — both crates this time

The omission that let review 45231 find a compile break last round was building the bins and treating that as coverage. Both are checked here:

  • claim_executor bin suite: 40 passed, 0 failed
  • cargo build --tests -p v1-compiler-tests: Finished

falsifier_failure_mode_classifies_three_arms now asserts both directions, so the move from text to value is proven rather than assumed:

assertion expects
the panic text alone WitnessRed — the rendered line must not carry the classification
an observed fault, text that hints at nothing Infra — the value settles it
the panic text with no fault WitnessRed — prose alone never promotes to Infra

Proven discriminating: with the typed arm neutered the test FAILS; restored, it passes.

Pure Bootstrap receipt (review 45261)

ci_failure_class_seed_fork_note on the authority whose fork this is:

  • Added: an InfraFault sum recording a fault the walk observes (a claim thread panic, from handle.join() returning Err) plus the field carrying it — replacing a format!-then-contains round-trip through the walk's own rendered line. That fault is the walk's own observation, not a signature this module models, so it is not a second fork of the roster.
  • Not added: any new substring authority. The retracted deletion is recorded there too.
  • Deferred to: ZeroHandMaintainedRust, roadmap node v1-zero-hand-maintained-rust (gunbc.v1_deletion_plan v1_exit_finish_lines).
  • Concrete dissolution — the fork closure, not a generic seed deletion: falsifier_failure_mode consumes this module and calls classify_failure_reason, at which point the hand-typed list is deleted, classify_failure_reason gains its first production consumer, and the build-log/job-signal site axis becomes decidable at the call site instead of being flattened away.

Honest residual, verified not a regression

batch_failure_mode_and_detail (the per-batch component receipt) does not see infra_faults — flagged in review 45266. Checked against origin/main: the panic has always pushed to walk-level failure_details, never to rec.results, so that path was blind to it before this change and is no worse after. Recorded rather than silently left; wiring it is a separate change now that InfraFault carries batch_index.

Verification after the restore

  • claim_executor bin suite: 40 passed, 0 failed
  • cargo build --tests -p v1-compiler-tests: Finished
  • ci_failure_class witnesses: all 5 PASS by execution

Brian Searls and others added 2 commits July 30, 2026 22:58
…ng produces

Sibling of #7476, found by looking for the same shape elsewhere: a typed fact
formatted into prose and then recovered by grepping that prose.

THE ROUND-TRIP. `handle.join()` returning `Err(_)` means a claim thread panicked
— the walk KNOWS this. That bool became `format!("batch=N infra=thread_panic")`,
and `falsifier_failure_mode` recovered it with `d.contains("infra=")`. The panic
PAYLOAD is genuinely lost (`Err(_)` discards it), but *that a thread panicked* is
not, so it now travels as `InfraFault::ClaimThreadPanicked { batch_index }` and
`falsifier_failure_mode_with_faults` consults it before any text path. The
rendered line goes back to being for humans.

A MATCHER ARM THAT COULD NEVER FIRE. `d.contains("failed to spawn")` is deleted:
no producer reachable from this input emits it. The interpreter's spawn failure
says "failed to execute '{argv0}': {e}"; the in-tree producers of "failed to
spawn" are a different bin, test helpers, and panic messages — and a panic
payload is discarded before it could become a detail. A substring its own input
cannot contain only looks like coverage.

KEPT AS TEXT, DELIBERATELY. "Resource temporarily unavailable" and "sccache" are
genuinely EXTERNAL text arriving as an io::Error Display through
`failed to execute '{argv0}': {e}` (EAGAIN renders as the former). Matching them
here is not principled, and the comment says so: typing them belongs at the
interpreter boundary where the io::Error is caught. Not silently left as if it
were the same kind of thing as the fact above.

ALSO FIXES A LIVE MAIN RED, unrelated to the above but caught by it.
`cargo test --bin claim_executor` does not compile on clean main: #7470 added the
`finalization_record` helper with a `ClaimResult` literal while #7476 added the
required `budget_refusal` field. Both merged, git saw no textual conflict, and CI
runs no cargo test, so nothing caught it. Verified by stashing this branch's diff
and building unmodified origin/main (E0063 at claim_executor.rs:4526). My field
made it required, so the one-line fix rides here.

VERIFIED BY EXECUTION, both crates this time — the omission that let review 45231
find a compile break last round:
  - claim_executor bin suite: 40 passed, 0 failed.
  - `cargo build --tests -p v1-compiler-tests`: Finished.
  - `falsifier_failure_mode_classifies_three_arms` now asserts BOTH directions, so
    the move from text to value is proven, not assumed: the panic text ALONE
    classifies WitnessRed, an observed fault classifies Infra even when no text
    hints at it, and no fault means no Infra whatever the prose says.
  - Proven discriminating: with the typed arm neutered the test FAILS; restored it
    passes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

review 45261 — receipt added, and verifying it surfaced something bigger plus a mistake of mine that I've retracted.

The receipt

ci_failure_class_seed_fork_note, placed on gunbc.ci_failure_class — the authority whose fork this is, rather than on an unrelated module. It names what the seed adds (an InfraFault sum for a fault the walk observes, replacing a format!-then-contains round-trip), defers to ZeroHandMaintainedRust / roadmap node v1-zero-hand-maintained-rust, and gives a dissolution trigger that is the fork closure rather than a generic seed deletion.

What verifying it surfaced

gunbc.ci_failure_class already models this concept properly. InfraSignature is a closed sum whose match text is derived from cited upstream authorities — errno_strerror(EAGAIN), spawn_outcome_log_fragment(SpawnFailed), the sccache fragments, runner_lifecycle_log_fragment(ShutdownReceived) — each with an infra_signature_origin naming the source and an infra_signature_site distinguishing build-log from job-signal text.

The seed's falsifier_failure_mode is a hand-typed fork of it. And the fork is the one that runs: classify_failure_reason has no production consumer — only witness tests reach it. The grounded authority is inert while the ungrounded copy is live, which is the coverage-by-illusion tier DESIGN §6 names.

A deletion I made and retracted

This PR originally deleted the "failed to spawn" matcher arm as unreachable. Wrong twice over.

The evidence was truncated: my grep for producers ended in head -5 and I read five results as the population. There are 24 — one inside claim_executor.rs itself ("[floor-memory] heartbeat thread failed to spawn: {e}"). I've made that same mistake three times today in different forms, so it is a habit and not a slip.

The reasoning was also wrong independently: the model declares ProcessSpawnFailure a live signature whose text is exactly "failed to spawn", cited to extdeps.rust.std_process. Editing one side of a fork on surface-local evidence widens divergence rather than closing it. Arm restored; the retraction is recorded in the note so it isn't re-attempted.

The InfraFault half stands — a thread panic is the walk's own observation, not a signature this module rosters, so typing it is not a second fork.

Residual, checked rather than assumed

review 45266 noted batch_failure_mode_and_detail doesn't see infra_faults. Verified against origin/main: the panic has always pushed to walk-level failure_details, never to rec.results, so that path was blind before this change and is no worse after — pre-existing, not a regression. Recorded rather than quietly left; wiring it is a separate change now that InfraFault carries batch_index.

Verification after the restore: claim_executor suite 40 passed, 0 failed; cargo build --tests -p v1-compiler-tests Finished (both crates this time); ci_failure_class witnesses all 5 PASS by execution.

— sent from quiet-ferret-16

@briansrls
briansrls merged commit 38625e8 into main Jul 31, 2026
5 checks passed
@briansrls
briansrls deleted the session/quiet-ferret-16-infra-typed branch July 31, 2026 03:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant