Skip to content

Falsifier alert reports per-component state instead of one hardcoded story - #7467

Merged
briansrls merged 5 commits into
mainfrom
session/quiet-ferret-16
Jul 30, 2026
Merged

briansrls merged 5 commits into
mainfrom
session/quiet-ferret-16

Conversation

@briansrls

@briansrls briansrls commented Jul 30, 2026 •

Copy link
Copy Markdown
Contributor

The defect, priced

falsifier-alert.yml read only run.conclusion and then hardcoded one causal story for every failure (old lines 36, 53-57):

falsifier is RED — affected-set cold control is dark … per-PR affected-set selection runs UNVERIFIED by its cold control, the Gate-1 emit receipts … do not execute anywhere, and the known-red probe un-quarantine accounting is dark.

On run 30509024051 all three clauses were false. Batch 1, the predict-only affected-set cold control, concluded Done over 5,217 witnesses; batches 2–3 produced their expect_red still-red OK receipts; batches 5–8 passed. Exactly one component failed: the silent-pick gate, killed at its whole-receipt wall budget (900001ms > 900000ms).

An overall-red composite that erases the green state of its completed children is a state-space conflation (DESIGN §5), and it misdirected triage every time it fired. It also had no data to do better: the falsifier job had no upload-artifact step at all, so every receipt written to target/ died on the runner, and the failure classification existed only as prose eprintln!.

What landed

  • dag/gunbc/floor_component_receipt.dag — per-component receipt as a projection of std.observation.ObservationEvent, the record gunbc.witness_row_cost already names as THE record ("not a TSV schema"). A bespoke status schema would have been a second representation of it (§3). Refused stays distinct from Failed; a skipped batch is Skipped { reason }, never an absent row.
  • Components are keyed by structural role, not batch index. gunbc_falsifier_batches composes conditionally on enrollment flags, so a flag flip shifts every later index — which is why the silent-pick gate reports as batch 4 while sitting fifth in source order. The cold control is identified by the property that defines it: node_frontier_selection = SelectionPredictOnly, reusing the std.realization_schedule authority. Zero matches → ControlAbsent; two or more → ControlAmbiguous. Never a guess.
  • claim_executor writes target/floor-component-receipt.json on every exit path including red — the run where it matters most. A row that cannot be constructed is a typed refusal that fails the walk, never a component silently dropped.
  • falsifier_workflow.dag gains the upload step with if: always(), plus falsifier.yml regenerated in this PR (it is drift-gated, so a direct .yml edit would red the gate). The +10 transfer term joins gunbc_falsifier_job_backstop_timeout_minutes (305 → 315) and the witness asserting the exact step-sum moved with it.
  • falsifier-alert.yml downloads that artifact and reports real state. A missing or unparseable receipt is an explicit unknown that makes no claim about any component — it never re-widens into the old story.

Proven by execution

dag/test/claim/floor_component_receipt_witness_test.dag — 7 witnesses green, and the REDs discriminate in both directions (each perturbation run, then reverted):

perturbation result
Done => false (reproduces "always dark") fcr_real_run_reports_control_verified_and_names_silent_pick FAILS
Failed => true (reproduces "always green") fcr_red_control_control_itself_failed_is_not_verified FAILS
absent control claims verified: true fcr_red_control_absent_control_is_not_silently_verified FAILS

End-to-end, not just unit: claim_executor was run against gunbc_ci_regen_floor_batches, which went genuinely red, and wrote a receipt naming the failed component, reporting the cold control as absent (that plan has no predict-only batch — true), and recording the unreached batch as skipped. Those real bytes were then fed through the actual alert JS, which rendered the honest report. The JS has no .dag witness available, so it was executed directly against both the real receipt and a missing-receipt case.

Deliberately not in scope, with triggers

  • TimedOut is modelled and projected but not yet emitted. InterpError::WitnessWallBudgetExceeded { elapsed_ms, budget_ms } carries the numbers structurally, but ClaimOutcome::RuntimeError flattens them to a String before the walk sees them. The floor emits Refused with the interpreter's own located diagnostic — correct on observation_refused_distinct_note's own terms for a deliberate stop at a declared ceiling. Fabricating 0/0 to reach the more specific arm would be the fabricated output §5 forbids. Dissolve-on is declared in-carrier; the projection side already handles the arm, proven today.
  • No re-basis of the 900s ceiling. The budget note requires an appended dated re-basis, and the measurement is censored (killed at deadline), so the true cost is unknown — only that it exceeded 900s.

Findings from the investigation, not fixed here

  1. The silent-pick witness's 900s is largely a duplicated whole-tree compile. It shells out to resolution_divergence_census --closure-scoped, a separate process that re-resolves ~1309 modules from cold — the same corpus batch 1 resolved in the same job (resolve_ms = 1,119,333). The subprocess shares none of the parent's 4.68M memo hits. Two cost-shape defects sit in the census walk itself: a per-module deep clone of SymbolIndex (cli_run.rs:23996) and import_chain_owner computed twice per site (:24009, :24038) across ~40.6k sites.
  2. The witness-cost drift detector is vacuous. dag/gunbc/witness_row_cost_basis.tsv is a header plus two comments — zero data rows — so all 5,237 rows record BasisAbsent and drift_exceeded is pinned at 0. Because the file exists, the loud "basis file missing" diagnostic never fires either. This is the mechanism that would have warned as the row climbed 717s → 815s → 900s.
  3. source_root_ingest_gate_passes returned Bool(false) on the 07-28/07-29 falsifier reds — a genuine witness failure, unrelated to hosts, and a different cause from the budget graze.

🤖 Generated with Claude Code

@gunbai-bot gunbai-bot Bot changed the title affected set is red again Falsifier alert reports per-component state instead of one hardcoded story Jul 30, 2026
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review July 30, 2026 08:37
… Pure Bootstrap deferral

- floor_component_outcome_of_failure_mode maps the seed's failure-mode
  vocabulary to ObservationOutcome in .dag under a witness, and REFUSES an
  unmodelled mode. This replaces a `_ => "failed"` catch-all in the seed that
  would have absorbed a newly added mode silently (DESIGN §5).
- Pure Bootstrap receipt for the seed transport: no new Rust file, no
  classification left in Rust; deferred to the ZeroHandMaintainedRust finish
  line (roadmap node v1-zero-hand-maintained-rust) with a concrete dissolution
  (Filesystem.Write via host_effect_apply).
- Note why floor_component_row_is_done stays local: std.observation's own
  canonical surfaces are themselves total matches, and !is_anomaly would report
  a Skipped batch as successful.
- 2 new witnesses incl. the unmodelled-mode refusal RED control (9 total, green).

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

Thanks — review 45058. I verified all 7 findings against the tree. Two were real and are fixed in 18adcbd; five rest on a misreading of the seed-transport boundary, and I'm declining those with the in-tree precedent.

Fixed

Finding 7 (hand-Rust receipt) — valid, and verifying it found a defect of my own.

You're right that new hand-Rust owes a named deferral rather than a description, and there's an in-tree pattern for it (emit_on_demand_host_seed_deferral_note). Added floor_component_receipt_seed_transport_deferral_note, deferring to the ZeroHandMaintainedRust finish line, roadmap node v1-zero-hand-maintained-rust (gunbc.v1_deletion_plan v1_exit_finish_lines), with a concrete dissolution: the transport deletes when the receipt write is issued from .dag as a typed Filesystem.Write through host_effect_apply (shell→intent Phase 2 routing) instead of std::fs::write in the seed.

Chasing your "does transport actually justify this?" question surfaced a genuine §5 defect I'd introduced: the seed held the mode→outcome mapping with a _ => "failed" catch-all, which would have absorbed a newly added falsifier_failure_mode into failed with no diagnostic. That classification now lives in .dag as floor_component_outcome_of_failure_mode, under a witness, and refuses an unmodelled mode — the row cannot be built and the walk fails closed naming the mode. New RED control fcr_red_control_unmodelled_failure_mode_refuses_never_widens proves it (unknown mode → absent; BudgetExceeded → present). The seed now carries zero classification: it extracts the mode string and marshals. That's a real improvement your finding produced, so thank you.

Finding 6 (is_done re-matches the coproduct) — premise doesn't hold, but the locality now carries its reasoning.

I checked for the canonical fold/query surface. std.observation exposes observation_outcome_class and observation_outcome_is_anomaly, and both are themselves total hand-written matches over ObservationOutcome — there is no fold or query surface to consume, so sibling-style matching is the canonical shape at the authority.

It's also not a fork of is_anomaly, which answers a different question and disagrees on two arms:

outcome is_anomaly is_done
Skipped false false
Final false shown_failures == 0

So !observation_outcome_is_anomaly would report a skipped batch as successful — precisely the conflation this receipt exists to prevent. Routing through observation_outcome_class would trade 6 arms for 10 and still lose the Final reading. Kept local under second-consumer discipline (§6, model just-in-time — one consumer today), now with floor_component_is_done_locality_note recording that analysis and the dissolve-on (lift to std.observation beside is_anomaly on a second consumer). I did not add it to std/observation.dag unprompted: that's P0 of an operator-signed lane and my brief sets a higher bar there.

Declined, with the precedent

Findings 1–5 (budget_ms/elapsed_ms/wall_ms as Nat) — these are seed-transport parameters, not stored magnitudes.

The unit-modelling rule bites when a magnitude is modelled as a bare scalar. Nothing here stores one:

  • TimedOut { budget: Millisecond, elapsed: Millisecond } — the std.measure carrier
  • ObservationEvent.wall: Measured<Nanosecond> — the carrier
  • every parameter is grounded on the first line it's used: millisecond(count: budget_ms), millisecond_to_nanosecond(m: millisecond(count: wall_ms))

Those _ms: Nat parameters exist only because Rust hands primitives across the interpreter boundary. The exact precedent is the sibling seam this module was modelled on — gunbc.observation_seed_render, called from the same bin (render_phase_concluded_line):

fn phase_concluded_line(phase: NonEmptyStr, elapsed_ms: Nat, overhead_ms: Nat, emoji: Bool) -> String {
  ... wall: MeasuredValue { value: millisecond_to_nanosecond(m: millisecond(count: elapsed_ms)) }

seed_heartbeat_line is the same (elapsed_ms: Nat, rss_bytes: Nat, …). That module's header states the contract explicitly: "primitive arguments in, a rendered line out." Note the deliberate contrast in the same file — scoped_run_*_measured takes wall: Nanosecond, a carrier, because those callers already hold one.

Taking Millisecond in these signatures would require the seed to construct Value::Record { type_name: "Millisecond", … } by hand, i.e. moving carrier construction into Rust and forking the constructor — worse on §3 and on the very hand-Rust discipline finding 7 raises. So this stays, matching the established boundary.

If you'd rather the boundary itself changed, that's a change to observation_seed_render's contract affecting every seed progress line, and belongs in its own PR against that lane — not smuggled in here.

State

9 witnesses green by execution, incl. 4 discriminating REDs; end-to-end re-verified after the refactor (claim_executor → real receipt → alert JS, on a genuinely red plan). cargo fmt clean, test build clean.

Two things flagged in the PR body that this PR does not fix, so they aren't missed: the 900s silent-pick row is largely a duplicated whole-tree resolve in a subprocess, and witness_row_cost_basis.tsv has zero data rows so the drift detector can never fire.

— sent from quiet-ferret-16

@cursor

cursor Bot commented Jul 30, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

… boundary

Reverses my earlier decline. Three reviews (45058, 45070, 45074) independently
flagged the seven *_ms: Nat constructor parameters, and they are right: a
duration whose unit lives only in the field name is form 3 of the standing
unit-modeling merge-hold. The sibling seam I cited as precedent
(observation_seed_render.phase_concluded_line) is itself un-migrated debt, not
a licence — citing debt as sanction is the cementing the brief warns against.

- Every duration on the public surface is now Millisecond (= Measure<Time,
  Milli, Nat>, the ratified Measure<Q,S,M> shape). Immediate millisecond(count:)
  wrapping inside a body does not discharge it: the parameter surface is what a
  caller can get wrong, and passing seconds into wall_ms would have typechecked.
- The seed constructs NO carrier: it calls millisecond(count:) across the
  interpreter boundary and passes the Millisecond back, so the constructor stays
  the single authority (a Value::Record built in Rust would have forked it).
- Collapsed to ONE seed entry point: floor_component_row_of_failure_mode, whose
  mode vocabulary now covers every disposition the walk reports including
  not_reached (Skipped). The generalised two-constructor marshaller is deleted.
- 10 witnesses green incl. not_reached -> skipped and the unmodelled-mode
  refusal; end-to-end re-verified through claim_executor on a red plan.

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

review 45074 — fixed in f4e0646, and I was wrong to decline this earlier. Recording the reversal properly since I argued the other way in my previous comment.

I was wrong, and why

I declined findings 1–5 of review 45058 on the grounds that _ms: Nat is the established seed-transport shape, citing gunbc.observation_seed_render:

fn phase_concluded_line(phase: NonEmptyStr, elapsed_ms: Nat, overhead_ms: Nat, emoji: Bool) -> String

That citation is factually true and argumentatively worthless. An existing instance is not a sanction — that seam is un-migrated debt on its own lane, and invoking debt as precedent is exactly the cementing this repo's brief warns against. review 45070 then made the point that broke my argument: "Immediate millisecond(count: …) wrapping does not discharge it without a typed parameter surface." That's correct. The parameter surface is what a caller can get wrong — a caller passing seconds into wall_ms would have typechecked cleanly. Wrapping in the body protects the body, not the API.

Three independent reviews converging (review 45058, review 45070, review 45074) against one precedent argument of mine should have moved me at the second, not the third.

The fix — the typed surface, not the 🟡 gate

Both remedies were offered; I took the real one rather than the marker. All seven parameters are now the std.measure carrier:

line before after
113, 114 budget_ms: Nat, elapsed_ms: Nat budget: Millisecond, elapsed: Millisecond
182 wall_ms: Nat wall: Millisecond
204, 205, 207 budget_ms/elapsed_ms/wall_ms: Nat Millisecond
243 wall_ms: Nat wall: Millisecond

Millisecond = Measure<Time, Milli, Nat> — the ratified Measure<Q,S,M> shape, consumed not forked. grep -nE "(budget_ms|elapsed_ms|wall_ms): Nat" over the module now returns nothing.

The seed constructs no carrier. It calls millisecond(count:) across the interpreter boundary and passes the resulting Millisecond back in, so the constructor remains the single authority. Building Value::Record { type_name: "Millisecond", … } in Rust — the other way to get a typed signature — would have forked the constructor and hardcoded the carrier's internal shape in the seed, trading a unit violation for a §3 one.

A simplification that fell out

Typing the surface let the seed collapse to one .dag entry point. floor_component_outcome_of_failure_mode gained not_reached → Skipped, so its mode vocabulary now covers every disposition the walk can report, and the generalised two-constructor marshaller I'd added is deleted. Fewer hand-Rust lines, one seam instead of two — which also improves the finding-7 posture from review 45058.

Verification

10 witnesses green by execution (up from 9), including two new ones: fcr_not_reached_mode_is_skipped_not_failed (a skipped batch must not read as failed) and fcr_red_control_unmodelled_failure_mode_refuses_never_widens (unknown mode → refuses; BudgetExceeded → present). End-to-end re-verified after the rewrite: claim_executor against a genuinely-red plan → real receipt → correct failed and skipped rows. cargo fmt clean, test build clean.

One note on review timing

review 45074 ran against the committed state of 5c7ff6fc5 while this fix was still in my working tree, so it flagged code that was already being replaced — no fault of the review, just worth noting so the line numbers aren't re-litigated. f4e0646 is the SHA to look at.

Still open and unfixed here, flagged in the PR body so they aren't lost: the 900s silent-pick row is largely a duplicated whole-tree resolve in a subprocess, and witness_row_cost_basis.tsv has zero data rows so the cost-drift detector can never fire.

— sent from quiet-ferret-16

@briansrls
briansrls merged commit a4604db into main Jul 30, 2026
5 checks passed
@briansrls
briansrls deleted the session/quiet-ferret-16 branch July 30, 2026 17:05
briansrls pushed a commit that referenced this pull request Jul 30, 2026
…e stages at arm time

Step 0 of the review disposition, plus the two findings fixable without the
run_stage extraction. The remaining findings are named, not silently
carried.

REBASE, and the conflict was load-bearing exactly as predicted. #7467 added
floor_component_receipt_ok to the walk verdict; this branch had replaced
that composition with ordinary_failed || on_success_failed. Resolved by
folding the component receipt INTO ordinary_failed, so a component-receipt
construction or write failure is an ordinary-floor failure that blocks
every success stage — dropping it would have reopened the very ordering
defect this branch exists to close. The test fixture also gained #7467's
new BatchRecord label/selection_tag fields.

THE CARRIER NOW DESCRIBES THE EXECUTOR IT HAS, not the one it wants. The
note claimed members within a stage run concurrently and that each stage
writes its receipt before the next begins; neither is true today — members
run serially and one aggregate receipt is written after the whole
sequence. A carrier promising a guarantee its executor does not provide is
the defect this type exists to end, and I had reintroduced it. The note
now states the barrier that IS real (stage N completes before N+1; a
failed stage prevents every later one) and names three gaps: serial
members, stages bypassing the ordinary unit-lane partition and therefore
governor admission and clamps, and the aggregate receipt. The repair —
extracting the ordinary batch machinery into a reusable run_stage so both
populations share one executor — is named on the carrier as the next step.

ARM-TIME STAGE VALIDATION. Success-stage admissibility is checked
immediately after the plan parses, BEFORE the governor arms and before any
ordinary batch runs: a plan-shape error is knowable at parse time, and
discovering it after a 20-30 minute floor spends the whole walk to report
something the parse already had. Refuses discovery runnables (no defined
green-only meaning), empty entry/function, and heavy-whole-tree-resolve
claims (which would bypass governor admission through the weaker route).

ONE HONEST NARROWING: I first wrote the validator against
profile.spawns_host_compiler and profile.memory — fields the Rust Runnable
does not carry. Only use_walk_memo (the parsed form of
heavy_whole_tree_resolve) and execution_mode survive parsing, so the
validator walls the heavy-resolve case and says so; walling the other two
requires retaining them on Runnable, which lands with the run_stage
extraction. The wall is narrower than intended and the code says which
part is missing rather than implying full coverage.

VERIFIED: cargo test 37/37 (including both floor-finalization arms against
the rebased BatchRecord); the WalkPlan parser RED still refuses a bare-list
plan post-rebase; generated artifacts regenerate clean; fmt clean.

STILL OWED, from the review and unstarted: run_stage extraction with real
intra-stage concurrency and per-stage receipts; finalization policy carried
by WalkPlan rather than selected by plan-function name; schedule-lens
projections that see the stage population; the discriminating executor
control set; then the admission occupants and the task #12 deletion.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N7LfCpidMuDjV3FxYUHv1K
gunbai-bot Bot pushed a commit that referenced this pull request Sep 1, 2026
…itations found BOTH were false

XL-N caught two defects in the row. Both are fixed, and the second one turned
the row's own content inside out in a way worth recording.

DEFECT 1, THE REMEDY WAS ONE ARM AND NEEDED THREE. "Past tense with the date,
never deletion" is correct only for a claim that WAS true and whose executor
died. Past-tensing a never-true claim manufactures a false historical statement
— "X USED TO resolve Y" asserts an execution that also never happened. And my
own item 1 shows a third case: the instrument_sandbox live half DOES execute,
via a local recipe, and OfflineLocalRecipe HAS a route — so the sentence names
the WRONG AUTHORITY for a live relation, and past-tensing it would record a live
relation as dead. That is a new contamination in the opposite direction,
produced by the remedy itself, which is exactly what this row exists to name.
A remedy mechanical enough to apply without reading WILL be applied without
reading. The row now carries one remedy arm per origin, and the
"never deletion" absolute is softened to a default: a sentence whose entire
content is a false execution claim has no reasoning to preserve.

DEFECT 2, AND IT IS THE MORE USEFUL ONE. XL-N asked me to verify the two
cli_run.rs notes rather than inherit them, on the grounds that a row about
unbacked claims should not itself contain one. It did contain two — and
verifying killed BOTH of my origin-B citations:

- floor_component_resource_checkpoint_note and
  floor_component_phase_journal_scaffold_note were REAL `data …: String`
  declarations in gunbc.floor_component_receipt. They were removed on
  2026-08-30 by the prose-bankruptcy sweep #9752, which converted module-scope
  commentary rows into §4c annotations corpus-wide.
- claim_executor DID resolve gunbc.floor_component_receipt:
  write_floor_component_receipt_at joined gunbc/floor_component_receipt.dag
  directly, from #7467 (2026-07-30) until #9228 deleted it (2026-08-25).

So ORIGIN B — never backed at all — HAS ZERO VERIFIED INSTANCES here. It is
recorded as conceivable and unmeasured, with its remedy arm, rather than as a
population. I had asserted a two-origin class on the strength of two claims I
had not checked.

WHAT THE VERIFICATION FOUND INSTEAD is a third real origin with a corpus-wide
producer: THE CITED SYMBOL DIED WHILE ITS CONTENT SURVIVED AS AN ANNOTATION.
§4c makes an annotation uncitable by construction — no Accepted program can
read one — so every citation of a row #9752 converted was dangling the moment
that sweep landed. The population is that sweep's diff, not anything about this
module. Its remedy is its own arm: name the module and the FACT, since there is
no symbol left to cite; past-tensing would report the content as gone when only
its citability is.

RECOGNITION RULE EARNED, and it is now in the row: "resolves nowhere NOW" is
not "never resolved". The distinction is decided by history, not by the working
tree, and the instrument is `git log --all -S` over the DECLARATION FORM —
which also separates the two attested origins by showing WHAT deleted the
referent. Nothing but a reviewer asking for verification caught this.

CORRECTIONS TO WHAT I ALREADY LANDED, applying the arms to my own diff:
- ci_failure_class: my first pass DELETED the claim_executor comparison as
  false. It was true. Restored in the past tense with both dates, as the worked
  precedent it still is — remedy arm 1, not arm 4.
- cli_run.rs, both sites: my first pass said the two notes "resolved in neither
  the receipt module nor anywhere else". False. Now records that #9752 made them
  uncitable and the pair was deleted after — remedy arm 2.

docs/design-ledgers.md reprojected.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Li6e7cEDFodeBV7uPi3yTz
gunbai-bot Bot added a commit that referenced this pull request Sep 1, 2026
…model with no producer, reciting a deleted transport in the present tense (#9858)

* XL-0-RECEIPT: delete the floor component receipt pair — a well-built model with no producer, reciting a deleted transport in the present tense

gunbc.floor_component_receipt and gunbc.floor_component_receipt_document
describe, in the present tense, an alert that downloads an artifact named
floor-component-receipt from a run id it is given and reads four named fields.
That alert was falsifier-alert.yml, deleted on 2026-08-15 in the CI cut. A
later lane read the module, believed the transport live, planned against it,
and was corrected by its reviewing authority. That is premise contamination —
the class the CI rung drop names in its own words — appearing in a module
rather than in the canonical authority.

CENSUS (reproduced on main 37e705c, not inherited), per medium, because a
survivor stops being reached silently and a reach measurement over one medium
reads exactly like a reach measurement:

- PRODUCER: none. Nothing in src/ or dag/ writes target/floor-component-receipt.json;
  no Rust carries the schema string floor-component-receipt/v1 or its members.
- CONSUMER, workflow argv: witnesses.yml uploads exactly four artifacts —
  required-floor-disposition, expected-red-roster-join, long-home-storage-agreement,
  required-floor-claim-cost. The receipt is not among them, and only
  witnesses.yml / fleet-converge.yml / fleet-desired.yml remain.
- CONSUMER, import graph: the only importer of either module is their own
  witness test, which is a PEER of the subject, not a guard over a survivor.
- CONSUMER, exported symbols: FloorComponentReceipt, FloorComponentReceiptDocument,
  FloorComponentReceiptSubject, ComponentAlertSummary and the schema/path/artifact-name
  rows resolve nowhere outside the pair. FloorComponentFailureMode and
  ComponentOutcomeRead appear only in two gunbc.non_fold_residue prose rows.
- CONSUMER, Cargo [[bin]]: none. Rust: one string literal used as a test label
  in cli_run.rs, not a call.

WHY THIS IS NOT A QUIET GUARD. Three questions decide: mechanism existence,
join reachability, current occupancy. Yes/yes/zero is a healthy guard being
quiet. Here the answer is NO at the first — there is no producer at all, so the
join is UNREACHABLE rather than merely unoccupied. That distinction is the
whole difference between retiring a dead model and deleting a live wall.

DISPOSITION: delete. This completes floor-cut Step 2, which already named both
files by identity as machinery that "falls out" once reachability confirms —
they survived the cut and stopped being reached, which is exactly the third
bound that plan records the census cannot see. DESIGN section 6: a new artifact
with no final consumer is experimental residue, and the reviewer's test is
whether it survives the terminal architecture AND is consumed by it. The model
is well built; that is not an answer to that test.

Landed with it: the two non_fold_residue frontier rows and their reason and
dissolution strings; and every surviving citation of the pair rewritten to the
past tense with the deletion and its date recorded, because a citation left
naming a deleted symbol fakes a grep hit for the next reader. Two of those were
already false before this change — ci_failure_class claimed claim_executor
"already resolves gunbc.floor_component_receipt" (it never did), and cli_run.rs
twice cited floor_component_resource_checkpoint_note and
floor_component_phase_journal_scaffold_note, which resolved in neither the
receipt module nor anywhere else.

DURABLE HOME for the finding: a receipt appended to the
reachability_read_as_occupancy row in gunbc.recurring_failure_mode, which had
only the "do not delete a quiet guard" pole and now carries the discriminating
counter-specimen for the other one. docs/design-ledgers.md is reprojected.

NOT WIDENED, flagged instead: src/v2/workflow/ci_floor_peak_emit still emits a
shell echo naming "the floor-component-receipt artifact", and its own emission
does not appear in witnesses.yml. That is a separate unconsumed emit surface,
not this cut.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Li6e7cEDFodeBV7uPi3yTz

* Roster the class at its real grain: unbacked_execution_claim, one class with two origins

XL-N extended the lane: the receipt's present-tense recital is probably not
alone, and if so the class is not about the falsifier and not about the receipt.
It is PROSE ASSERTING A LIVE EXECUTING RELATION THAT NO AUTHORITY BACKS. New
roster row gunbc.recurring_failure_mode unbacked_execution_claim, projected into
DESIGN.md's index and docs/design-ledgers.md; the recital half is lifted off
reachability_read_as_occupancy, which keeps only the consequence for ITS rule
(a good model with no consumer is still residue) and points at the new row.

ONE CLASS, TWO ORIGINS, and that is a decision with a reason. Origin A is
falsified by a later deletion (the receipt's alert). Origin B is FALSE WHEN
WRITTEN — ci_failure_class claimed claim_executor "already resolves
gunbc.floor_component_receipt" and it never did; cli_run.rs twice cited two
notes that resolve nowhere. The origins differ, but the recognition rule and the
remedy are identical, so they are a FIELD of one row rather than two rows; two
rows would fork one recognition rule.

I APPLIED XL-N's TEST, not the runs/enrolled one, reading each line in context
rather than from the grep window. std.witness_admission
witness_cadence_has_scheduled_route is the single authority: does the prose
imply a live route for an arm it says is routeless?

RESULT: SIX CANDIDATES, FIVE CONTAMINATING, ONE FALSE POSITIVE.

CONTAMINATING (none in modules this PR otherwise touches — listed for routing,
deliberately NOT fixed here, per the stop line):

1. dag/test/claim/instrument_sandbox_witness_test.dag
   fixture_line_remaining's preceding annotation: "stays per-PR while the live
   half runs on the falsifier lane". The live half is
   dag/test/claim/long/instrument_sandbox_live_witness_test.dag, enrolled on
   gunbc.ci_layer_roots falsifier_substrate_long_lane_rows =
   FalsifierSubstrateLongLane, routeless. Present-tense "runs". The same file's
   line 55 also claims that half moved "with a named executing consumer".
   NOTE: that half DOES carry a local recipe, and OfflineLocalRecipe has a route
   — so the repair is to name the recipe, not to call the witness unexecuted.

2. dag/test/claim/self_host_use_site_verdict_behavioral_witness_test.dag
   self_host_use_site_verdict_behavioral_receipt_holds's annotation:
   "Live host effects — nightly falsifier Wet batch when frontier row is
   SelfEmitted with binding". FalsifierSelfHostWet, routeless. The condition is
   about frontier state, not about the cadence existing.

3. dag/test/claim/self_host_body_producer_behavioral_witness_test.dag
   self_host_body_producer_behavioral_receipt_holds's annotation: same sentence,
   same arm.

4. dag/test/claim/self_host_logic_behavioral_witness_test.dag
   self_host_logic_behavioral_receipt_holds's annotation: "so it RUNS IN the
   nightly falsifier Wet follow-on batch (falsifier_self_host_wet_entries), not
   per-PR hermetic discovery or bin_witness_wet". The strongest instance —
   explicit present-tense execution, naming the routeless arm, and contrasting
   it against the one cadence that does have a route.

5. dag/test/claim/long/dag_compile_clean_perturb_corpus_witness_test.dag
   the annotation above perturb_cross_tree_import_corpus_green_holds:
   "Enrolled on falsifier_rehomed_bin_wet_entries (nightly batch 5)".
   THIS IS THE ARM THE NAIVE DISCRIMINATOR LOSES. "Enrolled on" is TRUE.
   "(nightly batch 5)" asserts a cadence that executes, and
   FalsifierRehomedBinWet is routeless. Minimal repair: strike "nightly" — the
   line already carries a local recipe, which is a real route.

FALSE POSITIVE, and it is the exemplar of the remedy rather than a specimen:

6. dag/gunbc/commit_workflow.dag, the annotation above
   ci_floor_witness_enrollment_note's neighbours: "moved from per-PR to the
   4-hour falsifier cadence" sits inside a block opening "RETIRED 2026-08-20 —
   the subject of this row no longer exists" and attributes the sentence to an
   "ORIGINAL CLAIM (operator ruling 2026-07-25)". Correctly framed already.
   Second false positive, already known and not re-derived:
   gunbc.rust_item_host_observation's "executes as the falsifier" — falsifier as
   a ROLE, the discriminating test, matching every keyword and meaning nothing
   of the kind.

WHY THE REMEDY IS PAST TENSE AND NOT DELETION: the reasoning these sentences
support usually survives its executor, and a reader who finds a dangling claim
silently removed learns nothing. That is positional_citation's neighbouring
rule — a citation left naming a deleted symbol fakes a grep hit — so the
correction records the deletion rather than removing the name.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Li6e7cEDFodeBV7uPi3yTz

* The remedy field branches on origin — and verifying my own origin-B citations found BOTH were false

XL-N caught two defects in the row. Both are fixed, and the second one turned
the row's own content inside out in a way worth recording.

DEFECT 1, THE REMEDY WAS ONE ARM AND NEEDED THREE. "Past tense with the date,
never deletion" is correct only for a claim that WAS true and whose executor
died. Past-tensing a never-true claim manufactures a false historical statement
— "X USED TO resolve Y" asserts an execution that also never happened. And my
own item 1 shows a third case: the instrument_sandbox live half DOES execute,
via a local recipe, and OfflineLocalRecipe HAS a route — so the sentence names
the WRONG AUTHORITY for a live relation, and past-tensing it would record a live
relation as dead. That is a new contamination in the opposite direction,
produced by the remedy itself, which is exactly what this row exists to name.
A remedy mechanical enough to apply without reading WILL be applied without
reading. The row now carries one remedy arm per origin, and the
"never deletion" absolute is softened to a default: a sentence whose entire
content is a false execution claim has no reasoning to preserve.

DEFECT 2, AND IT IS THE MORE USEFUL ONE. XL-N asked me to verify the two
cli_run.rs notes rather than inherit them, on the grounds that a row about
unbacked claims should not itself contain one. It did contain two — and
verifying killed BOTH of my origin-B citations:

- floor_component_resource_checkpoint_note and
  floor_component_phase_journal_scaffold_note were REAL `data …: String`
  declarations in gunbc.floor_component_receipt. They were removed on
  2026-08-30 by the prose-bankruptcy sweep #9752, which converted module-scope
  commentary rows into §4c annotations corpus-wide.
- claim_executor DID resolve gunbc.floor_component_receipt:
  write_floor_component_receipt_at joined gunbc/floor_component_receipt.dag
  directly, from #7467 (2026-07-30) until #9228 deleted it (2026-08-25).

So ORIGIN B — never backed at all — HAS ZERO VERIFIED INSTANCES here. It is
recorded as conceivable and unmeasured, with its remedy arm, rather than as a
population. I had asserted a two-origin class on the strength of two claims I
had not checked.

WHAT THE VERIFICATION FOUND INSTEAD is a third real origin with a corpus-wide
producer: THE CITED SYMBOL DIED WHILE ITS CONTENT SURVIVED AS AN ANNOTATION.
§4c makes an annotation uncitable by construction — no Accepted program can
read one — so every citation of a row #9752 converted was dangling the moment
that sweep landed. The population is that sweep's diff, not anything about this
module. Its remedy is its own arm: name the module and the FACT, since there is
no symbol left to cite; past-tensing would report the content as gone when only
its citability is.

RECOGNITION RULE EARNED, and it is now in the row: "resolves nowhere NOW" is
not "never resolved". The distinction is decided by history, not by the working
tree, and the instrument is `git log --all -S` over the DECLARATION FORM —
which also separates the two attested origins by showing WHAT deleted the
referent. Nothing but a reviewer asking for verification caught this.

CORRECTIONS TO WHAT I ALREADY LANDED, applying the arms to my own diff:
- ci_failure_class: my first pass DELETED the claim_executor comparison as
  false. It was true. Restored in the past tense with both dates, as the worked
  precedent it still is — remedy arm 1, not arm 4.
- cli_run.rs, both sites: my first pass said the two notes "resolved in neither
  the receipt module nor anywhere else". False. Now records that #9752 made them
  uncitable and the pair was deleted after — remedy arm 2.

docs/design-ledgers.md reprojected.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Li6e7cEDFodeBV7uPi3yTz

* Cite the census that already owns this population instead of minting a second authority

Found while pre-reading the five corrections for PR two:
gunbc.deleted_cadence_reference_census ALREADY EXISTS and already owns the
falsifier-cadence instance of this class. Twelve sites, a
DeletedCadenceReferenceStanding vocabulary whose PremiseInvalidated arm is
exactly "the prose asserts a cadence that no longer executes", and one
GuaranteeRungDrop filed ONCE for the shared executor rather than per site —
with its own note explaining that twelve copies of five fields would be twelve
places to update when the route returns.

The row I was about to land described that population as though it were an
open finding. That is a second authority for a fact that already has one —
the §3 violation this row's own remedy exists to prevent, committed inside the
row, which is the third time this lane has caught the class reproducing itself
in its own remedy.

The row now CITES the census and copies nothing from it. What stays here is
only the recognition rule and the remedy arms, which generalize past the
falsifier; the population, its standings and its drop stay where they already
live.

TWO THINGS THIS CHANGES FOR PR TWO, recorded now so the next session does not
re-derive them:

1. My five corrections are NOT in the census's twelve. The census subject is
   "authority rows whose stated enforcement, audit or backstop was the
   affected-set falsifier cadence" — rows that RELIED on the cadence. My five
   are witness-test annotations asserting their OWN cadence. Whether that is
   the same subject or an adjacent one is the first question PR two answers,
   and it is answered against the census's declared subject, not by me.
   Either way the five get enrolled or the subject gets widened deliberately —
   they do not get freelance prose edits beside an existing authority.

2. The corpus has already applied my remedy arm 1 correctly, twice, in the
   exact wording the row now recommends: ci_layer_roots bin_witness_wet_note
   carries "THE JUSTIFYING HALF OF THAT SENTENCE IS PAST TENSE (2026-08-26)"
   with the deleting commit and the census citation, and
   namespace_import_closure_behavioral_transport nic_doc carries
   "classification is membership, not execution". Those are the exemplars PR
   two should match rather than invent a house style beside.

docs/design-ledgers.md reprojected.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Li6e7cEDFodeBV7uPi3yTz

* Origin 2's population is ZERO, not the sweep's diff — and the correction is better than the claim was

gentle-bear-446 (XL-0-CITE) measured the population I flagged and it is zero.
I verified both of their load-bearing facts rather than inheriting them.

WHAT I HAD WRONG. The row reasoned that because §4c makes annotations
uncitable, the prose-bankruptcy sweep broke every citation of a converted row,
making the population the sweep's own diff. The premise is right and the
conclusion is backwards: v1_compiler.cli_run annotation_erased_scan_text feeds
the semantic passes, so annotation text is not in the tree the harvester walks,
and v1_compiler.declaration_index admits citations from exactly two producers,
citation_from_record_literal and citation_from_constructor_call. A plain name in
annotation prose was never a citation, so the sweep could not break one.
Measured zero today AND as of the sweep commit, on a control that discriminates
in both directions — so it is not a zero produced by someone repairing it later.

WHAT THAT LEAVES IS A BETTER ROW, not a smaller one. These citations bind
READERS and no mechanism, so they belong in §4b's OUTSIDE THE MODELED GUARANTEE
column — observed and repaired by reading, never gated. Calling them a
dangling-citation population would have been rung inflation about a check that
by construction cannot see them. The two cli_run sites remain genuine instances
of the harm, and the honest statement is that no mechanical census would have
found them.

SECOND CORRECTION, TO A DATE BOTH I AND MY MANAGER REASONED FROM. We both
framed this as a measurement of what the cited-symbol drop cost while it stood.
It was not standing. Verified in the drop's own row: "THE RESTORATION TRIGGER
FIRED ON 2026-08-25 AND THIS ROW IS RETIRED AS A DROP", restored strictly wider
as v1_compiler.declaration_index in the parse phase of --required-ci. The sweep
landed 2026-08-30, five days AFTER, under a live and wider check.

AND THAT MISFRAMING HAS A CAUSE WORTH ROUTING, which I am reporting rather than
fixing because it is load-bearing §4b modeling and outside this disposition:

  gunbc.design_document, the §4b rung-drop list — DESIGN.md's
  "The ones standing today:" is projected by
  `map(rung_drop_roster, d => …)` with NO filter, so it enumerates every row in
  the roster including retired ones. One of the nine listed is retired. The
  retirement is recorded only in prose inside the row's own body, so the
  projection cannot filter on it: the fix is a modeled retirement field on the
  drop carrier, not a predicate over existing data. This is the canonical
  authority asserting a live state its own ledger contradicts — this row's class
  in the document that defines it — and it is what led two sessions tonight to
  reason about an unguarded window that did not exist.

docs/design-ledgers.md reprojected.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Li6e7cEDFodeBV7uPi3yTz

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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