Skip to content

FLOOR-Y cutover: delete the CI floor, rebuild from the run_required_floor seed - #8283

Merged
briansrls merged 92 commits into
mainfrom
integration/floor-cut
Aug 17, 2026
Merged

briansrls merged 92 commits into
mainfrom
integration/floor-cut

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Aug 15, 2026 •

Copy link
Copy Markdown
Contributor

Integration branch for the floor replacement cut (DESIGN §3 vehicle: a breaking cut never lands on main mid-loop). This PR is the standing view of the whole cut vs main — it accumulates as fix-forward commits land on integration/floor-cut, and it is the one atomic merge main eventually receives.

Merge bar: one green run on the current head. The branch is no longer deliberately red — it now carries an explicit, named debt population instead, described below.


What the cut deleted

The composed floor: ci.yml, falsifier.yml, falsifier-alert.yml, their .dag authorities, the v2 scheduler, per-PR discovery, the compile-clean gate ordering, the selection cluster (3,813 lines, 42 diagnostics), the join and refusal apparatus and Floor2Plan (258 lines), and ~30 witness modules.

What replaced it

One emission — gunbc.witness_floor_workflow → .github/workflows/witnesses.yml — invoking our own binary once:

claim_executor --required-floor --source-root dag --source-root src/v2

No plan entry, no plan function, no batch id, no worker role, no selection flag. run_required_floor folds every discovered witness through one PreparedRepository.

Exactly which identities do what

This section replaces an earlier claim that "the whole discovered roster runs unshrunk by construction". That sentence was true of the fold and false of the run, because two populations are declined before the fold sees them. The honest statement is a partition, and the run now proves it by identity rather than asserting it:

offered = executed  ⊎  long-home-declined  ⊎  live-tree-declined
  • executed — every one of these runs, and its outcome is asserted. Within it:
    • passed — ordinary green.
    • known_red_held — enrolled in v2.workflow.floor_expected_red, failed exactly as enrolled. Reported as its own terminal count, deliberately not folded into passed: agreement about a failure is not a passing witness, and a number that rises as debt is added has no direction left to report repayment in.
    • failed — anything else. Reds the build.
  • long-home-declined — three module-path prefixes. A deliberate hack, kept deliberately dumb.
  • live-tree-declined — modules declaring LiveTreeDisposition = ReadsLiveTree. These are wet witnesses with no wet consumer; they refuse rather than fabricate. This is a real coverage hole, stated as one.

A site declined by neither arm refuses the run. That arm is the silent narrowing this whole path exists to make unwritable.

The expected-red roster, and why it is not a skip list

v2.workflow.floor_expected_red enrolls failing identities at exact qualified-name grain — never by prefix, module, or directory. Enrolled rows still execute and their outcomes are still asserted. Three arms:

state verdict
not enrolled, fails reds the build
enrolled, fails held debt
enrolled, PASSES reds the build, naming itself for removal

That last arm is what makes the roster monotone: it can only shrink under an honest run, and its length is legible as debt rather than as policy. Four mechanisms keep it from rotting:

  • a duplicate identity refuses (the roster's length is read as the debt; 820 rows naming 819 identities would report one more fixed row than exists);
  • an enrolled identity that did not execute refuses by name (otherwise a renamed or deleted row sits there forever, never observed, never passing, never asking to be removed — and enrolling a nonexistent identity would be a free fake-green);
  • held + now_passing must equal the roster exactly, so a later third arm cannot quietly swallow rows;
  • removing a row requires the row to pass. There is no way to close work by editing the roster.

The roster asserts expected non-pass, not exact failure equivalence — a row may change from an assertion-false to a timeout and remain enrolled. Typed cause is a post-merge refinement.

The debt, by class

820 identities, measured on tree 380c242c79a. This is an observation on one tree: bare-name binding consults the containment relation only when a name has two or more candidates, so changing what is loaded moves references between a checked and an unchecked arm, and a diagnostic count moves with the instrument's sensitivity as well as with the defect population. Cross-tree deltas on this branch are not a progress metric.

family rows what it is
name resolution ~342 172 call-contract mismatches, 154 missing functions, 16 undefined variables — one root cause: bare names bind by insertion order
budget ~291 bimodal: ~250 sit within 1–20% of the ceiling, ~39 are genuinely expensive (max 29,040ms)
hermetic mock refusals 101 wet witnesses with no wet consumer — not failing tests
assertion false 46 the claim is actually false
other ~40 non-exhaustive matches, arity

What is explicitly not in this PR

The parity comparator, the full disposition/cadence model, a wet consumer, sharding, the regen/heal re-add, the namespace cut, universal qualification, sub-500ms everywhere, and emptying the roster. Each is a successor. Bundling them converts the first step toward a faster floor into the last step of an entire CI redesign.

Cost

Preparation 529s, fold 2204s, witness execution 94.5% of the fold — so the fold parallelizes near-linearly, but every shard would pay its own preparation and its own ~15 GB resident set. Serial ≈ 46 min; N=5 shards ≈ 16 min; N=20 ≈ 11 min. Preparation becomes the floor almost immediately, which is why sharding is a successor and not part of this cut.

gunbc-ci-auto-heal and others added 10 commits August 15, 2026 12:38
…n import

The selection-control job died with affected-set selection; cadence_verdict_should_fail
still took its outcome, and the topology witness still pinned four jobs.

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

Operator directive 2026-08-15: wipe every single thing in CI; jobs come back one
by one only as agreed. This deletes the three workflow artifacts, the modules that
emitted them, and the witnesses whose only subject was the deleted surface. It adds
nothing. fleet-converge.yml survives untouched -- that is fleet operations, not CI.

WHAT IS GONE

  artifacts   .github/workflows/{ci,falsifier,falsifier-alert}.yml
  registry    CiYamlArtifact and FalsifierYamlArtifact rows, their paths, commit
              policies, equality arms, generation arms and extra-validation arms
  emit        gunbc.ci_yaml_emit, gunbc.falsifier_workflow, tools.emit_falsifier_yaml,
              and ci_workflow's job surface (ci_job, ci_build_job, ci_regen_job,
              ci_heal_generated_artifacts_job, ci_fleet_job, ci_regen_floor_step and
              the ci_workflow Workflow value itself)
  falsifier   lane, run control, cold-corpus execution, and all four alert modules
  plan        v2.workflow.ci_floor_plan -- entirely, including gunbc_ci_regen_floor_plan.
              The regen plan is a real obligation and it returns from the quarry when
              the regen job is re-agreed; keeping the obvious survivor is how a deleted
              structure grows back.
  gate        gunbc.ci_materialization_gate (its subject was the ci_workflow value)
  witnesses   30 test modules whose subject was one of the above

WHAT SURVIVES, AND WHY

ci_workflow.dag and ci_spec.dag are retained as GitHub Actions STEP vocabulary, not as
CI: fleet_converge_workflow consumes ten step constructors and five timeout rows from
them, and fleet-converge.yml still generates. Every job, the workflow value, and the
floor step are deleted from ci_workflow. The commit gate roster in commit_workflow.dag
is retained deliberately -- it IS the obligations ledger the re-add queue is drawn from,
and deleting it would delete the record of what CI used to owe.

realization_artifact_for_surface now returns GeneratedArtifact? rather than a total
GeneratedArtifact: three of its four surfaces have no artifact after this wipe, and a
surface with no artifact answers none rather than a fabricated plausible one.

THE RUNG DROP, DECLARED (DESIGN section 4b)

  previous rung   mechanically preventable -- every class below was blocked at merge by
                  an executing required check
  temporary rung  mitigatable at best, and for most classes nothing at all: the invalid
                  state is writable and no mechanism observes it
  reason          the floor's structure was the thing being deleted; re-adding
                  obligations onto it would have preserved what the cut exists to remove
  population      the whole repository, every push, for the duration of the branch
  restoration     obligations return one at a time from the ledger below, each
                  re-derived from first principles rather than restored from quarry,
                  each closing only when the operator is satisfied with its performance

THE OBLIGATIONS LEDGER -- what this deletion actually orphaned

  1  build and artifact verify (the release bins every other job consumed)
  2  the witness corpus: 48 roster rows on GithubActionsCiJob, plus tree-wide
     *_test.dag discovery -- no witness in this repository executes on any push today
  3  the regen self-host fixed point: 2 roster rows on GithubActionsCiRegenJob
  4  the generated-artifact drift gates -- and note the second-order loss: with the
     drift gate gone, .gitattributes and the remaining generated artifacts can now
     drift from their authorities silently
  5  the seven effect gates in tools.floor_effect_gate_witness: dag compile-clean,
     generated-artifact drift, emit-host, extdeps citation, extdeps scope placement,
     prose-row introduction, cheap-claim pool
  6  the cargo fmt gate (the pre-push hook still runs it locally; that is opt-in per
     clone and bypassable, so it is not an authority)
  7  heal: repo-local git config convergence, binary/source skew guard, author-commit
  8  the falsifier cadence: 8 roster rows on FalsifierCadenceJob, and with them the
     cold-corpus control that was the only unselected whole-corpus run in the system
  9  compile-clean scope selection, ci.yml drift+parse, merge-admission stamping

The two pre-existing broken modules (complexity_accumulator_copy/analyze.dag,
live_read_classification.dag) are untouched and were already red before this branch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbc-ci-auto-heal and others added 19 commits August 15, 2026 16:23
Operator spec, verbatim: "a single github actions emission into our own binary -
that then runs all test witnesses in the repo via a single fold." This is that,
built fresh rather than restored.

THE EMISSION. dag/gunbc/witness_floor_workflow.dag is a new module, not a revival
of gunbc.ci_workflow's job-spec architecture. It emits .github/workflows/witnesses.yml
-- 30 lines, one job, four steps: checkout, toolchain, one cargo build of exactly
the two binaries the fold needs, one invocation of our own binary. There is no
second job, so nothing to sequence, no artifact to hand over and no `needs` edge
to get wrong. The predecessor's 19-binary roster is not re-derived (most of those
bins this cut deleted), and neither is its CARGO_BUILD_JOBS=1-then-unset-RUSTC_WRAPPER
retry arm, which made an sccache deficit unobservable by construction.

THE FOLD. claim_executor --required-floor takes no plan, so it short-circuits
before the plan-arg requirement: no schedule to resolve, no batch to assign, no
worker to spawn, no selection to compute. run_required_floor prepares the
repository ONCE, projects one immutable scope per distinct claim scope from the
compiler's own func_env closure, builds a cheap fresh mutable frame per claim, and
folds every witness exactly once. It refuses when planned, executed and terminal
identity counts disagree, so a silently short roster cannot report as a pass.

Which claims exist, what identity each has, which frame each needs, and whether
the roster is admissible at all are decided in .dag by v2.workflow.required_floor.
Admission is all-or-nothing: a manifest carrying any refusal does not run its clean
subset and report on the rest.

PORTED, and only this. From session/vivid-bear-458-floor2 b19a3e2: the
preparation/scope/fold stack in cli_run.rs, the PreparedScopeIndexes split in
v1_interpreter.rs (immutable indexes built once per scope, fresh mutable state per
claim), and the two .dag manifest modules. The quarry's plan, batch, worker and
coordinator surfaces are not migration subjects and did not come across.

ci_workflow.dag IS DELETED. Its last consumer was fleet_converge_workflow, which
needed ten step constructors and five timeout rows -- never CI facts, only
CI-authored ones. Those move to gunbc.fleet_workflow_steps and fleet-converge.yml
still generates. Keeping ci_workflow alive as the home for its own last consumer is
how a deleted structure grows back around whatever survived it.

Also: claim_executor_hand_rust_boundary.dag deleted (it instruments a floor-plan
architecture that no longer exists -- the dangling import tidy-gull-813 reported),
and two stale citations corrected where the deferral they recorded was discharged
by deletion rather than by a schedule.

STILL ABSENT, deliberately: regen, heal, drift gates, the seven effect gates, fmt,
merge-admission stamping, the falsifier cadence. Ledger rows, one at a time, each
under its own agreement.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
single_shard() is its constructor and claim_executor cannot name a private type.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The required fold prepares two source roots, dag and src/v2. 116 test fn
declarations across 15 files under src/v1/tests/claim are therefore outside its
subject, with no consumer and no cadence behind them since the scoped witness
batch was deleted.

Declared rather than fixed, deliberately. Adding --source-root src/v1 is one
token but admits 52 non-test v1 modules into the single flat namespace the fold's
scopes are projected from, and a first census taken against a subject nobody has
run is not a census worth having.

Declared rather than quiet, also deliberately: run_required_floor's own
identity-count refusal makes a narrowed roster unable to present as a roster, but
that wall works INSIDE the subject and cannot see a population the subject never
admitted. So the honesty has to be carried in prose at the boundary -- the fold
runs every witness in its subject, and its subject is two roots.

Dissolve-on: the boundary decision on those 15 files, carrying a recommendation to
relocate them into the dag test root rather than widen the root set.

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

The first real execution of the fold refused at strict preparation and found two
classes of residue my own whole-corpus compile could not see. `gunbc compile
--target dag` resolves a transitive IMPORT CLOSURE and reports the remaining 1,135
modules as census-only; the fold admits every file under both source roots. That
difference is the fold's entire value and it collected on its first run.

THE OVER-DELETION. Commit 19890af replaced the first 84 lines of
dag/gunbc/roster_registry.dag with 3. The intent was to drop two RosterRegistration
rows whose rosters the selection cut deleted (scoped_witness_batches,
v1_claim_scoped_witness_entries); the deletion took the module declaration, both
imports, four notes, the GroupMembership type, the RosterRegistration type and
roster_decl with them. The file has declared no module since, so
v2.lens.roster_registry's import of it was unresolvable and the whole registry
cascade -- 13 diagnostics in the test, 7 in the lens, every downstream
RosterRegistration / roster_decl / ByContainment / ByDerivation failure -- followed
from one missing header.

Repaired by restoring the header from origin/main and re-applying only the two
intended row deletions. 35 registrations remain; zero scoped_witness references.

THE SIX ORPHANS, each importing the deleted v2.workflow.ci_floor_plan. Five are
deleted outright because their subject was the floor plan or the falsifier lanes:
pr_native_batch_test, realization_schedule_witness, walk_plan_schedule_lens_test,
schedule_occurrence_multiplicity_test, and the production_qualification_origin_probe
cadence fixture. The sixth, v2.workflow.ci_placement, is production and survives: it
reads the fast-lane budget, which this cut re-homed to gunbc.witness_row_cost. Its
note is corrected to say the threshold is now DECLARED and not enforced, because the
executor that armed it is deleted.

NOTHING WAS NARROWED TO GET GREEN. No exclusion row added, no source root shrunk,
no file dispositioned out of the subject. After the repair the fold's refusal set
contains ZERO references to anything this cut deleted; what remains is pre-existing
breakage the fold is the first mechanism to surface.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Three rulings from the re-add #1 boundary, carried on the module they are about
rather than in a plan document that would drift from it.

WHAT THE REFUSAL DISCOVERED, and it is larger than the wall-clock: this repository
has never been whole-tree strict-typechecked. The old floor prepared per-entry
closures, so a broken module reddened only the closures importing it, and a module
nothing imported was never typechecked at all. This fold's admission wall is the
first mechanism ever to demand the whole tree resolve as one namespace, and it
cannot yet. The same asymmetry caught this lane: `gunbc compile --target dag`
reports 1,135 modules as census-only, which is why six orphaned importers passed a
whole-corpus compile and were found only by the fold.

ALL-OR-NOTHING PREPARATION IS UPHELD. The subject is the corpus; admitting a
partially-typechecking subject while reporting a whole-corpus verdict is the
empty-observation narrow, which DESIGN names as strictly worse than the widen
section 5 forbids -- a widen is expensive, a narrow is silently uncovered.

THE LARGEST CLASS IS NOT THIS LANE'S, AND MUST NOT BE FIXED THE OBVIOUS WAY. 151 of
185 undefined-variable diagnostics are one name, `Empty` -- FreeMonoid's nullary
constructor in std.algebra, verified present and unrenamed. They are bare
cross-module references that no import brings into scope; the old path admitted them
by pool-membership coincidence. Repairing by authoring 151 import lines would author
them into a grammar the namespace lane is deleting. The class belongs to
containment-based resolution, so the fold's first green is downstream of that cut --
a cross-lane sequencing fact, not a defect in this step.

THE MEMORY ENVELOPE IS FIRST-CLASS. One run OOM-killed (exit 137 at 537s during
preparation); the next peaked at 9.37 GiB, climbing 3.9 -> 6.3 GiB over 90 sampled
seconds. The binding constraint is the shared 20 GiB slice, not the 31 GiB container
cap. Consequence named: non-deterministic OOM is what makes a required check flaky.
Direction ruled and measurement deliberately not started -- do not re-shard into
batches or workers to make it fit, since that is the deleted decomposition rebuilding
itself inside its replacement. The peak is a cost-shape defect to root-cause.

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

The previous revision of this note said `Empty` is FreeMonoid's nullary constructor
in std.algebra, declared once. It is declared TWICE -- std.stack `Stack` and
std.algebra `FreeMonoid`.

The error was reproduced independently on both sides of the relay: each of us
grepped the module we had been pointed at, and neither swept the tree for a second
declaration of the name. That is the incomplete-enumeration class committed while
diagnosing the incomplete-enumeration class. It is recorded in the note rather than
quietly amended, because the corrected fact changes the remedy.

WHAT CHANGES. These are bare references to a two-candidate homonym where neither
candidate sits on the referencing module's containment chain, so containment-based
resolution cannot bind them -- the honest answer there is a refusal for ambiguity.
The class is therefore corpus AUTHORING work (a qualified reference per site), not
resolver work, and the dependency the previous revision recorded -- the fold's first
green as downstream of the namespace cut -- is STRUCK. It was a promise made on
another lane's behalf that its own measurement showed it could not keep.

WHAT DOES NOT CHANGE. Still one class with one mechanical rule. And the ruling
against adding import lines stands, with a sharper reason: a qualified reference IS
the dependency edge, which is the end state; an import line is the grammar being
deleted.

Not started here: 151 qualified references authored on this branch would collide
with the namespace branch's rewrite of the same files, so the sequencing is an
operator decision.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The list named regen as an unmet obligation awaiting its turn. The v1 cut deleted
regen_stage0 with the whole v1 .dag compiler authority, so the statement was false
in the direction that invites someone to restore it.

The emitted Rust is retained and frozen; what died is the loop keeping it in sync
with an authority that no longer exists. Deleting regen in that same commit was
load-bearing -- left standing it would have computed an empty emit set against the
deleted authority and deleted the 142 frozen files.

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

THE QUALIFICATION PASS. All 151 bare `Empty` references rewritten to
`std.algebra.Empty`, applied positionally at the exact reported line:column rather
than by file-wide token replace, so `EmptyDiffIds`, `NonEmptyStr` and the rest are
untouched. 151 rewritten, 0 skipped, across 42 files.

Every site is FreeMonoid, established rather than assumed: no file containing an
`Empty` site mentions `Stack` or `Push` anywhere; every use sits in a `Cons`-paired
or list-shaped position (`tail:`, `empty:`, `acc:`, `init:`); and `List<T>` is
declared as `FreeMonoid<T>` in both std trees, so every `List` context is a
FreeMonoid context. `std.algebra.Empty` was already the corpus idiom in
`v2.lens.coverage` and `v2.lens.enforcement.grammar_coverage`, neither of which
errors -- so this pass makes the majority match the working minority.

THE CORRECTION, which matters more than the pass. The first-execution receipt said
zero of the 282 diagnostics referenced anything this cut deleted. That was false.
The check behind it was a grep for names I expected to find, so it could only
confirm my own list; two carriers from the deleted affected_set_floor_runner
(FloorDiffLineTouch, DiffPathsProduced) matched none of those patterns. The sound
check asks from the other side -- for every unresolved symbol, is it declared in the
live tree, and if not, was it declared in a file this branch deleted -- and it found
them at once.

Their two consumers are deleted here: affected_set_witness_a_prove_test and
affected_set_disposition_both_axes_test both test the deleted selection kernel
(floor_witness_run_disposition, floor_kernel_would_skip) against fixtures under the
deleted test/fixture/floor_skip/ tree. They should have gone with it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…and delete a floor roster the wipe missed

The Empty pass closed the largest class; this closes the rest of the class it
belonged to. Every unresolved-type, undefined-variable and function-not-found
diagnostic is now gone from the fold's subject. What remains is 18 diagnostics
in 11 files, none of them about naming.

QUALIFICATION, ~23 symbols. Each resolved by SHAPE against both candidate
declarations, not by tree side or directory proximity, because proximity would
have guessed wrong three times:

  Exact     -> v2.lens.enforcement.vocab       use site passes kind: ConsumerKind;
                                               cron takes value:, coercion takes nothing
  Refuse    -> v2.lens.enforcement.standing_intent   use site is bare;
                                               upsert_decision's carries {reason}
  Blocking  -> v2.lens.enforcement.vocab       EnforcementMode -- a declaration my own
                                               index MISSED, because it sits inline on
                                               'type EnforcementMode = Advisory | AuditOnly | Blocking'

standing_intent.dag already writes v2.lens.enforcement.vocab.Blocking, so as with
Empty the pass makes the majority match a working idiom rather than inventing one.

MY INDEX WAS UNSOUND IN BOTH DIRECTIONS and the correction is the durable part.
First pass missed inline variants; second pass matched match-arms and == , inflating
Empty to 57 declarations. That is rebuilding the parser by grep over a language whose
declarations the compiler already knows -- DESIGN section 6 aimed at one's own tooling.
The form that is sound by construction: THE INDEX GENERATES CANDIDATES ONLY, THE
COMPILER DECIDES. Every choice here is refutable by the fold, and the fold ran.

THREE DEFECTS THE CONCEALMENT CENSUS SURFACED, all pre-existing, none reachable
before whole-tree strict preparation:

  - claim_pipeline/normalize.dag read normalized.children where normalize returns
    NormalizedTree sole_constructor { root: Node }. The return type was tightened and
    this caller was never updated, because the module has never been typechecked.

  - Two grounding_typescript rosters, 9 lines each, whose entire content is four
    subjects that have never been declared anywhere in this repository -- on this
    branch or on main. Verified inert in all reference forms before deleting.

  - Two round_trip aggregators called umbrella fns dissolved by 611fd70. Repaired by
    inlining the seven conjuncts each stood for, all 14 verified present as test fn
    first. Deleting the umbrella instead would have silently dropped the three
    non-test-fn conjuncts below it, which nothing else executes.

FLOOR RESIDUE THE WIPE MISSED. src/v2/workflow/claim_witness_corpus_ci_runner.dag:
71 hand-authored rows of entry+function STRINGS, ten pointing at files that do not
exist, nothing checking that any string resolves, zero live consumers. It is the
opt-in roster the single fold replaces. Its scaffold row in language_source_scaffold_index
declared dissolves_to: SingleAuthority bound at that very type, so deleting the module
FIRES that dissolution rather than dodging it; the bind is repointed to
v2.workflow.required_floor RequiredFloorClaim, which is the authority now.

QUARRY DISCLOSURE. Commit b9cb125 on session/vivid-bear-458-floor2 had already
dispositioned the rosters and the umbrellas. It was not cherry-picked. It was read as
an oracle, every claim re-derived against this tree, and the same disposition reached.

THE 18 THAT REMAIN are six real classes, all typecheck-grade, none naming:
  6  EqualsClaim rows carrying rhs: true where the carrier declares Node
  3  method surface: complement/meet/join on Container(BooleanAlgebra, Coproduct(Bool))
  2  subterm_at called with p: where the declared parameter is path:
  2  Empty/Cons in pattern position against List, where List<T> = FreeMonoid<T> --
     the alias does not project its coproduct's variants into a match
  2  Holds/Violates matched against Optional, plus a non-exhaustive Absent/Present
  1  a function value called with a named argument
  1  nat_compare ambiguous between v2.std.nat and std.nat
  1  resolve, unique declaration, referenced bare cross-module

INSTRUMENT NOTE, scoped honestly: the parse gate covers the SOURCE ROOTS, not the
repository. Every path edited here is inside dag/ and src/v2, so this change is fully
covered; a change touching .dag elsewhere would not be.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…tes do not ride on it

The regen paragraph in witness_floor_workflow stated its retirement in a settled
present tense it had not earned. regen_stage0 and its 142-entry roster are deleted
on integration/v1-cut and ALIVE on main, so "its subject is deleted" is a fact about
a branch, not about the repository, while the paragraph read as though the obligation
were already discharged.

Two arms it did not name, both now stated:

  - if THIS cut lands first, main carries a live regen authority with no required job
    invoking it. That is a real gap someone must own, not a settled absence.
  - if v1-cut never lands, the item returns to the queue as an ordinary unmet
    obligation rather than a retired one.

An unfireable retirement is worse than no retirement, because it reads as handled and
so never ranks for attention -- the same failure shape as an inert lens, and section 4b
requires a trigger that can actually fire.

This is the identical branch-dependent-population defect already declared on the src/v1
coverage gap row a few hours earlier. Having applied that discipline there and not here
is the point worth recording: the defect is not hard to see once named, it is hard to
remember to look for.

SEPARATELY, AND MEASURED: the drift gates do not ride on regen. On the v1-cut branch
heal_generated_artifacts PASSES while regen is RED, so "the regen fixed point and the
generated-artifact drift gates" is two obligations with two subjects and only the regen
half is order-dependent. Recorded so a future reader cannot retire the drift gates by
association when the regen half retires.

Prose only. No mechanism, no generated artifact, no change to the emitted workflow.
Parse-checked: 0 blocking errors.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…y judgment calls remain

The branch-head fold now refuses with 5 diagnostics in 2 files, down from 18 in 11.
Everything closed here was a decidable local defect with a wrong-but-obvious answer;
what remains is exactly the two questions that need a ruling rather than a patch.

CLOSED, each verified against the actual declaration rather than guessed:

  nat_compare       ambiguous v2.std.nat vs std.nat -> qualified to v2.std.nat, which the
                    enclosing fn already names in its own signature (v2.std.nat.Nat)
  resolve           unique declaration referenced bare cross-module -> v2.compiler.resolve
  subterm_at        called with p: where the parameter is declared path:
  Optional/Witness  rust_call_facts_miss returns Optional<InferredFacts> and its consumer
                    matched it with Holds/Violates. Three diagnostics, one defect. Now
                    matched with Present/Absent, behaviour preserved exactly: facts when
                    present, generic facts when absent
  function value    predicate: fn(CostCoverageFnVerdict) -> Bool called with a named
                    argument. A function VALUE carries no parameter names -- named args
                    bind against a declaration, and there is none. Called positionally

  EqualsClaim rows  six diagnostics across three lens/application files, one shape:
                    lhs took a Bool and rhs took the literal true, where the carrier
                    declares lhs: Node, rhs: Node. Repaired to the idiom already working
                    in-tree (v2.test.lens_fact_density.kernel_ambient_bool): the *_claim_rhs
                    fn returns the expected NODE when the predicate holds and a distinct
                    node when it does not, with lhs pinned to the expected node. The claim
                    still passes exactly when the predicate holds and fails when it does
                    not -- the assertion is preserved, not weakened into a tautology.

REMAINING 5 ARE NOT MECHANICAL AND ARE DELIBERATELY UNTOUCHED:

  3  method surface: complement/meet/join on Container(BooleanAlgebra, Coproduct(Bool)).
     BooleanAlgebra<T> is a RECORD whose fields are functions; the call is field projection
     spelled as method syntax. Whether that should resolve is a substrate question, and
     DESIGN section 4 says operations come from inhabitance.
  2  Empty/Cons in pattern position against List at one site, two arms. Narrowed to a
     DOTTED cross-module type argument, 1 positive against 34 in-tree negative controls,
     traced to namespace wave 1 on main. Three lanes hit this root.

Making either go away at the use site is how a narrowed subject gets built, so neither was
touched. Both are escalated with witnesses.

Parse-checked whole-source-root: 0 blocking errors.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…of spelling them

The CI emission hand-wrote `--source-root "$ROOT/dag" --source-root "$ROOT/src/v2"` as a
string literal while `gunbc.ci_layer_roots` `witness_layer_roots` is the single authority
for that list -- the same one the compile-clean closure and the divergence census read.
A literal beside it is a second representation (DESIGN §3), and the rung drop is invisible
exactly while the bytes still agree: the copy typechecks and looks finished. The first time
the roots moved, this workflow would have compiled a different corpus than every other
consumer with nothing to report it.

`witness_floor_source_root_flags` folds the authority into the flags, matching the existing
`--scan-dir` fold in ci_layer_roots.

Proven inert: regenerating `expected_witness_floor_yml` reproduces `.github/workflows/witnesses.yml`
byte-for-byte, argv line included. RUNG HONESTY: this restores single authority, it does not fix
a demonstrated defect -- the literal and the authority agree today, so no drift can be exhibited.
The evidence is that one of them is derived and the other was typed.

Class named by tidy-gull-813 on a sibling lane the same day, from its own migration; found here
by asking their question of my own emitter rather than only of the files I deleted.

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

ci_release_build_step and ci_release_bins_unpack_verify_step carry their ids as literals;
in the deleted gunbc.ci_workflow they were the named constants falsifier_release_build_step_id
and ci_release_bins_step_id. My first reading scored that "two small single-authority
downgrades", which is the wrong test.

The right test is whether the value crosses a boundary where agreement is required but not
checked, and a step id is exactly that: GitHub Actions resolves steps.<id> job-scoped, and a
mismatch does not fail -- it resolves to null and the comparison is unconditionally false.
That defect ran at least sixteen days across three repair attempts on this repo, one of which
introduced a strictly worse version while fixing the prior one, with nineteen corpus
diagnostics uncaught in the window.

Measured at this head: no reference to steps.release_build or steps.release_bins exists
anywhere in the tree. The constants' only consumer was falsifier_control_prerequisite_if,
which built the condition by concat over the constant -- and it went in this cut. So the
inline is safe because THE CONSUMER THAT MADE THE BINDING LOAD-BEARING WAS DELETED WITH IT,
which is a fact about the current population, not a property of the construction. The next
if: gating on steps.release_bins.outcome will hand-write the string with nothing binding it.

Recorded beside the ids so the next reader gets the condition rather than the score.
Emission proven unchanged: expected_fleet_converge_yml reproduces fleet-converge.yml
byte-for-byte (annotations are erased before semantic passes, DESIGN §4c -- verified, not
assumed).

Class, history and the better test: tidy-pike-117, 2026-08-15; consumer census verified here.

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

I had repointed compiler_tests_harness_trigger's bind off
v2.test.workflow.claim_witness_corpus_ci_runner (deleted in this cut) onto
v2.workflow.required_floor / RequiredFloorClaim, because a dangling bind inside a live
Scaffold disposition looked worse than a correct one. Reverted.

WHY, and it is not that the row was wrong -- it pointed at a module that exists and is the
actual successor. It is that four independent censuses now agree this file's subject is going
away: 41 of 41 ct_ names defined in files another cut deletes, 57 v1 module-path literals whose
modules a third cut deletes, and my own path-literal join. Editing it at all is investment in a
dying authority, and here it also costs visibility -- DESIGN's evidence inversion, consequence
three of deferring a deletion: an optimized X looks healthier, so each improvement reads as
evidence the replacement is less urgent. One true row in a hollow roster makes the file read as
tended, and a tended-looking roster does not get deleted. THE PARTIALLY-REPAIRED ARTIFACT IS
WORSE THAN THE ROTTEN ONE BECAUSE IT IS MORE PLAUSIBLE.

So the bind rejoins the 32 deleted .dag paths this cut leaves named as string literals in 30
surviving carriers, none of which refuses. That population is recorded as a census, not swept:
they are the .dag-side half of the same delete-first question, gated the same way.

Found, declined, and stated -- a declined repair with a reason is worth more to the next reader
than a silent fix.

Ruling: tidy-pike-117, 2026-08-15, on my own disclosure.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ts rule note

THE SHAPE-CHANGED PASS ON MY OWN CUT, and it found the defect in my own re-home rather than
in anything I deleted.

When the CI wipe deleted v2.workflow.ci_floor_plan I re-homed the five-second fast-lane budget
into gunbc.witness_row_cost -- correct move, the threshold is a fact about what a witness row
may cost and that is this module's subject -- and RENAMED IT in the same motion, to
witness_row_fast_lane_*. It typechecked, it read tidier, and it broke 65 citations at once:
58 naming gunbc_ci_fast_lane_witness_eval_budget (every dissolution row in gunbc.ci_layer_roots
that says an entry re-enrolls when its eval lands under that budget) and 7 naming
gunbc_ci_fast_lane_eval_budget_ms, including the migration-threshold derivation and the comment
in its witness asserting the 500ms figure is derived rather than typed.

DESIGN §3 rules that a citation names the SYMBOL precisely so it survives a move. A RENAME
DURING A MOVE IS THE ONE EDIT THAT DEFEATS THAT, and it defeats it silently, because nothing
resolves a citation. Names restored; 72 citations now name a symbol that exists. Verified by
execution: witness_row_cost_migration_threshold_ms() still derives 500.

ALSO RE-HOMED: gunbc_ci_fast_lane_rule_note, which I deleted with its old module while keeping
the budget it explains -- 25 rows cite it. Re-homed under its own name and CORRECTED rather
than restored verbatim, because the original asserts an enforcement mechanism this cut removed:
the executor armed a per-witness eval deadline from that budget, and that executor is deleted.
Restoring the text unchanged would have carried a false claim into a live carrier under a name
25 rows cite. The note now states what survives (the long/ dir policy, the threshold), what died
(enforcement -- no consumer arms this budget today), the receipt that justified the deadline in
the first place (run 29183446733: 243 of 270 minutes after the last progress line, zero
witnesses completed), the rung drop, and the restoration trigger.

Class and the scoping rule that found it: tidy-pike-117 / crisp-crab, 2026-08-15 -- a row
describing a ROLE survives a change of mechanism, a row describing a MECHANISM does not, so
scope the pass by what surviving rows describe rather than by the size of the diff.

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

THE AUTHORITY ROW FOR MY OWN WORK WAS DESCRIBING A SYSTEM I DELETED. DESIGN's Building &
checks bullet recited, in present tense, a claim_executor invocation with a --plan-entry naming
a deleted plan, a falsifier that is deleted, and a corpus_selection_off_note that is deleted.
A knowingly-false present-tense recital in the canonical authority is not a neutral hold: every
session reading it plans against a command that does not exist.

Rewritten as the §4b rung-drop declaration -- what was there, that it is deleted, what runs now,
THAT NOTHING HAS EXECUTED, what is unguarded meanwhile, and the restoration trigger. Not a
description of a finished replacement; describing the rebuild as done would be the inflation §4b
names as worse than sitting low. The section gets rewritten in one pass when the re-add queue
closes, which is the trigger stated in the text rather than held in my head.

ENUMERATED BEFORE REPLACING, over four passes, because a prose row is deleted for one reason and
takes everything in it -- the same rule that governs deleting a witness file whole. The first
attempt regenerated 6KB smaller while only four lines differed, and the size delta was the only
thing that caught it. Preserved: tools.dag_compile_clean_scope and its import-closure selection,
regen_stage0/regen_input_sources, the grammar-owned YAML parse claim (never a floor fact at all),
the 2026-07-11 Rust-suite and 2026-07-08 clippy removal rulings, and the 2026-08-13 whole-roster
directive -- which the replacement satisfies BY CONSTRUCTION, having no selection flag to set.

TWO OTHER CITATIONS THIS CUT FALSIFIED, corrected minimally in carriers I do not own:
  gunbc.ci_spec x2 -- both cite v2.workflow.ci_floor_plan corpus_selection_off_note, deleted here.
    Now marked as history with the live property named, their rows otherwise untouched.

AND ONE OF MINE, WHICH IS THE SAME CLASS I HAVE BEEN REPORTING ALL DAY. I had corrected a stale
`cli_run::selection_control_input_sources` citation inside a receipt string -- at the LEAF,
src/v1/stage0/src/v1_std_core.rs, whose own header says "Generated by v1 compiler -- do not edit."
That made it bytes-only: an assertion with no authority behind it, silently reverted by the first
regeneration after merge, in a file no drift gate compares. The correction now lands at
src/v1/00_core.dag compiler_diagnostic_seed_projection_note, and the authority's text matches the
leaf's byte-for-byte, so the leaf is derived rather than asserted.

DESIGN.md regenerated from the corrected producer and verified identical to expected_design_md
output; delta -4229 bytes against 4 changed lines, checked rather than assumed.

Rulings and classes: tidy-pike-117 (ownership decides timing; enumerate before replacing; check
the size delta against the diff), crisp-crab (fix at the authority, not the next artifact up),
2026-08-15.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…han as a pair

THE INVOCATION CENSUS FOUND THESE, AND NOTHING ELSE WOULD HAVE. A lane that deletes a .dag fn is
covered by the name join; a lane that deletes a Rust fn is covered by cargo; a lane that deletes a
BINARY is covered by nothing, because the thing that invokes a binary is a string in a file no
compiler reads.

Sweeping my two deleted bins across dag/ src/v2/ .github/:

    selection_control_skip_witness   ZERO invocation sites.
    floor_skip_discovery_witness     four hits -- two prose, and TWO LIVE STRUCTURAL ROWS in
                                     src/v2/test/claim/witness_admission_test.dag naming
                                     dag/test/claim/floor_skip_discovery_witness_test.dag as an
                                     entry:, a file this cut deleted.

Those two would RED on the first execution of the fold, not pass silently -- traced through
witness_consumer_cadence_for_row: with the roster row gone, consumer_for_explicit_rosters returns
NoConsumer, the excluded_from_discovery arm falls through the path-substring checks, and neither
reaches FalsifierRehomedBinWet. Loud, which is the good outcome, but broken by my deletion and mine
to close rather than to leave for whoever hits it.

CHECKED PER FN, NOT AS "the two dead ones" -- a one-sentence justification covering N things is one
claim wearing a plural, and finding it true for one member is not evidence about the others
(tidy-pike-117 / tidy-gull, 2026-08-15, from a ruling that had just been refuted this way). The
question is whether the subject is the dead ENTRY or the live CLASSIFICATION MECHANISM:

    FalsifierRehomedBinWet             5 live roster rows in gunbc.ci_layer_roots, an arm in
                                       gunbc.explicit_witness_admission, and coverage in
                                       src/v2/test/claim/witness_exclusion_reconciliation_test.dag
    witness_admission_manifest_covers_row   still exercised twice in this same file

So the mechanism keeps its subjects and its coverage; only these two rows lost theirs. That makes
the deletion closure rather than a coverage loss -- which is the distinction the same ruling got
wrong an hour ago by accepting "imports from the file I am cutting" as evidence of subjecthood.

Cargo.toml verified separately: both [[bin]] blocks were removed with their sources, and every
remaining [[bin]] path resolves.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The digest and the two module counts are computed before the strict typecheck
gate and were reported only in the Ok arm, so a refusal arrived with no
statement of the population it was computed over. Two refusals over different
subjects were indistinguishable in a log, and a silently narrowed subject read
exactly like one that had not narrowed.

The error now carries subject/modules_resolved/modules_excluded rather than a
second emit site racing the first.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Discharges the one landing-obligation row whose instrument dies with the v1
`.dag` authority: regen must run while it still exists.

Two leaves move. `std_realization_schedule.rs` loses 671 lines — the
ScopedWitness* receipt family whose `.dag` authorities this cut deleted, plus
the Rc indirection on FloorWorkerObservation.worker that the shrunk
FloorWorkerIdentity no longer needs. `std_types.rs` gains
`commit_sha_text_holds`, re-homed beside `CommitSha` off the deleted receipt
family: it is a validating check a caller must remember to run, not a
construction wall, and it carries that distinction and its dissolution
condition rather than reading as one.

The generated tree was otherwise already a fixed point: 143 files written,
2 changed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot added a commit that referenced this pull request Sep 2, 2026
… re-cite the live generated-artifact phase (#10054)

* Stop ci_spec asserting a heal-termination guarantee its witness lost two weeks ago

ci_heal_regen_note claimed a non-terminating heal loop is "unwritable while
that witness stays green", citing
generated_artifact_drift_fixed_point_witness_test.witness_committed_is_fixed_point.
611fd02 (#8283, the FLOOR-Y cut, 2026-08-17) deleted that file. The
enforcement went; the sentence claiming it survived, and nothing at the citing
end went red.

Three edits, none of them a silent deletion of the claim:

- gunbc.ci_spec ci_heal_regen_note quotes the old clause, dates its falsity to
  the cut, and states what is actually true now: the corpus-wide fixed point has
  no executing consumer (main_wet is the writer, nothing scheduled invokes it),
  and the only executing instance of the contract is one artifact wide.
- gunbc.rung_drop heal_loop_termination_unenforced files the DESIGN 4b(3)
  declaration retrospectively, with a restoration trigger naming the CAPABILITY
  (a scheduled consumer comparing every committed_generated_artifacts() path
  against artifact_generate and refusing on inequality) rather than a filename.
- test.claim.expectation_frontier_witness ran claim_batch over the SAME deleted
  path under ExpectSuccess. It executes nowhere -- FalsifierRehomedBinWet has
  been dark since falsifier.yml went with the same cut -- so it could not red on
  a missing subject. Re-pointed at test.claim.gitattributes_emit_witness
  witness_committed_matches_emit_holds (undeclared Filesystem.Read, live per-PR
  row), and censused as the eighteenth site in
  gunbc.deleted_cadence_reference_census.

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

* Record that the frontier row was unreachable, not vacuous — measured

claim_batch over the deleted entry REFUSES, typed and located, at exit 2
(BuildBuddy invocation ee22e7c5-6250-446d-a864-c2bf76cad6bd). Under the row's
ExpectSuccess that is a red, so the missing subject was never silently passed
over — it was waiting behind a dark cadence. Consequence runs the other way
from the usual one: restoring a route for FalsifierRehomedBinWet without this
re-point would have reddened the lane on its first run.

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

* Withdraw the rung drop: the capability is live, so re-cite it instead of declaring it lost

The drop I filed was rung DEFLATION -- it declared a guarantee lost while a
required lane still enforces it. Withdrawn; dag/gunbc/rung_drop.dag is now
byte-identical to main.

WHAT ACTUALLY ENFORCES THE FIXED POINT. RequiredCiPhase GeneratedArtifactPhase
(gunbc.required_ci_phase_roster) runs in the BuildLane of the required merge
context. src/v1/stage0/src/generated_artifact_boundary_host.rs asks the
authority for committed_generated_artifact_paths and adjudicates each path's
committed bytes against artifact_generate, refusing on Drifted or Absent. Its
own doc states the identity that makes this a termination argument rather than
a nearby comfort: "this roster and the one main_wet writes are one fold over one
registry". So the phase green on a merge candidate IS the statement that every
path the heal invoke would write is already at its fixed point.

It was enrolled by #9415 and restored to the required roster by #9814
(2026-08-31). So the guarantee came back by a different mechanism while the
citation stayed stale -- the note was wrong in both directions at once.

WHY #9949 DOES NOT CONTRADICT THIS, since I cited it as if it did. The phase
covers the REGISTRY (~35 artifacts, incl. DESIGN.md and ROADMAP.md);
gunbc_rust_source_type_bindings.rs has no variant in generated_artifact_registry
and is not in the stage0 mirror population RegenPhase covers either. That is a
real coverage gap, and it is not this loop's: main_wet writes the registry and
nothing else, so the population the heal touches is the population the phase
adjudicates. My #9949 citation was the loose part, not the phase citation.

Withdrawing the drop also removes the DESIGN.md / docs/design-ledgers.md
projection change, so no regeneration is required by this PR.

The frontier-witness repair and its census row are unaffected and stand.

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

* State the sharper finding in the note itself: a stale citation misses restorations, not just deletions

The damaging half is the second one -- it makes a live guarantee read as absent
to anyone consulting the authority, which is deflation. The note was committing
it before this PR existed, and that is the reason the repair re-cites rather
than deletes.

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

* Record the executed receipt for the re-pointed frontier subject

Running the release claim_batch over the new entry emits
'[expectation-frontier] 1 site(s), 1 dispatch(es) undeclared: Filesystem.Read=1'
and the subject exits 0. Both halves matter: a subject that REFUSED would emit
no receipt and satisfy the arm for the wrong reason, which is exactly how the
previous subject failed. The count stays unpinned; the claim is the receipt's
presence.

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

* Name the class trigger's grain mismatch as pre-existing, and say what bounds it

deleted_cadence_reference_drop's restoration trigger is plural ('each row
above') over a population spanning three cadences, while a row is actually
restored by its own cadence regaining a route -- which is what each
CoverageNotEstablished carries. The eighteenth row is the third member of the
bin_wet_template_coverage subclass, so it joins the mismatch rather than
introducing it, and it is not repaired here.

What bounds the hazard: the plural trigger is prose and nothing folds it. The
executing check reads coverage.lost_with per row, so a returning route flips
exactly the rows it restores and cannot green this one on another cadence's
re-add.

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

* Take ruling A: revert the witness edit, and make the census row actionable

The floor was right to refuse. changed_witness_projection_rows admits a CHANGED
witness whose outcome is RouteGapBeforeVerdict on exactly one arm -- the same
identity carrying a wet terminal admitted against THIS candidate -- and
enrolment in v2.workflow.floor_route_gap is not that. So editing a witness that
executes nowhere reds the floor with changed_witness_blocking=1 and failed=0.
That is this row's own finding turned on its author.

expectation_frontier_witness_test.dag is reverted to its base state; the dead
subject stays until the cadence decision lands.

TWO THINGS THE ROW NOW CARRIES so the next author does not re-derive the night:

1. That the re-point is KNOWN and MEASURED -- gitattributes_emit_witness
   witness_committed_matches_emit_holds emits the receipt and exits 0 -- and is
   unlandable for the floor reason above, not because it is wrong. Without that
   the un-re-pointed subject reads as un-analysed. It also records the ordering
   the wall forces: whoever restores the route must land the re-point in the
   SAME change, or the lane reds on its first run.

2. Its own coverage, frontier_wet_terminal_coverage, rather than the shared
   bin_wet_template_coverage. The shared trigger is a ROUTE FLAG, and the gap is
   measurable: witness_cadence_has_scheduled_route answering true would retire
   it while this identity still had no wet terminal and the re-point still could
   not land. The new trigger names what must be true OF THIS IDENTITY. The two
   rows on the shared coverage keep it; the pre-existing plural-trigger mismatch
   is named, not repaired.

Not done, deliberately: enrolling this identity in LocalRepoWetLane. That arm
claims effects confined to a temp dir and a local git repo; this witness spawns
a corpus-wide child claim_batch, so enrolling it would make a route claim FALSE
that currently has teeth -- a DESIGN section 5 escape hatch, not a fix.

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

* §4c: the heal regen note was dead prose in a String — convert it to a // block

review 58723 (REQUEST_CHANGES) is correct and I verified it rather than took it:
ci_heal_regen_note occurs EXACTLY ONCE in the repository, its own declaration.
Nothing reads it. That is the §4c defect verbatim -- "an ordinary String
declaration whose sole purpose is commentary is misplaced or dead data" -- and
by expanding the note I had made a pre-existing instance materially worse.

Converted to a standalone leading // block attached to a module-scope
declaration, gunbc_ci_heal_regen_invoke, which is the form §4c's initial .dag
realization admits and the form this file already uses in 631 other places. The
content is unchanged in substance: history, the enforcing symbol, the grain
identity, and the two population boundaries.

Net effect on the authority is subtractive: ci_spec.dag now carries one FEWER
data declaration than before this PR, not one more.

Checked before deleting: no // comment anywhere cites ci_heal_regen_note, so
removing the declaration cannot orphan a citation that
test.claim.prose_citation_census would catch. The replacement block
deliberately cites no *_note name for the same reason.

Not swept: the other six _note: String declarations in this file. They are
pre-existing and out of this PR's scope.

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

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 5, 2026
… repin the denominator

Reading every row either PR touched on the merged tree -- rather than trusting
the clean auto-merge -- turned up an error in my own worked-examples table.

 #10529's srv3 row names a live successor, srv3_ensure_directory_owned_by_current_user
(gunbc.host_effect_realize), so srv3_chown_directory_to_current_user was not
plain "discharged" as my table said: it was RENAMED AND CLIMBED at once. That is
a fourth cause a two-way discharge/rename split cannot express, and calling it
discharged loses the successor a reader needs to find. The table now carries all
four causes: dissolution, file deletion upstream of the name, bare rename, and
rename-plus-climb.

The denominator moved exactly as predicted. Re-derived on the merged tree it is
180 rows / 43 closed / ~137 live, against 41/~139 one merge earlier; #10529
striking two more SS1.C rows through is the whole difference. The banner now says
so, because a split that moves within one merge of being written is the argument
for naming the recipe rather than a bookkeeping detail. Measurement is pinned to
the merge of 70925ee with origin/main 16a702e.

Controls re-run on the merged tree, not carried forward: the four
bash_nearest_ancestor_locate_* call sites still stand and #7978 is an ancestor of
the merged HEAD; ci.yml is still absent with witnesses.yml present and #8283 an
ancestor; git_fetch_script is still absent while git_fetch_no_tags_shell and
git_fetch_prune_shell exist, so the rename example still discriminates. Diff is
still model-side prose only -- no .rs, no seed growth.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013GCBVTWARwTLkAfVWaGfKA
briansrls pushed a commit that referenced this pull request Sep 5, 2026
… flag the census's dead-ci.yml population (#10537)

* Correct the stale ci_floor_peak rows and flag the census's dead-ci.yml population

gunbc.plans.shell_emission_model's Phase 1 PARTIAL row still said While emit's
one production consumer, ci_floor_peak_emit, has cond and body "still raw shell
strings". That was true when written and is stale: ecbd086 (#7978, shell ->
dag Phase 1 cgroup vertical, 2026-08-08, ancestor of origin/main) replaced both
leaves, and the membership assign with them, with derived text from a typed
NearestAncestorContaining (std.path_intent) plus extdeps.linux.proc_self_cgroup
membership, lowered through bash_orch_if / bash_proc_self_cgroup, refusing with
a located marker rather than widening. git log -S on both
bash_nearest_ancestor_locate_cond_command and ci_floor_peak_nearest_ancestor_spec,
scoped to that file, returns exactly that commit as first introduction.

The correction carries the residue forward rather than reading as completion:
the peak calibration leaves on the same pipeline and the runtime-scan transport
in bash_membership_assign_from_source are still raw String Run.command values,
declared Phase 2 typed filesystem observation by the module itself.

Three census rows in docs/plans/shell-to-dag-residual-census-and-arc-completion.md
carried the same stale claim -- the SS1.A "concat-built floor-peak/cgroup runners"
row, the SS4.E already-on-emit row, and the SS4.J Phase-1 dispatch row that still
listed the two leaves as unassigned open work. That last one is what dispatched a
lane onto discharged work.

Sweeping the class turned up a larger root cause, filed as a banner rather than
silently truncated: .github/workflows/ci.yml was deleted by 611fd02 (#8283,
FLOOR-Y cutover), CI is now the witnesses.yml emission from
gunbc.witness_floor_workflow, and this census mentions none of that while still
naming ci.yml drift+parse as its byte-oracle in four places. A symbol-existence
check over the SS4.J dispatch roster found ~20 named production symbols with no
declaration anywhere in the .dag corpus. The banner states the denominator (180
data rows, 41 already closed, ~139 asserting live state) and states explicitly
what it does NOT establish: absence of a name is not discharge, since a rename
looks identical -- git_fetch_script is gone while git_fetch_no_tags_shell and
git_fetch_prune_shell exist. Per-row adjudication needs its own lane.

Model-side prose only; no seed growth, no .rs.

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

* Name the instrument behind the banner's counts, so the banner is not the next stale row

The staleness banner cited bare counts (180 data rows / 41 closed / ~139 live)
and a ~20-name absent-symbol list. Transcribed numbers under a dated claim are
exactly the defect the banner is about, one layer up: nothing re-derives them,
so they rot without anyone touching either end.

The banner now carries the two checks that produce them, verified to reproduce
their stated output as printed at 70925ee, and says to run them rather than
read them. It also states the second check's raw output honestly -- 50
candidates, of which the ~20 production symbols are what survives discarding
module names, the commit-sha and fn-fragment spellings the banner itself
introduced, and already-struck rows -- so the gap between "50 out" and "20
listed" cannot be mistaken for a miscount. The ci.yml deletion is the one claim
that is not count-shaped and its own one-line derivation is given.

The dispatch prohibition is unchanged and deliberate: a banner that describes
staleness while still permitting dispatch off the rows is a documented hazard
with no refusal.

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

* Turn the banner's absent-symbol list into a demonstration, and pin the denominator to its head

The banner asserted that absence of a name is not discharge because a rename
looks identical. It now demonstrates it, with six names that already have
verdicts on main and do not all point the same way:

  srv3_chown_directory_to_current_user  discharged        61bf47b (#8590)
  host_build_cache_provision_script     discharged        40f2fb6 (#8825)
  four host_hygiene_reap_*_body         files deleted     ffa16a5 (#8583)
  git_fetch_script                      RENAME, not gone  (unadjudicated)

Three causes, one grep signature. The host_hygiene row is the sharpest: the
commit that discharges those four names does not mention them, so the evidence
is not reachable from the symbol at all -- which is precisely why the per-row
lane cannot be done by symbol search. All four commits are ancestors of main, so
the table is head-safe independent of the SS1.C corrections landing separately in
 #10529.

The denominator now says it was measured at 70925ee and is valid only there:
any later edit that strikes a row through changes what the closed-marker grep
counts, so the 180/41/~139 split moves and must be re-derived rather than quoted.
The demonstration table sits inside the blockquote, so it does not itself perturb
the row count -- re-derived at 180 after the edit.

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

* Re-derive on the merged tree: correct a worked example reading found, repin the denominator

Reading every row either PR touched on the merged tree -- rather than trusting
the clean auto-merge -- turned up an error in my own worked-examples table.

 #10529's srv3 row names a live successor, srv3_ensure_directory_owned_by_current_user
(gunbc.host_effect_realize), so srv3_chown_directory_to_current_user was not
plain "discharged" as my table said: it was RENAMED AND CLIMBED at once. That is
a fourth cause a two-way discharge/rename split cannot express, and calling it
discharged loses the successor a reader needs to find. The table now carries all
four causes: dissolution, file deletion upstream of the name, bare rename, and
rename-plus-climb.

The denominator moved exactly as predicted. Re-derived on the merged tree it is
180 rows / 43 closed / ~137 live, against 41/~139 one merge earlier; #10529
striking two more SS1.C rows through is the whole difference. The banner now says
so, because a split that moves within one merge of being written is the argument
for naming the recipe rather than a bookkeeping detail. Measurement is pinned to
the merge of 70925ee with origin/main 16a702e.

Controls re-run on the merged tree, not carried forward: the four
bash_nearest_ancestor_locate_* call sites still stand and #7978 is an ancestor of
the merged HEAD; ci.yml is still absent with witnesses.yml present and #8283 an
ancestor; git_fetch_script is still absent while git_fetch_no_tags_shell and
git_fetch_prune_shell exist, so the rename example still discriminates. Diff is
still model-side prose only -- no .rs, no seed growth.

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

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 5, 2026
…ce August

The rows did not take effect and the seed says why, in a note I should have
read before adding them rather than after. std_witness_admission records the
per-cadence realization gate: of ten WitnessConsumerCadence arms, exactly four
have a live scheduled route, and BinWitnessWet is NOT one of them --
"falsifier.yml, the workflow that scheduled all five, was deleted at
611fd02 (2026-08-15, #8283), and no replacement executor exists."

So enrolling there is specification-without-execution by construction, which is
what the floor_prepared_subject_exclusions comment already recorded another
author discovering and reverting. I have now reproduced that experiment and it
came out the same way. Leaving the rows would leave a roster claim with no
consumer standing as though it were coverage.

What the same note establishes is that my ORIGINAL choice was the right one and
the bin_wet addition was the wrong correction: LocalRepoWetLane returns TRUE,
is "the one arm added with its executor rather than before it", and its stated
scope is exactly this witness -- "witnesses whose real effects are confined to
a temporary directory and a local git repository, which the required lane can
run in its own checkout". Its completeness join is at identity grain in both
directions and its liveness check refuses LocalRepoWetExecutorAbsent, which is
why a member it cannot run reds the lane rather than quietly widening it.

That leaves the enrollment as it was two heads ago -- exclusion row classified
LocalRepoWetLane, five rows on the schedule -- and the four identities still
evaluating hermetically and gapping on Dir. I do not know why, I have been
wrong about this lane twice, and I said I would stop rather than try a third
model. Stopping here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RvMEJFpYsy55NRdJ1Az4Vd
gunbai-bot Bot pushed a commit that referenced this pull request Sep 5, 2026
§4.I — ci_native_cache_root_toolchain_segment_command
  DELETED #7436 (003d960). CASE 1 dissolution — toolchain segment
  computation reordered after setup-rust-toolchain; fallback table entry
  struck through as RESOLVED.

§4.J.A — ci_floor_stamp_merge_admission_script
  All three raw leaves (ci_floor_stamp_ambient_exit_command,
  ci_floor_stamp_root_command, merge_admission_stamp_command) DELETED
  #7522 (87a4af3). CASE 1 dissolution. 'PARTIAL #7293' status stale.

§4.J.B — ci_floor_materialization_receipt_gate_script,
  ci_floor_resolve_receipt_gate_script
  DELETED #7470 (b01cdf4). CASE 1 dissolution — WalkPlan success
  stages finalization dissolved both receipt gates.

§4.J.C (ci_spec.dag table):
  - gunbc_ci_floor_only_script DELETED #9252 — CASE 1
  - ci_regen_floor_skip_shortcut_script DELETED #8406 — CASE 1
  - gunbc_ci_regen_floor_only_script DELETED #8406 — CASE 1
  - scheduler_invoke/scheduler_invoke_with DELETED #9252 — CASE 1
  - git_fetch_script RENAMED #6833 — CASE 3 (successor:
    git_fetch_no_tags_shell / git_fetch_prune_shell)

§4.J.D (ownership table):
  - Merge-admission row: all three raw leaves struck #7522 (CLOSED)
  - CI materialization row: both receipt gates struck #7470 (CLOSED)
  - CI-spec row: stale symbols struck through individually
  - Already-routed row: ci_selection_control_script #8283,
    gunbc_ci_run_script #9252, ci_regen_ensure_rustfmt_path_script
    #8406 (and 11 rustfmt raw leaves) struck through
  - Runtime terminal row: host_effect_plan_placeholder_effect
    DELETED #10509
  - Deferred srv3 row: srv3_chown_directory_to_current_user struck
    #8796 (ref §4.D), all 4 host_hygiene_reap_*_body + liveness body
    struck #8583 (ref §4.A)

All deletion commits verified as ancestors of origin/main ✅.

Part of #10537's per-row adjudication program.
gunbai-bot Bot pushed a commit that referenced this pull request Sep 5, 2026
…t Rust door's scaffold trigger at capability grain

The direct Rust door's manifest scaffold declared its exit as
`feature:medium_structure_containment`. That lens was deleted in #6831 --
recorded by v2.std.compilers.target_model target_text_carrier_scaffold_note and
by gunbc.plans.self_applying_lenses, neither of which any trigger citing it
could see. A trigger retired by a mechanism that no longer exists is retired by
nothing, so the scaffold read as tracked debt with a named exit while being
permanent.

The class is filed as
gunbc.recurring_failure_mode.dissolution_trigger_cites_a_mechanism_that_is_later_deleted.
It is its own row rather than a receipt on either neighbour because the
invalidation happens AFTER authoring and by a THIRD PARTY's edit:
restoration_promise_names_a_route_that_does_not_exist covers a route that never
existed, trigger_satisfied_before_the_row_was_written covers a trigger already
true when written, and neither origin arm finds a citation that was correct and
was later orphaned. The deleting lane cannot see it either, since a trigger
naming a mechanism is not one of its consumers.

The specimen's own trigger is rewritten here rather than only described: it now
names the capability -- a Cargo manifest authority producing the manifest
structurally through the target-model / serialize_target path -- and states,
measured, that no TOML model exists under extdeps/formats or extdeps/languages,
so the stall waits on an absent capability rather than on a scheduled edit.

A second receipt lands on restoration_promise_names_a_route_that_does_not_exist:
the weak self-host behavioral receipt (test.claim.self_host_logic_behavioral_witness,
DESIGN section 7 equivalence-by-execution with an --inject-fault RED) is
classified onto FalsifierSelfHostWet, whose sole scheduled executor falsifier.yml
was deleted at 611fd02 (#8283). Every carrier is individually honest about the
dark cadence; only the join with docs/plans/v2-self-hosting.md citing that
receipt as Wave 1 gate coverage is false, which is why it belongs on that row
rather than in a new one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BaBy8LXsmUnG6ARJHJGJ3K
gunbai-bot Bot added a commit that referenced this pull request Sep 5, 2026
…t Rust door's scaffold trigger at capability grain (#10577)

* File the trigger-cites-a-deleted-mechanism class, and state the direct Rust door's scaffold trigger at capability grain

The direct Rust door's manifest scaffold declared its exit as
`feature:medium_structure_containment`. That lens was deleted in #6831 --
recorded by v2.std.compilers.target_model target_text_carrier_scaffold_note and
by gunbc.plans.self_applying_lenses, neither of which any trigger citing it
could see. A trigger retired by a mechanism that no longer exists is retired by
nothing, so the scaffold read as tracked debt with a named exit while being
permanent.

The class is filed as
gunbc.recurring_failure_mode.dissolution_trigger_cites_a_mechanism_that_is_later_deleted.
It is its own row rather than a receipt on either neighbour because the
invalidation happens AFTER authoring and by a THIRD PARTY's edit:
restoration_promise_names_a_route_that_does_not_exist covers a route that never
existed, trigger_satisfied_before_the_row_was_written covers a trigger already
true when written, and neither origin arm finds a citation that was correct and
was later orphaned. The deleting lane cannot see it either, since a trigger
naming a mechanism is not one of its consumers.

The specimen's own trigger is rewritten here rather than only described: it now
names the capability -- a Cargo manifest authority producing the manifest
structurally through the target-model / serialize_target path -- and states,
measured, that no TOML model exists under extdeps/formats or extdeps/languages,
so the stall waits on an absent capability rather than on a scheduled edit.

A second receipt lands on restoration_promise_names_a_route_that_does_not_exist:
the weak self-host behavioral receipt (test.claim.self_host_logic_behavioral_witness,
DESIGN section 7 equivalence-by-execution with an --inject-fault RED) is
classified onto FalsifierSelfHostWet, whose sole scheduled executor falsifier.yml
was deleted at 611fd02 (#8283). Every carrier is individually honest about the
dark cadence; only the join with docs/plans/v2-self-hosting.md citing that
receipt as Wave 1 gate coverage is false, which is why it belongs on that row
rather than in a new one.

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

* chore: regenerate drifted generated artifacts (ci auto-heal)

Ledger-Repair-Judged: docs/design-failure-modes.md
Ledger-Rows-Repaired: docs/design-failure-modes.md restoration_promise_names_a_route_that_does_not_exist
Ledger-Rows-Repaired: docs/design-failure-modes.md dissolution_trigger_cites_a_mechanism_that_is_later_deleted
Ledger-Repair-Judged: docs/design-rung-drops.md

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
briansrls added a commit that referenced this pull request Sep 5, 2026
….E, §4.I, §4.J (#10576)

* Correct §4.A hygiene-reaper row: CASE 2 — four host_hygiene_reap_*_body symbols deleted by #8583

The §4.A row at L379 described host_hygiene_reaper_script.dag's 4
body symbols as A5-deferred. The file was deleted by ffa16a5
(#8583, Migrate host-hygiene reaper and liveness onto typed observation)
and the construction was migrated to typed host_hygiene_reaper_observe.dag
/ host_hygiene_reaper_remediate.dag / host_hygiene_liveness_observe.dag.
No direct successor body names exist — CASE 2 (file deletion upstream)
with hybrid CASE 1 (body names dissolved).

Verification:
- ffa16a5 is ancestor of origin/main ✅
- host_hygiene_reaper_script.dag: D in #8583's diff
- zero files define host_hygiene_reap_install_units_body et al.
- observe/remediate files present at dag/gunbc/host/

Part of #10537's per-row adjudication program.

* Correct §4.D srv3_chown_directory_to_current_user: CASE 4 — renamed AND climbed

The row at §4.D L436 listed srv3_chown_directory_to_current_user
as A5-deferred (srv3). It was actually renamed AND climbed by
20ad5b3 (#8796): successor is
gunbc.host_effect_realize.srv3_ensure_directory_owned_by_current_user.
New name has a stronger guarantee (readback-based, not chown exit-status
based).

This is CASE 4 (rename plus climb) — distinct from CASE 1 (dissolution)
because the construction did not disappear; it acquired a better name
and a stronger guarantee.

Verification:
- 20ad5b3 is ancestor of origin/main ✅
- srv3_chown_directory_to_current_user: 0 declaration files
- srv3_ensure_directory_owned_by_current_user: 2 declaration files

Part of #10537's per-row adjudication program.

* Correct §4.E: 4 stale foreign-executor rows

Four symbols claimed as 'already on emit' are no longer present in the
corpus. Each is struck through with its deletion commit:

1. ci_selection_control_script — DELETED by 611fd02 (#8283, CI floor cut).
   CASE 1/2: the ci.yml file was deleted and its selection-control script
   dissolved with it. Successor workflow is witnesses.yml via
   gunbc.witness_floor_workflow.

2. gunbc_ci_run_script — DELETED by 489346f (#9252, plan/walk CLI delete).
   CASE 1: the gunbc ci verb was deleted, taking its run script.

3. ci_regen_ensure_rustfmt_path_script — DELETED by 3b431f3 (#8406,
   REGEN ROOT CUT). CASE 1: regen_stage0 root deleted; rustfmt path
   script was zero-consumer machinery.

4. expected_live_deploy_retract_script — DELETED by d409b75 (#7909,
   Phase A release identity refactor). CASE 1: recategorized to
   runtime-present, then dissolved.

All four deletion commits are ancestors of origin/main ✅.

Part of #10537's per-row adjudication program.

* Correct §4.I, §4.J, §4.D ownership table: 18+ stale symbols

§4.I — ci_native_cache_root_toolchain_segment_command
  DELETED #7436 (003d960). CASE 1 dissolution — toolchain segment
  computation reordered after setup-rust-toolchain; fallback table entry
  struck through as RESOLVED.

§4.J.A — ci_floor_stamp_merge_admission_script
  All three raw leaves (ci_floor_stamp_ambient_exit_command,
  ci_floor_stamp_root_command, merge_admission_stamp_command) DELETED
  #7522 (87a4af3). CASE 1 dissolution. 'PARTIAL #7293' status stale.

§4.J.B — ci_floor_materialization_receipt_gate_script,
  ci_floor_resolve_receipt_gate_script
  DELETED #7470 (b01cdf4). CASE 1 dissolution — WalkPlan success
  stages finalization dissolved both receipt gates.

§4.J.C (ci_spec.dag table):
  - gunbc_ci_floor_only_script DELETED #9252 — CASE 1
  - ci_regen_floor_skip_shortcut_script DELETED #8406 — CASE 1
  - gunbc_ci_regen_floor_only_script DELETED #8406 — CASE 1
  - scheduler_invoke/scheduler_invoke_with DELETED #9252 — CASE 1
  - git_fetch_script RENAMED #6833 — CASE 3 (successor:
    git_fetch_no_tags_shell / git_fetch_prune_shell)

§4.J.D (ownership table):
  - Merge-admission row: all three raw leaves struck #7522 (CLOSED)
  - CI materialization row: both receipt gates struck #7470 (CLOSED)
  - CI-spec row: stale symbols struck through individually
  - Already-routed row: ci_selection_control_script #8283,
    gunbc_ci_run_script #9252, ci_regen_ensure_rustfmt_path_script
    #8406 (and 11 rustfmt raw leaves) struck through
  - Runtime terminal row: host_effect_plan_placeholder_effect
    DELETED #10509
  - Deferred srv3 row: srv3_chown_directory_to_current_user struck
    #8796 (ref §4.D), all 4 host_hygiene_reap_*_body + liveness body
    struck #8583 (ref §4.A)

All deletion commits verified as ancestors of origin/main ✅.

Part of #10537's per-row adjudication program.

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
briansrls pushed a commit that referenced this pull request Sep 5, 2026
…r, and the production path is unmeasured on all 28 (#10545)

* Step 0 calibration: what a corpus run's silence about a resolution arm is not

std.reference_binding_observation pays to preserve six typed index-build
refusals as distinct arms of StructuralBindingResolution, and its header says
they are "never collapsed". This measures whether that preservation survives to
a consumer, on controlled fixtures, BEFORE the namespace cut's corpus run cites
the instrument -- because a cell that never fires and a cell that fires and
finds nothing are indistinguishable in a corpus report, and only a calibration
run separates them.

The matrix is 4 observation kinds x 7 resolution arms, and its axes come from
the vocabulary std DECLARES, bound by the total matches arm_of_resolution and
kind_of_observation: an arm added upstream makes this module fail to compile
rather than silently shrink the denominator. A denominator derived from the
cases the instrument managed to produce would report itself complete by
construction.

Each cell carries three separately-sourced facts rather than one verdict word:
a four-valued consumer standing, the measured provenance distinguishability,
and a four-valued production standing. The last is UNSUPPORTED BY THIS ROUTE
for every cell with the missing input named -- this census hands the consumer a
constructed resolution, so it never executes the production path and obtains no
evidence about producibility. That is a statement about the route, not about
the world, and it is deliberately weaker than "unreachable".

The measured result: only the four StructuralBindingResolved cells are
provenance-distinguished. The other 24 render byte-identically to each other
AND to a resolved-but-non-matching comparator, because
binding_outcome_from_resolution maps every non-Resolved arm to Absent and each
consumer arm maps Absent to the same refused(capability, failure) as a
structural non-match. The instrument writes the full matrix and then refuses --
the stopped-line audit of DESIGN section 5.

The controls live in the witness corpus rather than beside the instrument,
because test fn rows under dag/gunbc/instruments are discovered by nothing and
an inert lens is itself a lie.

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

* The refusal path is the oracle; 28 was a measurement compared to itself

no_cell_is_sound_and_the_instrument_refuses asserted that exactly 28 cells were
unsound, which is a count standing where a check belongs. Two things wrong with
it, and the second is worse.

It has no independent referent: 28 is this run's own measurement of the live
population compared against itself, so automating its update would collapse the
assertion to measure() == measure(). Section 5 admits a numeric literal only
when it is grounded in a fixture, an external authority, a policy budget, or a
monotone debt contract, and this was none of them.

And it points the wrong way. A repair of ONE collapsed cell would have failed
this test with "expected 28" -- reporting a genuine improvement as a regression
and telling the next author to restore the defect to get green.

What must stay true is that the instrument's refusal path is REACHED, which is
a property of the refusal rather than of how much is currently broken. The
specific collapse is already carried by the discriminating controls beside it,
where a repair makes exactly the right row go red and nothing else moves.

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

* A defect-asserting control must say so where the reader meets it

Two of the five controls assert the COLLAPSE rather than an invariant, and that
is deliberate: a repair makes exactly the right row go red. But the only place
that was written down was a comment on a different function further down the
file, and nobody arrives at a control by reading the module top to bottom. They
arrive at a red test name in a CI log, where
"a_typed_index_refusal_is_not_distinguished_from_a_structural_non_match" reads
like a broken invariant and the obvious repair is to make the two renders
differ -- which is precisely what the real fix would already have done. The
future author would restore the defect to get green.

So each of the two now carries its own disposition on its own declaration:
going red means the defect was repaired, which is success; delete the row, do
not restore the behaviour. The six-arm control also states what a PARTIAL
repair means, because it goes red then too and that is still progress.

This is the count-oracle failure one level up. Both are true signals the reader
misclassifies, and in both cases the fix is to move the meaning to where the
signal is read rather than to weaken the signal.

Also records why the surviving == 28 in the denominator control is not the
literal that was just removed: 4 and 7 are the arities of two std types, an
authority this module does not own and cannot silently drift from, since the
exhaustive matches make an upstream change fail compilation. The removed
literal was this run's own measurement of how much is broken, compared against
itself.

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

* Three gaps in what the instrument guarantees about itself

The measured matrix and the production-gap separation were right. What was
wrong was every claim this file made about its OWN evidence, and all three
holes are the class the instrument exists to detect, turned inward.

C2, the worst: consumer_standing was a CONSTANT FUNCTION. It returned
CalibrationDemonstrated unconditionally with only the conditions string
varying, so three arms of a four-armed vocabulary were unconstructible on this
route and the field carried zero information -- a fixture pinned at an
absorbing extreme, where admission cannot fail because the input cannot differ.
And cell_is_sound never read it: a cell with RefusedOrIncomplete consumer
standing was SOUND as long as its production standing was demonstrated.
Descriptive data standing where an admission obligation belonged. The matrix
stays red today only because the production axis is unsupported, so repairing
that axis would have made the consumer axis silently admit everything.

consumer_standing now DERIVES from structure that can differ -- the
demonstration's three clauses read literally, with clause two (did the case
reach the intended judging stage) checked by round-tripping the constructed
observation and resolution through the same total matches that bind the
denominator. A parameterised form exists so the RED is authorable at all, and
two of the three non-demonstrated arms are now reached by executing controls.
cell_is_sound requires both standings.

C1: the denominator control proved a COUNT, not an identity join.
calibration_cells folds one traversal list across the other, so its cardinality
is a product, and the round-trip fold checks that each visited element relabels
to itself -- which a duplicate satisfies exactly as well as a unique element.
Replacing IndexModulePathRefusedArm with a second IndexTransportRefusedArm
leaves lengths at 4/7/28 and every control green while one column is measured
twice and another never. Verified by executing that exact sabotage: the old
control stayed true, the new distinctness control went false, and green
returned on restore.

The verdict now consumes traversal integrity too, because an empty or short
traversal has no unsound cell and would otherwise exit success -- "nothing was
measured" and "nothing was wrong" arriving at the same exit.

C3: the refusal control asserted a precondition of the decision, not the
decision. Factoring calibration_verdict out was necessary and is not
sufficient, and the residual gap is stated rather than papered over: replacing
the report's post-write refusal with ExitSuccess leaves every control here
green. No witness can cover it -- the report performs a host effect and the
floor's hermetic envelope refuses those, so such a witness would be counted
executed while its assertion never ran. Declared as a boundary with a
capability-shaped trigger, and the control is renamed to the verdict it checks.

Also synchronises two scope sentences: the opening claimed to measure what the
production path can produce while the body correctly says it does not, and "no
producer anywhere" is scoped to the production route, since this instrument
itself constructs StructuralBindingProductionRefused.

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

* C3 closed by execution: the wet route existed, so the gap was mine not the floor's

I declared a §4b boundary and named a missing capability: a witness-executable
route that can run an effectful entry point under the floor. That capability
already exists, with thirteen precedents in the same directory. A trigger
naming an existing capability is a drop that never ends, because a drop is
retired by its trigger and by nothing else -- so the declaration would have
been permanent by construction.

My barrier was real and was not a ceiling. Hermetic discovery does refuse host
effects, and a witness swept into it would be counted executed while its
assertion never ran. What I missed is the documented second route: exclusion
from hermetic discovery plus enrolment in a wet lane, exactly as
test.claim.commit_writer_heal_admission_real_execution does.

So the gap is closed rather than declared. A new wet witness calls the real
provenance_calibration_report against a real temp path and asserts the returned
ProcessExit. To make the arm two-sided through the real path, the report is
parameterised on its cell population -- computing it inside meant the only
outcome a wet witness could observe was refusal, which a report that refused
unconditionally would satisfy. The measured matrix must refuse; a constructed
sound matrix must succeed. Two further arms: the refusing report must still
have WRITTEN the matrix, since a refusal with no file is a different and worse
outcome than the stopped-line audit claims and is invisible in the ProcessExit;
and the empty-out-path guard refuses BEFORE any write, so "did it refuse" alone
could be satisfied without reaching the decision at all.

VERIFIED BY MAKING THE SUBSTITUTION. Replacing the post-write refusal with
ExitSuccess: the hermetic control stayed true and the wet witness went false.
That is the sentence that named the gap, now flipped, and running the hermetic
control on the sabotaged tree is what proves it could not have seen it.
Restored byte-identical, green returned.

Enrolled in the identity-grain local-repo wet lane rather than the dark bin-wet
class, deliberately: the witness exists because a wall that stops executing
must refuse rather than read as covered, and enrolling it somewhere it could be
silently absent would reproduce its own subject. Its admitted effect is named
as its own row rather than folded into a neighbour -- it builds no repository,
unlike the throwaway-repo class, and it writes, unlike the read-only probe
class.

Also adds two import lists flagged in review. Both claims were that name
resolution would fail; it does not, and the file carries zero diagnostics with
or without them -- measured both ways. They land for peer consistency, not
because the stated defect was real.

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

* Five: a helper that claimed a judgement it never ran, and two degenerate passes

N1 is the instrument's own subject one layer up, and it is the one I would not
have found. consumer_standing_for round-tripped the kind and the arm and NEVER
CALLED assess_reference_binding_observation, while its own conditions string
said the case had been "judged by" it. The matrix was not wrong today, because
the only caller supplied consistent arguments -- which is exactly how this
class survives: a derivation asserting what it did not perform is invisible
while its inputs stay well-formed.

It now takes ONE observation and reads the resolution OUT of it, so the judged
case and the checked arm cannot be two different things; the old signature took
both and could be handed a matched pair by convention alone. Demonstrated
standing is reached only after the real consumer runs, and carries that call's
attributed result. The discriminating RED is same-kind/different-embedded-arm,
which the old signature could not detect at all -- without it the change would
be a shape no input can falsify.

C1 and N2 are one shape twice: an assertion true at the absorbing extreme of
its own input.

C1: traversal_is_complete counted DISTINCT keys, which is coverage, and never
counted the list, which is uniqueness. 28 cells plus a duplicate has 28
distinct keys and passed while the population held 29. This became reachable
through the C3 repair -- parameterising the report made the population an INPUT
a caller shapes, so a duplicate now arrives through the parameter rather than
through the traversal lists the other conjuncts guard. Length == distinct ==
declared is the identity join; either count alone is a count.

N2: the write arm asserted Filesystem.Read(...).success, and a read of a
ZERO-BYTE file succeeds -- so a report that created the file and wrote nothing
satisfied the arm whose entire purpose is that the operator gets the evidence
before the line stops. It now compares the payload to calibration_body_of over
the SAME cells, using the existing renderer rather than a second authority, and
a third arm rejects a right-shape wrong-population payload.

Verified by the adjudicator's own falsifier: emptying the write content while
keeping the verdict left all three prior wet arms GREEN and reddened both
content arms. Restored byte-identical, green returned.

Two scope sentences: "no module anywhere constructs
StructuralBindingProductionRefused" was false unscoped -- this module
constructs it -- and is now scoped to the production route; and the empty-out
control no longer claims to observe the absence of a write, which its Boolean
cannot establish since no path is supplied for it to read.

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

* The wet witness was enrolled in one roster and executed by neither

The floor refused, correctly, and named the defect exactly: four identities
"never reached their subject: the hermetic route has no arm for Dir (operation
declares no mock_response)". My wet witnesses were still being evaluated on the
HERMETIC route, where shell.Mktemp.Dir cannot run. The fifth arm did not gap
because it builds no temp directory.

That refusal is the floor doing the thing this PR is about: it did not count
four unreachable claims as covered, it stopped and said which subject was never
reached.

The cause is a deviation I made deliberately and did not verify. The route I
was pointed at enrolls a wet witness in TWO rosters -- bin_witness_wet_entries,
the per-PR executing consumer, and the local-repo wet schedule, which joins
observed terminals back at identity grain. I chose the schedule alone because
the identity-grain join is the stronger property, and treated the other as an
alternative rather than as the half that actually executes. Measured against
the working precedent: it carries 4 bin_wet rows, I carried 0.

So the enrollment asserted an executing consumer it did not have, which is
specification-without-execution -- and the seed already records another author
making the same mistake on these rosters and reverting it. Both halves now
match the precedent.

What this does not establish: that the rows take effect. That is a claim about
CI mechanics I have now been wrong about twice, and it is settled by the next
floor run rather than by this commit message.

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

* Revert the bin_wet rows: that cadence has no executor and has not since August

The rows did not take effect and the seed says why, in a note I should have
read before adding them rather than after. std_witness_admission records the
per-cadence realization gate: of ten WitnessConsumerCadence arms, exactly four
have a live scheduled route, and BinWitnessWet is NOT one of them --
"falsifier.yml, the workflow that scheduled all five, was deleted at
611fd02 (2026-08-15, #8283), and no replacement executor exists."

So enrolling there is specification-without-execution by construction, which is
what the floor_prepared_subject_exclusions comment already recorded another
author discovering and reverting. I have now reproduced that experiment and it
came out the same way. Leaving the rows would leave a roster claim with no
consumer standing as though it were coverage.

What the same note establishes is that my ORIGINAL choice was the right one and
the bin_wet addition was the wrong correction: LocalRepoWetLane returns TRUE,
is "the one arm added with its executor rather than before it", and its stated
scope is exactly this witness -- "witnesses whose real effects are confined to
a temporary directory and a local git repository, which the required lane can
run in its own checkout". Its completeness join is at identity grain in both
directions and its liveness check refuses LocalRepoWetExecutorAbsent, which is
why a member it cannot run reds the lane rather than quietly widening it.

That leaves the enrollment as it was two heads ago -- exclusion row classified
LocalRepoWetLane, five rows on the schedule -- and the four identities still
evaluating hermetically and gapping on Dir. I do not know why, I have been
wrong about this lane twice, and I said I would stop rather than try a third
model. Stopping here.

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

* The floor's prepared subject consults a Rust literal and nothing else

Three CI cycles changed nothing because both rosters I edited were the right
rosters for the wrong consumer. There are two exclusion mechanisms with
different consumers: witness_exclusion_frontier, projected from .dag by
cli_run/witness_gates.rs, governs DISCOVERY SELECTION; the FLOOR PREPARED
SUBJECT consults floor_prepared_subject_exclusions and nothing else, as that
function's own comment has said since someone else learned it the same way. The
identities were gapping in the prepared subject.

The bin_witness_wet_entries detour was the same mistake with a worse cause:
that cadence is one of five whose executor was deleted with falsifier.yml at
611fd02, so the rows were dead on arrival. Reverted last commit. Worth
recording that the precedent I matched against is itself in that dead cadence
-- an excluded witness enrolled in a lane that does not run, which reads as
covered and is not.

This entry is the OPPOSITE of the two already in the list and its comment says
so rather than copying them. Those two are excluded BECAUSE they have no wet
consumer: the exclusion buys a green floor, the claims sit at UNEXECUTED-IN-CI,
and they say so plainly. This one is excluded so that it CAN be executed --
its five functions are on the local-repo wet schedule, whose cadence is one of
the four with a live scheduled route, and whose lane joins roster to terminal
receipts at identity grain in both directions and refuses
LocalRepoWetExecutorAbsent when a nonempty schedule meets an uninvoked
executor. A member it cannot run reds rather than reading as covered.

Admitted against the v1 freeze on the PURPOSE test: this is the executing
evidence for the calibration instrument's refusal path, and without it that
evidence cannot run at all. Mocking is not the alternative -- the witness
exists to prove the REAL report writes the REAL matrix before refusing, and a
mocked write asserts against the mock. One string and a comment; no new
declarations, no exported surface.

Seed verified by execution, with a discriminating control: cargo check
-p v1-compiler exits 0 and reports Finished; cargo check -Z
definitely-not-a-real-flag exits 101 and is refused. Whether the entry takes
effect is settled by the next floor run, not by this message.

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

* A test with no host effect does not belong in a wet witness

The seed exclusion worked: the four Dir route-gaps are gone. The floor then
refused on a narrower and different cause, which I read from the published
measurement receipt rather than from logs:

  cause=ChangedWitnessOutsidePreparedSubject
  identity=...an_empty_out_path_refuses_by_real_execution
  the changed-witness sublane selected this exact identity, but its module
  closure was not prepared, so execution cannot be represented as a decline

That identity is the fifth function, and it is the one that makes NO host
effect at all: the argument guard returns before the report touches anything --
no temp directory, no write, no shell. I put it in the wet witness because it
was topically adjacent to the arms that do write, and that was a misplacement
independent of any CI mechanism. It made a hermetic property depend on a lane
it does not need, and the floor named it.

So it moves to the hermetic controls, where it always belonged, and its
schedule row goes with it. The wet file now holds exactly the four functions
that perform real effects, and the schedule holds exactly those four -- checked
by an identity join in the direction that can fail, with a guard that refuses
an empty subject list rather than reporting a vacuous clean.

I am not claiming this clears the floor. The cause is new, the reasoning is
about my own file rather than about the lane, and the next floor run settles it.

Also records how the cause was obtained, because it nearly was not: the run was
still in progress, so the job-log API returned "run is still in progress" into
a file I then grepped for my module and found zero hits. That empty capture
read as a clean result, and I was one step from reporting that the route-gaps
were gone on the strength of a refusal I had mistaken for evidence. The receipt
artifact was retrievable while the logs were not.

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

* Remove the prepared-subject exclusion: the wet lane's members belong IN the subject

The exclusion was the proximate cause of ChangedWitnessOutsidePreparedSubject,
not a cure for the route gaps. A LocalRepoWetLane member is PULLED INTO the
prepared subject by local_repo_wet_schedule seeding the closure; excluding it
puts the identity in the one state the site loop refuses -- selected as a
changed witness and not prepared.

Restores the configuration in which the four route gaps appeared, which is the
configuration the changed-witness projection must be read against:
HermeticRouteGapHeldAndWetPassed is the floor's designed answer here, and this
run is to capture WHICH of its conjuncts fails.

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

* Enroll the four wet identities in floor_route_gap: the second half of a two-part enrollment

The wet schedule row supplies the EXECUTION; this supplies the record of the
HERMETIC BOUNDARY. Both are required and neither references the other, which is
why the schedule stood alone through five CI cycles.

Operation and ground are MEASURED, from required-floor run 33978797098 at
06c7740: 'the hermetic route has no arm for Dir (operation declares no
mock_response)' for each of the four. The enrollment was withheld until that run
existed rather than written from the inference that it would say Dir/NoMockResponse
-- which it did, but a roster row written from a guess is a transcribed number.

The same run establishes the pair discharges: [local-repo-wet] scheduled=22
admitted=22 refusals=0 with all four observed=passed, and the changed-witness
projection reading standing=hermetic-route-gap-held-and-wet-passed for each. The
hold is never a pass on its own.

Modelled on floor_route_gap_expectation_chunk_05, the same shape for the same
reason, in the typed form so a wrong operation or ground refuses rather than
enrolling silently.

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

* Write the absence of the wall into the header, since prose cannot refuse

The pair sentence was already here; what it lacked was honesty about its own
weakness. Both rows are required, neither references the other, and NOTHING
refuses a witness that has one and not the other -- stated as a declared
boundary rather than as advice.

The evidence that prose cannot carry this is in this repository, twice today:
floor_prepared_subject_exclusions carries a comment saying run_required_floor
consults that list and nothing else, and it did not reach the next author;
chunk_05's header states this same pairing in this same file, and it did not
reach the author of chunk_06, who supplied the schedule row alone and learned
the rest from five red floors.

Also records that floor_route_gap_expectation_mismatch returns early on a
missing expectation, so the one wall guarding these rows cannot fire for an
UNENROLLED identity -- the state every author is in while deciding what to
write. A guard whose precondition is the state you are not yet in protects the
case that no longer needs it.

Floor verified green at 0a036af before this commit: run 33980428822,
standing=measurement_completed blockers=0, all four jobs passing.

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

* The boundary paragraph understated the boundary: three carriers, not two

Review 61028 counted the carriers and was right. The enrollment is a TRIPLE:
the expectation in floor_route_gap_expectation_chunk_06, the schedule row in
local_repo_wet_terminal local_repo_wet_schedule, and the ci_layer_roots
witness_exclusion_frontier row classifying the file LocalRepoWetLane. None
references the others and nothing refuses a witness that has some and not all.
Named by symbol rather than by line, so the next edit above them does not
silently invalidate the citation.

A wrong count in a paragraph about a coupling nothing enforces -- written by the
author who checked the OTHER count in this same change an hour earlier and did
not check this one. Same class, same day, same hand, and this one came from
inside. The paragraph now records that it was caught by a reviewer counting,
not by its author.

An understated boundary is worse than no boundary because it will be trusted: it
is stated as a declared boundary in the file the next author is already editing,
and following it exactly supplies two of three and earns a red floor.

C1, N1 and N2 are untouched; this changes comment text in one .dag header and
nothing else.

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

* C1 reopened: the axes were counted against themselves, so an empty axis passed

THE DEFECT, reproduced as a fixture rather than described. Empty
calibration_resolution_arms, supply cells=[], and every conjunct holds:
distinct_arm_label_count == list_length is 0 == 0, the kind conjunct is 4 == 4,
length == declared is 0 == 4*0, distinct keys == declared is 0 == 0, and the
unsound list is empty. calibration_verdict returned ExitSuccess having measured
NOTHING. The two conjuncts that look like axis guards are vacuously true exactly
when the axes are most broken -- predicate_vacuously_true_on_an_empty_domain,
inside the instrument whose purpose is to refuse an empty traversal, and the
seventh specimen of a row this author appended six to this afternoon.

WHAT CHANGED. The axes are now PARAMETERS of traversal_is_complete_over and
globals only at the call site. That is the whole repair, because while the
predicate read the module lists directly NO FIXTURE COULD SUPPLY A DEGENERATE
AXIS -- the refusal arms were unauthorable, which DESIGN 4b calls a decoration
rather than a weak wall. A positive denominator on both axes now refuses the
empty case by name.

THREE CONTROLS ENROLLED, each red before this change and green after:
- an_empty_axis_refuses_rather_than_holding_vacuously (the case above)
- a_short_axis_is_internally_consistent_and_still_misses_a_kind: a shortened
  axis with its own matching matrix is INTERNALLY CONSISTENT, which is why the
  production defect is silent; the full matrix is refused against it
- a_colliding_axis_refuses_while_a_short_one_does_not: states by execution that
  the distinct-label conjuncts detect COLLISION, never OMISSION

DISCRIMINATION VERIFIED BY SABOTAGE, not by green: removing the positive
denominator turns the empty-axis control false, restoring it turns it true.

WHAT IS NOT FIXED, AND IT IS A LANGUAGE FINDING RATHER THAN A REMAINING TASK.
Axis completeness against the VARIANT TYPES is still not established anywhere.
Deriving the population from the type needs enumeration of a coproduct's
constructors from inside a fold; the substrate has no unfold, no range and no
constructor-listing primitive, so the list cannot be produced from the type by
any construction available. A third hand-maintained list would be a second
authority for the same fact and closes nothing. The capability that retires it
is named in the header.

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

* File the axis-completeness gap as a guarantee_stall, not a rung_drop

A rung_drop records a REGRESSION and carries a restoration trigger. Axis
completeness against the variant types was NEVER established, so there is no
height to restore and a drop would claim a loss that never happened. This is
DESIGN 4b(2)'s no-untracked-stall obligation: a class below its ceiling naming
what it waits on.

BLOCKER IS AwaitsOneGrounding, following the precedent of
roster_re_enumerates_its_own_rows_stall, which classifies a missing LANGUAGE
capability that way and argues why it is not ClimbableButUnbuilt: the climb is
not merely unstarted, it is unavailable with every construction the language
offers. That row is this one's sibling -- the same shape one layer over, an
authored list mirroring a declared population -- and the difference is the
missing primitive, VALUE BINDING for data declarations there against
CONSTRUCTOR ENUMERATION for a coproduct here. Neither implies the other.

The row carries the surface enumeration as its evidence, so one counterexample
falsifies it: no unfold, no range, no constructor-listing primitive, and std's
list surface is list_block, list_item, list_length, list_to_stack. It also
records why a third hand-maintained list is not the answer -- a second authority
for one fact that would make the stall LOOK discharged.

The trigger is stated as ENUMERATION OF THE TYPE rather than as a completeness
check over the list, because a check comparing the list to another authored
artifact is satisfied by editing that artifact while the axis stays short --
4b(3)'s trigger naming less than the capability it restores.

Guarantee stalls have no doc projection; the generated-artifact gate ran clean
with no drift.

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

* Say why floor_cost_basis_boundedness_stall was converted: main did not resolve

THE ROW DID NOT HAVE A TYPO. next_rung_trigger was a String when that row landed
(#10281); the field became the NextRungTrigger product with climbs_when as its
constructor in a separate change (#10582). The two never met, 31 of 33 rows in
that directory adopted the constructor, and the closure enumerating them stopped
resolving: expected Product(NextRungTrigger), got Primitive(String).

THE FINDING IS THE GATE, NOT THE ROW. Both commits are ancestors of a GREEN
required floor -- main's required-witnesses-floor at 2f8819b reported SUCCESS
with both in its history. The gate did not lose a race; it RAN AND PASSED over a
rostered row that does not typecheck.
dag/test/claim/guarantee_stall_witness_test.dag imports gunbc.guarantee_stall.roster
and declares eleven test fns, verified, so the closure looks covered and is not.
The roster is enumerated somewhere the required floor does not compile, and until
that is closed any stall row can stop typechecking with no red anywhere.

The conversion carried in the previous merge is mechanical -- the same string,
wrapped in the constructor the field now requires -- and was made only because a
branch merging main cannot resolve this closure otherwise. This commit adds the
explanation to the row so a reader of the diff cannot conclude a stall row had a
typo, which is what an unexplained one-line constructor change looks like.

Not mine to repair: the gate hole belongs to whoever owns the required floor's
discovery closure, and it is worth more than either PR it turned up in.

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

* Drop the carrier repair from this PR: it belongs to #10608 alone

The same row was edited by both PRs with DIFFERENT comment text -- +26 here and
+66 on #10608 -- which is two authorities for one fact. Worse than a plain
conflict: whichever landed first, the other conflicts, and if this PR landed
first the SHORTER, UNCORRECTED wording would reach main while the corrected one
waited behind an operator adjudication.

The carrier repair was never part of this PR's subject. It rode along only
because this branch could not resolve main without it. That is exactly the
coupling a standalone PR exists to remove.

This branch may now be unresolvable for local work until #10608 lands, which is
expected and is not a reason to re-add it: a PR whose subject is correct and
whose branch needs another PR first is an ordinary dependency.

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

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 6, 2026
…alRepoWetLane

Rehome namespace_import_closure_witness_test.dag and
interpreter_dispatch_bijection_real_roster_witness_test.dag from the
dead FalsifierSelfHostWet cadence (falsifier.yml deleted at 611fd02/
#8283, 2026-08-15) to the live local-repo wet lane (LocalRepoWetLane).

Changes:
- ci_layer_roots.dag: Reclassify both WitnessExclusionRows from
  FalsifierSelfHostWet to LocalRepoWetLane with excl_local_repo_wet_dissolve
- local_repo_wet_terminal.dag: Add WetScheduledClaim rows for both
  identities in local_repo_wet_schedule
- witness_admission_test.dag: Update assertions from FalsifierSelfHostWet
  to LocalRepoWetLane (kill inert passing assertions)
- floor_route_gap.dag: Move namespace_import_closure_receipt_holds from
  bare roster to LOCATED/expectation form (Run/NoMockResponse)
- wet_receipt_enrollment.dag: Remove both from
  falsifier_self_host_wet_template_entries; update
  dispatch_bijection_real_roster_red_enrolled_on_falsifier_self_host_wet
  to return false (rehomed identity)
- witness_exclusion_reconciliation_test.dag: Convert
  dispatch_bijection_real_roster_red_enrolled_on_falsifier_self_host_wet_holds
  to RED control (identity no longer on falsifier roster)
- Update prose in witness test files and transport module docs

Dashboard node: adhoc-cf84ab88-8dc
gunbai-bot Bot pushed a commit that referenced this pull request Sep 6, 2026
…alRepoWetLane

Rehome namespace_import_closure_witness_test.dag and
interpreter_dispatch_bijection_real_roster_witness_test.dag from the
dead FalsifierSelfHostWet cadence (falsifier.yml deleted at 611fd02/
#8283, 2026-08-15) to the live local-repo wet lane (LocalRepoWetLane).

Changes:
- ci_layer_roots.dag: Reclassify both WitnessExclusionRows from
  FalsifierSelfHostWet to LocalRepoWetLane with excl_local_repo_wet_dissolve
- local_repo_wet_terminal.dag: Add WetScheduledClaim rows for both
  identities in local_repo_wet_schedule
- witness_admission_test.dag: Update assertions from FalsifierSelfHostWet
  to LocalRepoWetLane (kill inert passing assertions)
- floor_route_gap.dag: Move namespace_import_closure_receipt_holds from
  bare roster to LOCATED/expectation form (Run/NoMockResponse)
- wet_receipt_enrollment.dag: Remove both from
  falsifier_self_host_wet_template_entries; update
  dispatch_bijection_real_roster_red_enrolled_on_falsifier_self_host_wet
  to return false (rehomed identity)
- witness_exclusion_reconciliation_test.dag: Convert
  dispatch_bijection_real_roster_red_enrolled_on_falsifier_self_host_wet_holds
  to RED control (identity no longer on falsifier roster)
- Update prose in witness test files and transport module docs

Dashboard node: adhoc-cf84ab88-8dc
gunbai-bot Bot pushed a commit that referenced this pull request Sep 8, 2026
…ission.dag:793

The function explicit_witness_admission_cadence_executes answers whether a
cadence actually runs, and std.witness_admission witness_cadence_has_scheduled_route
answers the same fact. For FalsifierSelfHostWet they disagreed:

  std:     FalsifierSelfHostWet => FALSE  (route deleted at #8283)
  gunbc:   FalsifierSelfHostWet => TRUE   (arm at :793)

This is DESIGN §5 coverage-by-illusion: without the false arm an author
could write an admission row on a dead cadence and satisfy the
every-witness-has-a-consumer wall with a row that executes nowhere.

The fix flips FalsifierSelfHostWet => false. It refuses nothing today:
zero explicit admission rows carry this cadence (verified:
  grep -c 'cadence: FalsifierSelfHostWet' explicit_witness_admission.dag = 0
). It closes the hatch before someone writes into it.

Four sibling arms carry the same divergence (FalsifierRehomedBinWet,
FalsifierSubstrateLongLane, BinWitnessWet, QuarantineProbeExpectRed) but
carry live populations — this PR does NOT touch them.
gunbai-bot Bot pushed a commit that referenced this pull request Sep 8, 2026
…ission.dag:793

The function explicit_witness_admission_cadence_executes answers whether a
cadence actually runs, and std.witness_admission witness_cadence_has_scheduled_route
answers the same fact. For FalsifierSelfHostWet they disagreed:

  std:     FalsifierSelfHostWet => FALSE  (route deleted at #8283)
  gunbc:   FalsifierSelfHostWet => TRUE   (arm at :793)

Without the false arm an author could write an admission row on a dead cadence
and satisfy the every-witness-has-a-consumer wall with a row that executes
nowhere (DESIGN section 5 coverage-by-illusion).

The fix flips FalsifierSelfHostWet => false. It refuses nothing today:
zero explicit admission rows carry this cadence (verified:
  grep -c 'cadence: FalsifierSelfHostWet' explicit_witness_admission.dag = 0
). It closes the hatch before someone writes into it.

Four sibling arms carry the same divergence (FalsifierRehomedBinWet,
FalsifierSubstrateLongLane, BinWitnessWet, QuarantineProbeExpectRed) but
carry live populations — this commit does NOT touch them.
gunbai-bot Bot pushed a commit that referenced this pull request Sep 8, 2026
… (review 62377 finding 1)

Root-cause fix per DESIGN §3 (single authority) and §6 (root-cause rather
than forked-logic patch): explicit_witness_admission_cadence_executes now
consumes std.witness_admission witness_cadence_has_scheduled_route for the
execution question, then adds only the genuinely-extra policy refusals
(DiscoverySelection, OfflineLocalRecipe, FixtureExplicitRoster — path-only
policies that have a route but must not appear on admission rows).

This replaces the hand-maintained match that duplicated the std authority.
All five falsifier-family cadences whose workflow was deleted at #8283 now
return false correctly through the delegation — no hand-edit can drift.
The three live-population cadences (QuarantineProbeExpectRed,
FalsifierSubstrateLongLane, BinWitnessWet) return false via
witness_cadence_has_scheduled_route without needing a separate arm.

Also fixes review 62377 findings 2 and 3:
- Finding 2: update prose comment at :782-789 to match the new delegation
  structure (DESIGN §4c annotation-contradiction defect)
- Finding 3: ci_layer_roots.dag blocker reason for interpreter_dispatch
  names the transport entry point and the declared budget symbol
  (gunbc_falsifier_self_host_wet_receipt_wall_budget) instead of
  transcribing the ~692s and 600s literals (DESIGN §6: name the
  instrument, never transcribe its output)
gunbai-bot Bot pushed a commit that referenced this pull request Sep 8, 2026
… with deleted_cadence_reference_drop

Adds dag/gunbc/rung_drop/transitional_admission_exception.dag as a
standing drop (LostAsPassenger, falsifier.yml deleted at #8283). 22
row identities on three cadences (QuarantineProbeExpectRed, BinWitnessWet,
FalsifierSubstrateLongLane) whose scheduled route was deleted.

Two overlapping identities (self_host_body_producer, self_host_use_site_verdict)
are already rostered in gunbc.rung_drop.deleted_cadence_reference_drop and
NOT duplicated here — the code-level exception list in
explicit_witness_admission.dag skips them.

Extends the SHARED-CAPABILITY HAZARD note to four drops: this row adds its
population to the same missing-cadence capability that
source_root_ingest_gate_rung_drop, deleted_cadence_reference_drop, and
witness_deferral_freeze_forward_rule_rung_drop wait on. The hazard: ONE
event fires four triggers; whoever lands the first cadence must retire all
four or leave the others standing on a trigger that has already fired.
gunbai-bot Bot added a commit that referenced this pull request Sep 8, 2026
…ith rung-drop; per-witness blockers (#10828)

The execution question is delegated to std.witness_admission witness_cadence_has_scheduled_route, so the five falsifier-family cadences whose workflow was deleted at #8283 are refused by one authority rather than a hand-maintained list (DESIGN §3).

The exemption is bounded by IDENTITY, not by cadence, and guarded by cadence so a listed identity cannot be laundered onto a cadence it does not belong to. Its population has a single authority: the RungDrop is constructed from the identity list rather than carrying a second hand-authored copy, so the two cannot drift.

The wall is executed, not declared. On the enforcing floor, all four cells report standing=planned-and-passed:
- a legacy exempted row admitted only through the bounded debt
- a newly constructed violating row on an exempted cadence, refused through the production predicate
- an admission on a non-executing cadence, refused
- a positive control on a live scheduled-route cadence, admitted

SHARED-CAPABILITY HAZARD: this drop waits on the same missing cadence category as its siblings. That coordination is not closed by this change and must not be inferred from it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WgiDD3VoavwLrcu832nJ2V
gunbai-bot Bot pushed a commit that referenced this pull request Sep 14, 2026
…with every refused route named

Review 65787 on #11315: the row called plain-fn controls 'enrolled'. They are not -- as test fns
the enrolment-margin gate refuses a newly enrolled ingest-reaching identity (run 34786156711),
the falsifier long lane has been DeclaredCadenceUnrealized since #8283, and the remaining live
cadences do not admit a hermetic ingest witness. The reds ARE enrolled (known-red, held by the
changed-witness arm). Wording corrected on the row and the corpus-path file; the standing is a
receipt on the row naming the class and the rung-drop trigger that would let the greens enroll.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RVFnQtBLTJd1ufJFr2hQKq
gunbai-bot Bot pushed a commit that referenced this pull request Sep 14, 2026
…te on no lane

Review 65787's second remedy. gunbc.rung_drop accumulator_copy_positive_controls_off_every_lane:
previous MechanicallyPreventable, temporary Mitigatable, lost as a passenger of the falsifier
long-lane executor (#8283); population the six green controls; restoration an executing lane with
a declared ceiling for an ingest-reaching hermetic witness, observed at retirement. Every refused
route is recorded on the row by execution or by the closing authority. Roster wired, projection
regenerated, roster witnesses pass; the class row now points at the drop.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RVFnQtBLTJd1ufJFr2hQKq
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