Skip to content

FLOOR-ROUTE-GAP-SELF-HOST: publish the executing route family that discharges the self-host behavioral witnesses from route_gap_held (49 required / 112 full) - #9725

Closed
gunbai-bot[bot] wants to merge 86 commits into
mainfrom
session/snappy-koi-879
Closed

gunbai-bot[bot] wants to merge 86 commits into
mainfrom
session/snappy-koi-879

Conversation

@gunbai-bot

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

Copy link
Copy Markdown
Contributor

What this PR delivers

23 self-host behavioral witnesses that were route_gap_held — never executed, nothing knowable about them — now execute and report a truthful verdict. Fifteen of them come back red, and that red IS the deliverable: the emitted crate v1_compiled does not compile (5 rustc errors, one being module Optional should have a snake case name under -D warnings), after which the witness binary is absent and downstream arms die at exit 127. That is the self-host frontier's actual state reaching a lane that can finally report it, which is worth more than a green would have been. route_gap_held goes 49 → 26, routed_to_wet_lane=23, claims_failed=0, unexpected_failures=0.

The receipt is committed at dag/gunbc/witness/wet_lane/ from run 33745596102 (srv3-13, 2h31m). Schema 2, 23 rows, every row carrying observed_entry_rel and observed_function with identity == observed_function throughout. The join against the known-red admissions is exact in both directions: 15 admitted, the same 15 red, nothing admitted passing, nothing red unadmitted, nothing admitted absent from the receipt.

The lease: the mechanism worked, including the part where it stopped me

The wet dispatch ran 2h31m. Its semantic subject still matched the evaluated tree exactly — the floor's own refusal says "the same semantic subject ran under a superseded seed build". Only the executor axis moved: envelope b6a2c43b against tree 3dcd74ec, because CI evaluates the merge ref and main merged src/v1/stage0 mid-run. That is the structural race the bootstrap lease was built for, exercised on a real receipt for the first time.

What happened next is the point. Not a silent stale-evidence admission, and not a lost dispatch: a typed refusal naming both digests, an escalation to the authority the artifact reserves the decision to, and a bounded operator grant. The lane refused to self-authorize and its manager refused to grant what the artifact reserves to the operator — so the mechanism stopped the author, which is what it is for.

The lease (gunbc.wet_seed_bootstrap_lease) pins four exact facts with no wildcard — envelope digest ffa6ca15, attempt_seq 1, semantic subject b6aee692, roster digest ab78f974 — and refuses NotApplicable if any fails to join, so no later receipt inherits it. Its window is closed-form against the evaluated tree's commit time, not wall clock, so it cannot be extended by re-running. The matching rung drop wet_executor_bootstrap_lease lands in the same push, as the artifact requires, with its trigger naming the capability: the executor axis derived from the evaluated tree rather than the dispatch tree — explicitly not "the next receipt lands exact", which a favourable runner slot satisfies while the capability stays dead.

The mechanism

The executing route family for the wet-routed self-host behavioral witnesses: v2.workflow.floor_wet_route (the receipt envelope authority, standing arms, and per-identity roster), its test module, the changed-witness join, the required-floor wiring, and the route-gap roster rewrite.

The defect this PR had to fix to be landable at all

The wet-lane receipt's candidate-exactness test is envelope.subject_digest == computed_subject_digest. The envelope is written by claim_batch; the equality is checked by claim_executor. wet_subject_digest folded closure_subject_for_entry -> subject_digest_for_closure, which is:

subject_digest_for_closure(sources) = derive_subject_digest(
    closure_content_digest(sources),   // the .dag closure -- correct
    transform_content_digest()         // hashes /proc/self/exe -- the bug
)

transform_content_digest() hashes the bytes of the running executable. Producer and consumer are different binaries, so that equality was unsatisfiable by construction on every tree, in every event, since the digest landed. The floor refused seven consecutive landing cycles for a staleness that never existed.

The receipt

A one-line edit to a .rs file, touching zero .dag, moved the "semantic subject" digest on one commit and one pristine checkout:

subject_digest
claim_batch in CI 5cc866cd221e7b56
claim_batch + one added eprintln 846ead7b689b7ead

A digest claiming to be over the .dag semantic closure must not move on a Rust-only edit. (wet_executor_contract_digest moved too, from 08ce4cd6 to e074e736 -- that one is correct, it is supposed to be about seed bytes.)

The fix

wet_closure_subject / wet_closure_subject_for_entry fold closure_content_digest alone. subject_digest_for_closure is unchanged for its two other callers, both resolve-cache keys, where the transform axis is correct and load-bearing: an artifact produced by one compiler must not be served to another. The exe hash is right in a cache key and wrong in a semantic subject.

The executor axis is not lost: wet_executor_contract_digest carries it as its own declared axis, over its own declared input roster, checked by its own standing arm (ReceiptExecutorSnapshotDifferent). This removes a double-count, not a guarantee.

The enrolled RED

wet_subject_is_independent_of_the_running_binary varies the transform axis directly and requires the wet subject not to move; the_wet_subject_moves_on_dag_content requires it to move on what it claims to measure. Permanently enrolled per DESIGN 4b dissolution-on-climb -- the production machinery dissolves, the evidence stays.

Verified by mutation against the pushed head: re-pointing wet_closure_subject at subject_digest_for_closure -- i.e. re-introducing the defect -- reds wet_subject_is_independent_of_the_running_binary with its intended message (test result: FAILED. 1 passed; 1 failed).

Do not read "two enrolled REDs" as two independent walls against this bug. the_wet_subject_moves_on_dag_content stays GREEN under that mutation. That is correct -- the cache subject is content-sensitive too -- so only ONE of the two tests discriminates for this defect; the second guards the converse property (a tree-only digest that ignored content would pass the first trivially).

Review warning: a diff-shipped runner can silently omit the test file

The first mutation attempt reported nothing useful and would have read as a pass. ctrl-build --remote fetches a commit and applies the working diff on top; because the fix was not yet pushed, it diffed against a stale base and shipped only 3 of 5 files -- required_floor_runner.rs, which contains the tests, never arrived. cargo test --lib wet_subject then matches zero tests and exits 0, which is indistinguishable from a green run unless the test COUNT is read. The real check was run against the pushed sha, where the runner fetches the true tree (Checking patch count 0, and the module's presence asserted in-run before the test invocation).

This is a general class, not a one-off: any remote runner that reconstructs the tree from a diff can drop exactly the file whose absence makes the check vacuous. Read the test count, never the exit code.

Both run on a real two-module closure. An earlier draft used an empty source list, where both digests fold to their seed constant and the assertions hold by construction -- green forever, wall or no wall. Each assertion now carries the positive control that makes it discriminating.

The instrument

wet_subject_entry_subjects is the named producer every caller of the digest folds, rendering one [wet-subject] entry=... closure_subject=... line per entry. The aggregate sha could say only THAT a producer and a consumer disagreed, never WHERE. That is the displaced cost this priced: seven cycles.

The bootstrap lease: mechanism present, no lease in force

Stated precisely, because an earlier revision of this body described a lease strategy the tree
no longer executes. The lease mechanism is live and enrolled: gunbc.wet_seed_bootstrap_lease,
wet_seed_bootstrap_lease_window_secs, wet_seed_bootstrap_admission, the
WetFloorAdmittedUnderBootstrapLease disposition arm, and their witnesses in
src/v2/test/floor_wet_route_test.dag. What is not present is a declared lease:
wet_seed_bootstrap_lease_declared is Absent {}.

So no lease is in force, no envelope is admitted under one, no ancestor-subject admission exists,
and no gunbc.rung_drop row is in force for this route — none is added here, and the
BootstrapLivenessLease row an earlier revision cited by name was never authored in any commit.
The mechanism sits unexercised against the executor-drift race it was built for. Preferring not to
need it is the outcome; having it available is not the same as using it.

The shell actuator was default-denied and deleted

The wet-receipts job originally carried a run: step that committed the receipt pair and opened a
pull request via hand-authored git/gh shell. Codex filed it on four consecutive heads
(reviews 57948, 57967, 58024, 58034) as a medium-as-string blocker. It is removed, not re-worded:
wet_receipts_pr_step, wet_receipts_pr_script, wet_receipts_pr_body and their dissolution
trigger are deleted. DESIGN §5 settles the disposition absent an operator ruling — a scaffold does
not land by author declaration, approval is external to the diff, and none exists.

The lane now executes the routed rows and uploads the pair as a run artifact. That is its entire
publication surface: no repository-write step on any ref.

The recurring cost that removal relocates to a person

Deleting the step does not delete the actuation. The scheduled lane executes and commits nothing,
so a person must land a fresh pair within floor_wet_route_receipt_staleness_budget_secs of each
execution, indefinitely; a miss refuses the required floor on every open pull request until someone
does. wet_receipt_hand_commit_dissolve_on declares that as admitted recurring debt, with a trigger
naming the capability — a typed repository-write effect on host_effect_apply reached from the
emitted pipeline. The earlier trigger wording ("the ref gate widens from refs/heads/main") would
have been retired by re-adding exactly the shell removed here, which is the §4b(3) grain mismatch
where a trigger naming less than the capability is satisfied while the capability stays dead.

This is an open question for the operator, not a resolved one. Review 58085 objects that the
debt is unbounded, and that objection is correct on its own terms; approval is external to the diff.

Why the age axis is not redundant, and why re-keying it was withdrawn

I proposed bounding the debt by keying expiry to the subject digest, since ReceiptExpired is
reached only after subject, executor contract and roster all match — so an exact receipt for an
untouched tree ages out anyway. Withdrawn. Both digests are computed from repository files, and
wet_executor_contract_input_prefixes covers the toolchain pin, not the realized toolchain, the
runner image, or resolved dependency bytes. A wet receipt is an observation of external reality,
which §4b keeps off the guarantee ladder; observations of the unmodeled decay while every modeled
digest stays identical. The subject axis bounds what we model, the age axis bounds what we do not.
Re-keying would have removed the detection, not the debt — the absorbing-fallback shape.

Merging main before dispatch is mandatory

The lane's condition is schedule || workflow_dispatch, so a dispatch checks out the branch head;
the required floor runs on pull_request, which GitHub evaluates on the merge ref. Those agree
only while main has not moved. Whenever files under wet_executor_contract_input_prefixes differ
between head and main, an envelope produced by a dispatch is ExecutorSnapshotDifferent against the
tree the floor adjudicates — stale on arrival. Merge main first, then dispatch on that exact head.

Generated-artifact drift is not gated

Regenerating DESIGN.md / docs/design-ledgers.md in this PR had to be done by hand:

gunbc run --source-root dag --source-root src/v2 \
  --entry dag/gunbc/instruments/generated_artifact_gate.dag --function main_wet

--required-generated-artifact was deleted by the "Required gate reduced to the compiler floor" drop and survives only in a comment, and the auto-heal job went with the floor cut — so nothing in CI catches these files drifting from their .dag authorities. Two ways that step fails while looking finished, both hit here: claim_executor --required-regen --write exits 0 with first_generation_equal=true and adjudicated=148 while changing neither document (it regenerates stage0 Rust), and main_wet itself exited 137, OOM-killed on the runner. Raised as its own work item.

Also in this diff

  • The receipt pair carries the most recent real run's envelope as history. It is NOT claimed as candidate-exact and no lease names it; the landing envelope comes from the wet lane dispatched on the tree that carries the mechanism.
  • The hand-committed-envelope actuation is declared at wet_receipt_hand_commit_dissolve_on (renamed from wet_receipt_pr_branch_hand_commit_dissolve_on, because the obligation governs main as well as candidate branches). gunbc.witness_floor_workflow's wet-receipts job holds no commit step on any ref.
  • Merge of main through RLM-2a. The run_name field addition emits nothing for Absent, so witnesses.yml is unchanged and no regeneration is owed.

On the codex reviews

  • 57748 / 57656 / 58085 (the coproduct predicate) — not taken, with reasoning in PR comments.
    57656 filed the Bool over WetLaneReceiptStanding and asked that polarity consume a canonical
    fold; the remediation added WetFloorGateDisposition and wet_route_gate_disposition. 58085 then
    objected to the reader of that fold. Every Boolean decision bottoms out in a variant-to-Bool map,
    so the objection has no fixed point. The typed disposition is provably undissolved: the floor
    prints subject-mismatch axis=semantic-subject with both digests, which a Bool could not carry.
    grep -niE "predicate" over DESIGN.md returns one hit, in §4b about lifting predicates to proof.
  • 57948 / 57967 / 58024 / 58034 (the shell actuator) — taken in full; the step is deleted.
  • 58092 (unmarked hand-shell carriers) — not taken at the cited grain. Build the witness fold
    is emitted 4× on main and 5× here from one shared producer; the lane run: block 3× and 4×
    from another; none carries a marker, including every pre-existing instance. Marking only the wet
    instances would put the marker on one call site of a shared producer. The corpus marks
    hand-authored transport (the rustup pin, ci_release_bins_pack, fleet_key_agent), not rendered
    argv. Named where the finding is right one level up: required_lane_run_script's hand-written
    ROOT=/cd prelude is unmarked hand-shell and plausibly warrants a marker on the producer,
    covering all four lanes — a separate change, since editing witness_floor_workflow.dag moves the
    executor contract digest and burns a wet run.

gunbc-ci-auto-heal and others added 9 commits August 30, 2026 06:05
…n, the wet lane, and the workflow job

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LUsJiEMrVVJYjbAXXvKtc
…m standing, publication wall, candidate-exact changed-witness admission

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LUsJiEMrVVJYjbAXXvKtc
# Conflicts:
#	dag/gunbc/v1/v1_witness_census.dag
#	dag/test/claim/match_exhaustiveness_coproduct_witness_test.dag
#	src/v1/stage0/src/cli_run/required_floor_runner.rs
#	src/v2/test/floor_changed_witness_test.dag
#	src/v2/workflow/floor_changed_witness.dag
… wet route; 4-arg projection test

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LUsJiEMrVVJYjbAXXvKtc
…arnings, all-targets)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LUsJiEMrVVJYjbAXXvKtc
…target (clippy --all-targets)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LUsJiEMrVVJYjbAXXvKtc
…-test exhaustiveness, axis on the ancestor fixture; add the preserved-wet-route selector control

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LUsJiEMrVVJYjbAXXvKtc
…-receipts lane job renders now that argv_command admits claim_batch_command

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LUsJiEMrVVJYjbAXXvKtc
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review August 30, 2026 10:07
…fields (review 57567), same construction as required_floor's sibling row

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LUsJiEMrVVJYjbAXXvKtc
@gunbai-bot

gunbai-bot Bot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor Author

Re review 57567 (four flat-scalar unit fields in the new envelope): fixed in 0052ba4 by the reviewer's second remedy — a typed dissolve-on row, flat_scalar_wet_receipt_time_fields_dissolve_on, covering wall_ms, executed_at_unix_secs, published_at_unix_secs and the fold's evaluated_tree_commit_unix_secs (plus the cadence/grace/budget/skew rows they compare against). Direct std.measure typing is not available to this module without new substrate work: Millisecond = Measure<Time, Milli, std.nat.Nat> is built on v1's host-backed Nat, while this module's Int is v2's inductive tower, and no verified bridge between the two numeric towers exists in the corpus — the identical class its sibling row v2.workflow.required_floor.flat_scalar_millisecond_fields_dissolve_on already records (review 53860 on gunbc#8584), whose trigger this row names verbatim so both dissolve together.

…ow, relocated beside the envelope type (review 57568)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LUsJiEMrVVJYjbAXXvKtc
@gunbai-bot

gunbai-bot Bot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor Author

Re review 57568: the tracked gate the verdict asks for is landed — flat_scalar_wet_receipt_time_fields_dissolve_on (a typed std.dissolution row, now carrying the 🟡 feature/dissolve-on marker and sitting directly beside WetReceiptEnvelope) covers all four named fields plus the cadence/grace/budget/skew rows they compare against, including the instant+duration mixing on the skew comparison. Direct std.measure carriers are not reachable from this module without first authoring a verified bridge between v2's inductive numeric tower and the host-backed Nat that std.measure is built on — the identical bounded gap v2.workflow.required_floor.flat_scalar_millisecond_fields_dissolve_on records (review 53860 on gunbc#8584); both rows name the same trigger and dissolve together.

gunbc-ci-auto-heal and others added 2 commits August 30, 2026 11:06
…not a gate membership the fixture never had

The witness expected Planned for an unrostered sibling of module
dag.test.claim.lifecycle_survivor_corpus_census, but that spelling matches no
required_gate_prefixes row, so its home disposition is
DeclinedOutsideRequiredGate. On main the witness never executed (its match went
non-exhaustive when PlannedAsChangedWitness landed -> compile refusal ->
outcome=absent); this branch's exhaustiveness repair ran it for the first time
and surfaced the wrong expectation. The control keeps its discriminating power:
a module-grain cost-debt reading would answer DeclinedCostDebt and go red.
Also drops a duplicated DeclinedOutsideRequiredGate arm in the rostered-identity
witness beside it. Both executed PASS remotely at this tree.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LUsJiEMrVVJYjbAXXvKtc
…/not_executed, not absent

Correction relayed by parent: no population hole in #9684's projection — the
module was lawfully declined outside the gate closure on main; this branch
pulled it into the closure, which is why it compiled (then refused) first here.
Comment-only (§4c annotation channel); held locally to ride the seed-envelope
push so the running wet dispatch stays candidate-exact.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LUsJiEMrVVJYjbAXXvKtc
@gunbai-bot

gunbai-bot Bot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor Author

Re review 57576 (REQUEST_CHANGES on the four flat-scalar time fields): these four fields are exactly the population named by the in-diff tracked dissolution row flat_scalar_wet_receipt_time_fields_dissolve_on (src/v2/workflow/floor_wet_route.dag, beside WetReceiptEnvelope). Consuming std.measure here is not currently constructible: std.measure's Time carriers are built on the host-backed Nat, and no verified conversion exists yet between v2's inductive numeric tower (v2.std.integer.Int) and that Nat — the same missing capability v2.workflow.required_floor.flat_scalar_millisecond_fields_dissolve_on already names for the required floor's own millisecond fields (precedent review 53860 on #8584). The row names that capability as its trigger, so this is tracked debt with a live dissolution condition, not a fork of the measurement authority. Reviews 57567 and 57568 raised the identical finding and offered the 🟡 dissolve-on row as an accepted resolution; review 57569 approved the PR on exactly that basis. — sent from snappy-koi-879

gunbc-ci-auto-heal and others added 3 commits August 30, 2026 11:26
…ding arms

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LUsJiEMrVVJYjbAXXvKtc
…s declared debt

Per review 57576 on #9725 and the parent ruling that followed: wall_ms is
std.types.Milliseconds; executed_at_unix_secs, published_at_unix_secs and the
standing fold's evaluated_tree_commit_unix_secs parameter are std.types.EpochSecs
(the corpus's one POSIX Unix-instant authority — DFS std first found it, no new
type minted); the cadence/grace/budget/skew rows are std.types.Seconds. The 🟡
flat_scalar_wet_receipt_time_fields_dissolve_on row is deleted — the debt never
lands. All 12 floor_wet_route and 18 floor_changed_witness witnesses PASS by
remote execution on this tree. required_floor's observed_cpu_ms/observed_wall_ms
remain main's pre-existing instance of the class under its own dissolution row.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LUsJiEMrVVJYjbAXXvKtc
…me grain (ruling c, confirmed with three walls)

Wall 1 — outcome grain: WetLaneOutcome and the envelope wire carry the raw typed
observation (pass, assertion-false, and ten no-subject-verdict arms incl. the
lane's resolve-failed/closure-subject-failed), never a collapsed Bool; the
reader refuses any wire outside the closed vocabulary as a contract mismatch.
Wall 3 — no duplicate expected-red authority: the expected set derives from
gunbc.explicit_witness_admission's ExecutionWitnessKind rows via
wet_route_expected_assertion_false_identities; nothing is authored in
floor_expected_red. Algebra: pass+unenrolled clean; pass+enrolled now-passing
(blocks until the row deletes); assertion-false+enrolled held (counted,
shrink-only); assertion-false+unenrolled unexpected red (blocks); any
no-verdict outcome blocks regardless of enrollment. ReceiptFailed leaves
WetLaneReceiptStanding (six envelope-level arms remain, never waivable).
Wall 2 — the publication transaction waives exactly the per-identity red
classes so a red attempt's receipt-confined refresh PR can publish evidence.
Also per review 57583: age_secs is Seconds on both arms; the variant->Bool
publication table is dissolved into the per-identity fold. Refined time
scalars bridge to arithmetic through wet_time_scalar (parameter-position
coercion, the roadmap_forecast precedent) since the interpreter has no cast
for refined scalars in either direction.

All 15 floor_wet_route + 18 floor_changed_witness witnesses PASS by remote
execution; clippy(lib+bins) clean; 580 lib tests green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LUsJiEMrVVJYjbAXXvKtc
gunbc-ci-auto-heal and others added 8 commits August 30, 2026 13:39
…gger

Per parent requirement: the parameter-position identity bridging refined time
scalars to Int arithmetic is a workaround for the interpreter's missing
refined-scalar coercion, marked on the carrier with a 🟡 dissolution row whose
trigger names the capability (an evaluating cast/widening from a where-refined
scalar to its base Int, sufficient for EpochSecs-as-Int and Seconds-as-Int
under gunbc run). The roadmap_forecast EpochMs-difference site is cited as the
same debt, one class, dissolving on the same capability. One identity at every
site so the census counts one row.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LUsJiEMrVVJYjbAXXvKtc
The fold_list+list_append form produced a Cons whose tail was a runtime List,
which floor_decode_list refuses mid-chain — the PR floor at 069f82d red with
'expected a FreeMonoid Empty/Cons chain, observed List(len=1)' before reaching
the wet join. Rebuilt with the filter/map idiom floor_expected_red_roster
already decodes through. Executed locally: returns exactly the six enrolled
ExecutionWitnessKind identities.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LUsJiEMrVVJYjbAXXvKtc
…rement); regenerate witnesses.yml from the model

Union pub-use resolution in cli_run.rs; witnesses.yml regenerated via
generated_artifact_gate main_wet on the merged tree — carries both #9747's
clippy step and this branch's wet-receipts job.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LUsJiEMrVVJYjbAXXvKtc
…he workflow model and regenerate witnesses.yml

Union in witness_floor_workflow.dag: both new jobs (fabric-evidence and
wet-receipts) registered in the jobs list, the per-job capability-closure
conjunction, and the aggregate gate; the fabric-evidence job additionally
carries not_on_wet_cadence_condition, which this branch's schedule trigger
makes necessary — the model's own rule that required lanes do not run on the
wet cadence. witnesses.yml regenerated from the model (clippy step,
fabric-evidence job, wet-receipts job all present). cli_run.rs pub-use union.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LUsJiEMrVVJYjbAXXvKtc
…9753) — union with the wet route

floor_changed_witness: both features coexist — the cost-policy planned
standings and the wet candidate-exact admission; standing_kind and every match
carry all arms. required_floor's cost_debt_roster_standing classifies
DeclinedRoutedToWetLane as declared-not-withheld (the double-enrollment wall
refuses that state upstream). Projection fn takes both feature parameter sets;
all call sites unified. witnesses.yml regen: byte-exact no-op. All 51 .dag
witnesses of the two fold modules PASS by remote execution.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LUsJiEMrVVJYjbAXXvKtc
… one-shot bootstrap lease homed outside the wet closure

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019LUsJiEMrVVJYjbAXXvKtc
… transaction

The publication waiver (residual B) returned false unconditionally under a
valid transaction, waiving all FOUR per-identity classes where its own prose
says two. `no_verdict` is the ABSENCE of a verdict — waiving it converts a
hole into a green merge path, the fabricated-plausible-output arm of §5 in a
receipt's costume. `cost_debt` DID reach a verdict and then exceeded the line,
so the figure is exact. Both now block regardless of the transaction; only
`unexpected_red` and `now_passing` are waivable (review 59383).

Seed-only, as with the three prior repairs: `v2.workflow.floor_wet_route` is a
term of its own semantic subject, so editing it voids the operator grant. The
model instance is filed as a fourth member of
`gunbc.guarantee_stall wet_route_model_lags_seed_stall`, alongside the
`roster_identities`/`roster_digest` pair as the fifth.

Files `gunbc.recurring_failure_mode subject_and_its_digest_as_independent_parameters`:
a subject and its digest passed as peer parameters can disagree silently,
carrying both faces — independent digest/subject, and N derived views agreeing
because one reader fed them all. One join that was never made.

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

gunbai-bot Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

Both findings verified against the current code. Review 59383's first finding is real and is now fixed; the second is declined for a reason that is itself filed as a stall.

1. The four-class publication waiver — CONFIRMED, and it was mine. Neither wet_route_identity_rows_block_with_publication nor its Rust realization exists on origin/main, so the fail-open was introduced by this PR. The function's own prose says the waiver covers "exactly the PER-IDENTITY reds ... Both waived classes carry remedies outside the receipt namespace" — two — while if publication_transaction_valid { false } waived four. no_verdict is the absence of a verdict, so waiving it merges an attempt in which a routed identity produced nothing; cost_debt reached its verdict and then exceeded the line, so the figure is exact. Repaired in v1_compiler.cli_run.required_floor_runner: the transaction is now evaluated only when unexpected_red or now_passing is non-empty, and the no_verdict/cost_debt diagnostics are pushed outside the waiver scope unconditionally. cargo check -p v1-compiler --bin claim_executor is clean.

Why the .dag still says four. v2.workflow.floor_wet_route is a term of its own semantic subject digest, which the operator-granted one-shot bootstrap lease pins as exact_semantic_subject_digest. Any byte edit to that file — including a comment — voids the grant and forces a re-dispatch (2h31m) plus a second operator grant. That is why the three prior repairs on this PR were also seed-only, under a standing parent ruling. The model instance is filed as a member of gunbc.guarantee_stall wet_route_model_lags_seed_stall, whose trigger requires the repairs to land on a head whose receipt was dispatched after them. The executing path — the one the required floor runs — refuses.

2. wet_route_disposition_blocks_floor as a hand-matched Bool predicate. Same constraint: the remedy is an edit to floor_wet_route.dag. Noting also that the predicate is not a new classification surface — it is a single read of the canonical wet_route_gate_disposition fold introduced to remove the second enumeration flagged in review 57656, and wet_route_standing_blocks_floor now delegates to it rather than re-matching the standing. The dissolution to a canonical fold/query rides the same re-dispatch.

3. Related, filed this push. gunbc.recurring_failure_mode subject_and_its_digest_as_independent_parameters — the general shape behind the envelope/digest seam already closed in the seed and the roster_identities/roster_digest pair one row over: a value and a summary of it passed as peer parameters can disagree silently, because the join that would catch it is the one nobody made. The repair, already built once, is to derive the digest from the value at the point the value is obtained.

Head is 4c4188a, which also merges origin/main; git merge-tree --write-tree origin/main HEAD returns 0.

— sent from snappy-koi-879

Parent ruling: fold prose-adjacency into the digest/subject row rather than
filing a sibling — the unifying claim is stronger than three siblings. An
annotation READS as documentation and FUNCTIONS as an assertion, and §4c
guarantees no `Accepted` program can read one, so nothing in the toolchain
will ever disagree with it. `wet_route_identity_rows_block_with_publication`
said two waived classes three lines above a body that waived four, and four
approvals read past it. Provider count is not attention.

Also de-tallies `wet_route_model_lags_seed_stall`: the subject line and
trigger now name the population as the enumerated members rather than a
transcribed count that went from three to five in one afternoon.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GvVoivi7L449wbh6rjeJY4
Review 59401, confirmed: `WetReceiptIdentityRow.wall_ms` is a non-optional
`Milliseconds`, so the two pre-execution refusal arms in `claim_batch` write a
synthesized `0` for a duration nothing measured. The tell is inside the same
struct literal — `observed_entry_rel` and `observed_function` are Optional and
correctly `None` on exactly these arms, under an annotation saying a fabricated
observation is the plausible output §5 forbids — and `wall_ms` fabricates one
two fields later.

The repair is a schema change to `v2.workflow.floor_wet_route`, a term of its
own semantic subject, so it rides a re-dispatch and a fresh grant. Filed as
`wet_receipt_wall_ms_fabricated_on_refusal_arms_stall` with the capability
trigger: `Optional<Milliseconds>` AND a receipt dispatched under it — a
consumer that branches on the outcome wire is the mitigation this row counts,
not its discharge.

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

gunbai-bot Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

Review 59401, finding 1 — confirmed, and sharper than stated. The fabrication sits in the same struct literal as its own refutation: observed_entry_rel and observed_function are Optional and correctly written None on exactly these two arms, under an annotation two lines above the type saying that a fabricated observation is the plausible output §5 forbids — and wall_ms fabricates one two fields later. 0ms is not a fast execution; it is the absence of one.

I have not made the schema change here. wet_receipt_identity_row's type lives in v2.workflow.floor_wet_route, which is a term of its own semantic subject digest; the operator-granted one-shot bootstrap lease pins that digest, so any byte edit voids the grant and forces a re-dispatch. And the schema change alone would not be enough — the committed envelope still carries the old shape, so the repair genuinely rides a re-dispatch. Filed as gunbc.guarantee_stall wet_receipt_wall_ms_fabricated_on_refusal_arms_stall, ceiling StructurallyImpossible, with the trigger stated as a capability: wall_ms carried as Optional<Milliseconds> so an unmeasured duration has no constructor that produces a number, plus a receipt dispatched under that schema. Explicitly not discharged by a consumer that branches on the outcome wire — that is the mitigation the row exists to count.

Findings 2–5 need nothing from me, and I agree with your own dispositions:

  • WetLaneOutcome / WET_OUTCOME_WIRES hand-mirroring — the drift risk is exactly as you describe (a 13th arm compiles green on the model side and drops silently on the reader), and it is rostered under floor_wet_route_seed_growth_justification with a capability-shaped dissolve-on.
  • The Present lease — that is the intended reading. It is an honest §4b(3) drop, rostered in full, pinned to an exact quadruple, refusing on any one of the four facts mismatching, and homed outside the wet semantic closure so it cannot pin itself.
  • wet_time_scalar — identity workaround, language-capability dissolve-on, staying on the census.
  • The hand-Rust growth is enumerated with an owner.

Head is now 8b8358c.

— sent from snappy-koi-879

gunbai-bot Bot pushed a commit that referenced this pull request Sep 3, 2026
…open-PR writing it

This repository's authorities are single by construction (DESIGN §3), which
makes them contention points: one file is where a concept lives, so every lane
touching that concept edits that file. A lane about to restructure a module
cannot see, from its own branch, that three other branches are already
rewriting it -- the conflict is created at authoring time and discovered at
merge time, by whoever lands second. The displaced cost is the rework the later
lane pays, in full, every time.

  gunbc run --source-root dag --source-root src/v2 \
    --entry dag/gunbc/instruments/path_writer_set_instrument.dag \
    --function writers --arg repo=gunb-ai/gunbc --arg path=<path>

A subject ending in `/` asks about a subtree; anything else names one file, and
the report prints which rule it used.

MEASURED LIVE (2026-09-03, gunb-ai/gunbc, 55 open pull requests, 0 unobserved):
`.github/workflows/witnesses.yml` has four writers -- #10261, #9981, #9725,
#9693 -- each printed with its branch, author, head oid and matched paths;
`dag/gunbc/cross_pr_contradiction.dag` has none, and says so in words.

WHY IT IS NOT A WIDENING OF `gunbc.cross_pr_contradiction`. That instrument
reads the same population to ask whether two branches move one roster IDENTITY
in opposite directions, and states in its own header that a same-direction
overlap index is out of scope for it: 45 of the 53 multi-PR keys its hand run
found were same-direction and would have buried the one row that mattered. That
ruling is correct for a SCAN over the whole corpus, and it is exactly why this
is a QUERY -- the subject is supplied by the asker, so there is no population to
bury a finding in.

RENAME DETECTION IS OFF, AND THAT IS THE ONE NEW EXTDEPS OPERATION.
`diff.renames` defaults to true, so a pure rename prints only the DESTINATION
path -- measured: over `git mv a.txt b.txt`, `git diff --name-only HEAD~1 HEAD`
prints `b.txt` alone while `--no-renames` prints both. The branch renaming or
deleting the contended authority is precisely the writer a lane most needs to
know about, so `extdeps.git.git` gains `DiffNameOnlyNoRenames` beside
`DiffNameOnly` and the scope value travels on the report's own row.

EMPTY IS NOT ABSENT (DESIGN §5). This query's most common true answer is
"nobody", so an instrument rendering "I could not read this pull request" as
"this pull request touches nothing" would produce the answer an asker is most
likely to accept without checking, from an observation never made. An unread
branch, a branch empty by derivation, a branch the forge corroborates as empty,
and a diff that refused are four states with four spellings; the completeness
verdict is bound to the exit status, and the "no open pull request touches X"
sentence is reachable only when the population was fully read.

`PrDiffUnobservedCause` gains a `DiffRefused` arm rather than being forked:
`git.Core.Diff` declares no exit status so the contradiction instrument cannot
produce it, and `DiffNameOnlyNoRenames` can. One vocabulary, one set of
consequences.

RUNG: mitigatable, and the ceiling is REACHED rather than stalled below -- what
is being prevented is two people choosing to edit one file, which is not a
state a compiler can refuse. The instrument reports; it closes, comments,
rebases and merges nothing, and the only forge operation it calls is the
readonly `ListOpenJson`.

EVIDENCE. 13 witnesses in dag/test/claim/path_writer_set_witness_test.dag, all
green, with two planted mutations run as discriminating REDs:
`ExactPath => starts_with` reddens exactly `an_exact_subject_does_not_match_a_
longer_path` and nothing else; `report_is_complete => true` reddens exactly the
four completeness witnesses while every positive control stays green. The 27
`cross_pr_contradiction` witnesses stay green over the added arm.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AinEdiYkU1u4HYnS6DUP78
gunbc-ci-auto-heal added 3 commits September 3, 2026 19:03
# Conflicts:
#	dag/gunbc/recurring_failure_mode.dag
#	docs/design-failure-modes.md
#	docs/design-rung-drops.md
gunbai-bot Bot added a commit that referenced this pull request Sep 3, 2026
…currently writing it (#10263)

* The writer set for a contended authority: given a path, print who is open-PR writing it

This repository's authorities are single by construction (DESIGN §3), which
makes them contention points: one file is where a concept lives, so every lane
touching that concept edits that file. A lane about to restructure a module
cannot see, from its own branch, that three other branches are already
rewriting it -- the conflict is created at authoring time and discovered at
merge time, by whoever lands second. The displaced cost is the rework the later
lane pays, in full, every time.

  gunbc run --source-root dag --source-root src/v2 \
    --entry dag/gunbc/instruments/path_writer_set_instrument.dag \
    --function writers --arg repo=gunb-ai/gunbc --arg path=<path>

A subject ending in `/` asks about a subtree; anything else names one file, and
the report prints which rule it used.

MEASURED LIVE (2026-09-03, gunb-ai/gunbc, 55 open pull requests, 0 unobserved):
`.github/workflows/witnesses.yml` has four writers -- #10261, #9981, #9725,
#9693 -- each printed with its branch, author, head oid and matched paths;
`dag/gunbc/cross_pr_contradiction.dag` has none, and says so in words.

WHY IT IS NOT A WIDENING OF `gunbc.cross_pr_contradiction`. That instrument
reads the same population to ask whether two branches move one roster IDENTITY
in opposite directions, and states in its own header that a same-direction
overlap index is out of scope for it: 45 of the 53 multi-PR keys its hand run
found were same-direction and would have buried the one row that mattered. That
ruling is correct for a SCAN over the whole corpus, and it is exactly why this
is a QUERY -- the subject is supplied by the asker, so there is no population to
bury a finding in.

RENAME DETECTION IS OFF, AND THAT IS THE ONE NEW EXTDEPS OPERATION.
`diff.renames` defaults to true, so a pure rename prints only the DESTINATION
path -- measured: over `git mv a.txt b.txt`, `git diff --name-only HEAD~1 HEAD`
prints `b.txt` alone while `--no-renames` prints both. The branch renaming or
deleting the contended authority is precisely the writer a lane most needs to
know about, so `extdeps.git.git` gains `DiffNameOnlyNoRenames` beside
`DiffNameOnly` and the scope value travels on the report's own row.

EMPTY IS NOT ABSENT (DESIGN §5). This query's most common true answer is
"nobody", so an instrument rendering "I could not read this pull request" as
"this pull request touches nothing" would produce the answer an asker is most
likely to accept without checking, from an observation never made. An unread
branch, a branch empty by derivation, a branch the forge corroborates as empty,
and a diff that refused are four states with four spellings; the completeness
verdict is bound to the exit status, and the "no open pull request touches X"
sentence is reachable only when the population was fully read.

`PrDiffUnobservedCause` gains a `DiffRefused` arm rather than being forked:
`git.Core.Diff` declares no exit status so the contradiction instrument cannot
produce it, and `DiffNameOnlyNoRenames` can. One vocabulary, one set of
consequences.

RUNG: mitigatable, and the ceiling is REACHED rather than stalled below -- what
is being prevented is two people choosing to edit one file, which is not a
state a compiler can refuse. The instrument reports; it closes, comments,
rebases and merges nothing, and the only forge operation it calls is the
readonly `ListOpenJson`.

EVIDENCE. 13 witnesses in dag/test/claim/path_writer_set_witness_test.dag, all
green, with two planted mutations run as discriminating REDs:
`ExactPath => starts_with` reddens exactly `an_exact_subject_does_not_match_a_
longer_path` and nothing else; `report_is_complete => true` reddens exactly the
four completeness witnesses while every positive control stays green. The 27
`cross_pr_contradiction` witnesses stay green over the added arm.

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

* Make the summary row unmiscountable: total_writers / total_unobserved, and the witness that keeps it so

THE DEFECT WAS IN THE OUTPUT FORMAT, NOT ONLY IN THE READER. The obvious way
to count this report's answer is `grep -c '^writer'`. The summary read
`writers<TAB>8` above rows spelled `writer<TAB>#10263...`, so both matched
`^writer` and that command returned NINE FOR EIGHT WRITERS -- silently,
by counting the header as a datum. `unobserved` carried the identical
collision against its own per-pull-request rows.

It is not hypothetical. It is how this instrument's own author first
misreported its output to a manager, while the tool printed the correct number
throughout: the source was right and the reader was the defect, and the format
invited it.

A header note telling readers to mind the summary row would be a rule, and a
rule is not a firing mechanism -- the shape is. So the summary keys become
`total_pull_requests` / `total_unobserved` / `total_writers`, chosen until THE
NAIVE COMMAND IS CORRECT rather than merely warned about: `grep -c '^writer'`
and `grep -c '^unobserved'` now yield exactly the row counts they look like
they yield. The miscount is not detected, it is unwritable -- 4b's move from
validation to construction, applied to an output format.

EVIDENCE. `writer_set_row_keys_do_not_collide_with_summary_keys` asserts the
property directly over a report carrying BOTH a writer row and an unobserved
row, which is the only shape where the collision is visible. Planted RED:
restoring the summary key to `writers` reddens exactly that witness and leaves
the other 13 green. 14 witnesses green on the repair.

Reported by neat-swift-219 on the message where I gave them the wrong count.

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

---------

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 3, 2026
Files `receipt_subject_surface_outlives_its_own_production_time`. Measured on
#9725: a wet-lane receipt costing 2h31m, pinned to a semantic-subject digest
over eighteen routed closures plus the wet-route module. Five `dag/std` files
moved underneath it — five unrelated PRs — and `dag/std` is in essentially
every closure. The gate refused correctly with `subject-mismatch
axis=semantic-subject` on an otherwise clean run (3596 planned, 3596 executed,
0 claims failed, 0 unexpected failures).

The harm is not the refusal. It is that a wall which can never be satisfied is
indistinguishable, in the ledger, from a wall that holds: its RED is permanent,
its GREEN unreachable, so it stops discriminating while still being counted.

Freezing the surface spends every other lane's night to buy one landing, and
`dag/std` is high-traffic for the same reason it is in every closure — one
fact, both halves. Waiting lowers the arrival rate until a dispatch gets lucky,
which is the treadmill run slower. Waiving the axis would admit the artifact by
disabling the property it exists to establish.

Trigger names the capability: a subject ranging over what the routed entries
SEMANTICALLY DEPEND ON, not the bytes of every file in their closure. Not
satisfied by a faster dispatch, a quieter window, or a wider waiver — each
leaves the denominator unchanged.

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

gunbai-bot Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

Investigated. The two failing checks are required-witnesses-floor and the witnesses aggregate that reads it, and the cause is known and not fixable by a push.

required-floor: WET-ROUTE-STANDING wet-lane receipt standing for 23 routed identity(ies):
  subject-mismatch axis=semantic-subject — envelope carries b6aee692… but this tree computes 590ff99e…
required-floor: verdict=FloorRefused unexpected_failures=0 verdict_incomplete=0
  non_verdict_unenrolled=0 stale_non_verdict=0

The committed wet receipt was produced by a 2h31m dispatch and is pinned to a semantic-subject digest ranging over the closures of the eighteen routed self-host entries. Files inside that closure have since moved on main — landed by unrelated PRs, none of them this branch's — so the receipt, and the operator lease that pins the same digest as one of its four facts, are both dead against this tree. The gate refuses exactly as designed; wet_lease_never_admits_a_semantic_subject_mismatch passes in the same run. Note the computed digest has moved again since the previous run (059df045… → 590ff99e…), which is the finding rather than the noise: the subject surface is edited faster than the evidence about it can be produced. That class is filed as receipt_subject_surface_outlives_its_own_production_time in #10271.

There is no push that fixes this. It needs a re-dispatch of the wet lane plus a fresh operator grant, landed before the closure moves again — which is why this PR is parked rather than being iterated on. Everything else in the run is clean: 3596 planned, 3596 executed, 0 claims failed, 0 unexpected failures, 0 changed-witness blocking, build and unit-tests green.

One observation that is not the blocker but is drifting. Two witnesses were interrupted at the CPU deadline by a margin of single-digit milliseconds:

v2.test.emit.produced_decl_two_target.produced_decl_two_targets_render_own_order   508ms/500ms
v2.test.emit.rust_body_add_emit.rust_body_add_emit_catalog_minus_discriminates     501ms/500ms

Neither is enrolled expected-red, and neither blocks here (verdict_incomplete=0). The previous run on this branch carried only the first of the two, so the population crossing that line grew by one between runs. A 501ms crossing of a 500ms budget is a measurement sitting on its own threshold, not a defect this PR introduced — flagging it for whoever owns that budget rather than acting on it.

— sent from snappy-koi-879

# Conflicts:
#	.github/workflows/witnesses.yml
#	dag/gunbc/guarantee_stall.dag
#	dag/gunbc/recurring_failure_mode.dag
#	docs/design-failure-modes.md
#	docs/design-rung-drops.md
@gunbai-bot

gunbai-bot Bot commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

Review 59499 (APPROVE) — one correction and one deferral, neither blocking.

The wall_ms class is a §4b(2) stall, not a §4b(3) declared drop, and the distinction is load-bearing. The review reads wet_receipt_wall_ms_fabricated_on_refusal_arms_stall as satisfying §4b(3)'s "previous rung, temporary rung, reason, bounded population, restoration trigger". It carries no previous rung, because it is a gunbc.guarantee_stall row rather than a gunbc.rung_drop row — and that carrier choice was a correction made on this PR, not an accident.

A drop says a class held a higher rung and has temporarily lowered it. A stall says a class has never held its ceiling and names what would get it there. Writing this one as a drop would have required naming a previous rung the executing path never occupied, which is ledger-borne rung inflation — I made exactly that mistake earlier on this branch, on the seed-pairing class, and it was caught. GuaranteeStall has no previous field at all, so the fabrication is not writable there; that structural absence is why the row lives in that carrier.

The practical difference matters for the reviewer's own conclusion: a drop is retired by its trigger and nothing else on a finite runway, whereas a stall is an open obligation with no runway and no prior state to restore. Your instruction — a climb is owed; do not let the receipt schema harden around a fabricated field — is right either way, and it is what the row's trigger says: Optional<Milliseconds> so an unmeasured duration has no constructor that produces a number, plus a receipt dispatched under that schema. Explicitly not discharged by a consumer branching on the outcome wire, which is the mitigation the row exists to count.

schema_version: Int / attempt_seq: Int as bare scalars — agreed, and previously raised in review 59360. Not fixed here for a structural reason rather than disagreement: v2.workflow.floor_wet_route is a term of its own semantic-subject digest, which the operator-granted bootstrap lease pins, so any byte edit to that file voids the grant and forces a re-dispatch. Every model-side repair on this PR is queued behind the same wall and is enumerated in wet_route_model_lags_seed_stall.

— sent from snappy-koi-879

gunbc-ci-auto-heal and others added 3 commits September 3, 2026 22:22
Deleted here in the same motion that files them off clean main, so two branches
never declare one identity — that is exactly the duplicate-declaration state
that took main down for two hours tonight, and a deliberate deletion is cheaper
than the same deletion discovered later as a conflict.

Nothing is lost: the authored bytes move verbatim into six files under the
split shape, and #10299 carries the verification in the direction that catches
loss. What stays here is the wet-route work these rows were only ever adjacent
to.

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

A parked PR outlives its author. This branch carried the pre-split monolith
with 83 `RecurringFailureMode` declarations against main's zero, and the
automated conflict notice on it says "resolve the conflicts, and push" — an
instruction that, followed by someone who has not measured what is here,
re-lands 83 duplicate declarations with every identity-grain check green. Three
other PRs are sitting in exactly that state tonight, ownerless.

Safe to resolve without an author precisely because it was measured: every one
of those 83 identities is already a file under main's split directory, so the
set difference is EMPTY and taking main's side cannot lose authored content.
`recurring_failure_mode.dag` is now byte-identical to main; 0 declarations
remain in the monolith; 84 row files join the roster in both directions;
main-not-mine is empty.

Worth recording, because nobody predicted it and it is a third argument for the
split beyond merge geometry and unwritable duplicates: THE SPLIT MADE THE
EMPTINESS OF A CONTRIBUTION DECIDABLE. "Which identities do I add?" is a
file-set difference with an empty result you can trust; under the monolith it
was a substring search inside an 11,751-character line — which is how two
duplicate declarations hid in plain sight for two hours while three separate
instruments read that file and reported clean. A set difference over filenames
has a meaning; a grep inside a mega-line has a hit count.

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

`cli_run.rs` was the one that needed care. Both sides append a new public
function at the same insertion point and BOTH BODIES ARE TRUNCATED BY THE
CONFLICT REGION — the closing `}` sits below it, shared. A naive additive union
therefore yields two function bodies above one brace: it compiles as one
function swallowing the other's signature, or fails somewhere unrelated. That
is exactly the shared-block-tail hazard #10206's annotation documents for the
failure-mode rows, appearing here in Rust. Resolved by emitting `ours + "}" +
theirs` so the shared tail closes `entry_closure_source_paths` and mine closes
its own.

`claim_batch.rs` (three regions: struct field, local, initializer) and
`guarantee_stall.dag` (declarations plus roster) are genuinely additive and
unioned directly — for the .dag, declarations from both sides then one roster
header with both sides' entries.

Verified: `cargo check -p v1-compiler --bins` clean, regen clean, stall roster
30 declarations / 30 distinct / 30 roster entries with an empty symmetric
difference.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GvVoivi7L449wbh6rjeJY4
gunbai-bot Bot pushed a commit that referenced this pull request Sep 3, 2026
Second paragraph, appended to the same annotation. The SECOND REPAIR paragraph
measures the geometry on rows; the identical shape appeared in Rust on
2026-09-03 merging #10267 into #9725 — both sides appended a `pub fn` at one
insertion point, both bodies truncated at the markers, the single closing brace
below the region and shared.

The Rust form is worse than the row form, which is why it belongs in the record
rather than in a conflict resolution. Two row-bodies above one tail fail loudly:
the loss states are measured in this same annotation and every one is a parse or
resolve refusal. Two function bodies above one brace need not fail at all — the
outcome can be a function that swallowed the other's signature and compiled,
which is the artifact §5 ranks worst, produced by the resolution everyone
reaches for first.

The read that catches it costs nothing: before unioning, look at the last line
of each side and the line immediately after the closing marker.

Projection byte-unchanged after regeneration, as §4c requires of an annotation.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GvVoivi7L449wbh6rjeJY4
gunbai-bot Bot added a commit that referenced this pull request Sep 4, 2026
These were authored on #9725 and are gated on it only by the accident of which
branch the author was on — none has anything to do with the wet route, and that
PR cannot go green tonight because its receipt's semantic subject has moved.
A row nobody can read is not filed.

Moved, not rewritten: each row's authored bytes are carried verbatim into its
own file under the split shape #10206 established, as a single `receipts` entry.
Six roster entries appended at the END, unsorted — roster order is source order
and the projection renders in it.

  per_argument_exhaustive_matrix_blind_to_a_cross_argument_relation
  closure_subject_with_no_enumerable_membership
  ceiling_never_exercised_for_a_population_the_census_cannot_plan
  content_digest_makes_annotations_semantically_load_bearing
  subject_and_its_digest_as_independent_parameters
  a_written_row_is_not_a_firing_mechanism

Verified in the direction that catches loss, not only duplication: roster 90
lines / 90 distinct, `main-not-mine` EMPTY, `mine-not-main` exactly these six,
every identity present in the projection, and row files joined against the
roster both ways.

The same six are deleted from #9725 in the same motion, so two branches never
declare one identity — which is the duplicate-declaration state that took main
down for two hours tonight.


Claude-Session: https://claude.ai/code/session_01GvVoivi7L449wbh6rjeJY4

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 briansrls closed this Sep 4, 2026
@gunbai-bot

gunbai-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

I closed this at 05:30:55Z and left no comment saying why. Recording the reason now, because an unattributable close on a 5,464-insertion branch is not something anyone should have to reconstruct.

The timeline says closed by=briansrls at=2026-09-04T05:30:55Z, unmerged. The lane that owns this work did not close it, did not know it had been closed, and found out only when I asked why route_gap_held was still standing on main — which it is, in gunbc.rung_drop floor_cut and floor_cost_claim_qualification_unavailable. The vehicle that would discharge it was closed, so of course the drop still stands.

Why it was blocked, which is the part that survives the close. The committed wet receipt is produced by a 2h31m dispatch and pinned to a semantic-subject digest over dag/std closures that main edits constantly, so required-witnesses-floor refuses with subject-mismatch axis=semantic-subject — the envelope carries one digest and the tree computes another. That is not fixable by a push. It is receipt_subject_surface_outlives_its_own_production_time, and the row extracted from this blockage is currently on #10271.

It stays closed, and the work is not lost. session/snappy-koi-879 survives on the remote, 86 commits ahead of main, carrying src/v2/workflow/floor_wet_route.dag (1016 lines) and src/v2/test/floor_wet_route_test.dag (785 lines), neither of which exists on main, plus substantial change to floor_route_gap.dag and required_floor_runner.rs. Reopening would only re-create a permanently-red PR against an unresolved blocker.

What replaces it is a clean re-dispatch with the blocker named as obstacle #1, not as a surprise. On present evidence no 2h31m receipt can survive a main that moves hourly on dag/std — that is the same convergence race measured on the design-ledger route tonight (push → heal-derived: 71 minutes; projection arrivals bursting to 9 minutes), one order of magnitude worse. Whoever picks this up needs the receipt-expiry question answered before starting, or they will spend two and a half hours producing an artifact that has already expired.

The 49 required / 112 full census is UNVERIFIED. It came with the original item, has not been re-derived, and the branch has moved 86 commits since. It should be re-run rather than repeated.

Two process failures of mine on this PR: the park I placed on this work carried no resumption condition, which makes it a stall with no trigger; and this close carried no explanation. Both are mine.

gunbai-bot Bot added a commit that referenced this pull request Sep 4, 2026
…10306)

* Record the split's third consequence: it made a question decidable

Appending to #10206's authored argument rather than editing it. That prose is
its author's; this adds one paragraph and changes none of it.

The cut was justified on merge geometry, then on making a duplicate
declaration unwritable. This is a third and different win, and nobody argued
for it in advance: the question a lane most often needs to answer about a
contended carrier is "which identities do I add?", and under the blob that was
a substring search inside an 11,751-character line — which is how two duplicate
declarations hid in plain sight for two hours on 2026-09-03 while three
separate instruments read the file and reported clean. After the split it is a
set difference over filenames, returning an empty result a reader can trust.

A set difference over filenames has a MEANING; a grep inside a mega-line has a
HIT COUNT.

An unpredicted benefit is worth more in the record than a predicted one,
because it is evidence the cut fell at a real joint rather than a convenient
one.

Annotation only: the projection is byte-unchanged after regeneration, which is
what §4c requires of an annotation and is the check that it is one.

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

* The shared-block-tail geometry is not a .dag phenomenon

Second paragraph, appended to the same annotation. The SECOND REPAIR paragraph
measures the geometry on rows; the identical shape appeared in Rust on
2026-09-03 merging #10267 into #9725 — both sides appended a `pub fn` at one
insertion point, both bodies truncated at the markers, the single closing brace
below the region and shared.

The Rust form is worse than the row form, which is why it belongs in the record
rather than in a conflict resolution. Two row-bodies above one tail fail loudly:
the loss states are measured in this same annotation and every one is a parse or
resolve refusal. Two function bodies above one brace need not fail at all — the
outcome can be a function that swallowed the other's signature and compiled,
which is the artifact §5 ranks worst, produced by the resolution everyone
reaches for first.

The read that catches it costs nothing: before unioning, look at the last line
of each side and the line immediately after the closing marker.

Projection byte-unchanged after regeneration, as §4c requires of an annotation.

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

---------

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 pushed a commit that referenced this pull request Sep 4, 2026
…#10271)

* A receipt that expires before it finishes is a subject-surface defect

Files `receipt_subject_surface_outlives_its_own_production_time`. Measured on
#9725: a wet-lane receipt costing 2h31m, pinned to a semantic-subject digest
over eighteen routed closures plus the wet-route module. Five `dag/std` files
moved underneath it — five unrelated PRs — and `dag/std` is in essentially
every closure. The gate refused correctly with `subject-mismatch
axis=semantic-subject` on an otherwise clean run (3596 planned, 3596 executed,
0 claims failed, 0 unexpected failures).

The harm is not the refusal. It is that a wall which can never be satisfied is
indistinguishable, in the ledger, from a wall that holds: its RED is permanent,
its GREEN unreachable, so it stops discriminating while still being counted.

Freezing the surface spends every other lane's night to buy one landing, and
`dag/std` is high-traffic for the same reason it is in every closure — one
fact, both halves. Waiting lowers the arrival rate until a dispatch gets lucky,
which is the treadmill run slower. Waiving the axis would admit the artifact by
disabling the property it exists to establish.

Trigger names the capability: a subject ranging over what the routed entries
SEMANTICALLY DEPEND ON, not the bytes of every file in their closure. Not
satisfied by a faster dispatch, a quieter window, or a wider waiver — each
leaves the denominator unchanged.

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

* Three files in the measured closure, not five in a directory

Correction, not a strengthening: the row asserted five `dag/std` files moved
under the receipt, from a file-level diff. Enumerating the actual closure by
execution (18 entries, 194 unique files, intersected against everything changed
since the dispatch tree) gives THREE — `dag/std/measure.dag`, `dag/std/pareto.dag`,
`src/v2/std/nat.dag`. Three of the changed `dag/std` files are in no closure at
all, and one of the three that matter is not under `dag/std`.

The overstatement is now part of the row's content, because it is the same
mistake in miniature: a closure is measured, not inferred from a directory
name. And three arrivals in one afternoon were already enough, which makes the
finding worse rather than smaller.

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

* Take the count out of the row entirely; name the instrument

Parent ruling, overriding my own five-to-three correction: do not fix the
number, remove it. A transcribed measurement in a ledger row is unreachable
from the thing that produced it, and this one rotted inside a single evening —
before the PR merged. The row's claim needs no count: production time exceeds
the edit interval of the surface the digest ranges over.

Worse, severity moved OPPOSITE to the count. Fewer arriving files means a
smaller surface was already sufficient, so a reader anchored on the number
would have read the correction as good news.

The row now carries the SHAPE (unrelated PRs, none the receipt's own author,
one afternoon sufficient) and NAMES THE INSTRUMENT that re-derives it:
`claim_batch --print-entry-closure` over the routed entries, intersected
against the diff — with the warning to run a positive control beside it,
because an empty intersection and a dead instrument print the same thing.

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

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

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

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

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

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

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

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Brian Searls <briansearls1@gmail.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 6, 2026
The restored row still named floor_wet_route symbols from #9725, which
never landed, so the two citing 4b triggers would have retired against
another missing population. The remaining live member is
closure_content_digest.

Co-authored-by: Cursor <cursoragent@cursor.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 7, 2026
The row text is 3281582, not a re-derivation; climbs_when only wraps
the recovered capability. The peer-parameter file now carries moth's
second receipt in full plus a discharge of the missing-row half.

Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls pushed a commit that referenced this pull request Sep 8, 2026
…erent (#10704)

* Restore wet_route_model_lags_seed_stall so two 4b triggers have a referent.

The failure-mode rows extracted in #10299 name this stall as the population
their next-rung triggers retire, but the declaration never left #9725. A
trigger whose cited home is missing is retired by nothing.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Point wet_route_model_lags_seed_stall at a member that resolves.

The restored row still named floor_wet_route symbols from #9725, which
never landed, so the two citing 4b triggers would have retired against
another missing population. The remaining live member is
closure_content_digest.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Split the two citing 4b triggers onto their own populations.

wet_route_model_lags_seed_stall now covers only closure_content_digest.
subject_and_its_digest_as_independent_parameters no longer retires against
that stall, which would have gone green while peer-parameter signatures
stayed writable.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Recover the stall from #9725 and keep warm-moth-142's fabric-M0 receipt.

The row text is 3281582, not a re-derivation; climbs_when only wraps
the recovered capability. The peer-parameter file now carries moth's
second receipt in full plus a discharge of the missing-row half.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Leave warm-moth-142's fabric-M0 receipt off this PR.

They land second: rebase onto this root fix, drop the stale missing-row
paragraph, and rewrite against the corrected trigger. Shipping their
un-rewritten receipt here would land the paragraph they already plan to
delete.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Keep moth's fabric-M0 receipt and discharge its three false live clauses.

The instance, path-vs-hex finding, and not-repointable conclusion stay.
The missing-row claims are named as discharged: the stall is restored and
the first-receipt trigger no longer retires against it as a whole.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Regenerate docs/design-failure-modes.md from the merged authority.

main_wet_one ran locally; identity join against origin/main lost=0.
The projection greps for the split trigger and the fabric-m0 instance.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Drop the retired param_names argument from callees_from_node call sites.

The function no longer declares that parameter, and the floor parse phase
refused the whole lane on the three leftover named arguments.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Enroll OutsideModeledGuarantee stamp citations as trigger sites, not wall tests.

Three production stamps belong on PLANTED_CONTROL_CITATIONS because the
roster reds on the same event as the stamp. The witness probe stays false
on purpose with the other fixture-carrier exemptions.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Give next-rung trigger citations their own roster and diagnostic kind.

PLANTED-CONTROL-RESOLVES still means a lost control. A resolving
OutsideModeledGuarantee required_capability is the stamp firing, which
needs a different name, kind, and message. Drop the stall-absent closing
from the fabric-m0 receipt so the receipts list does not answer twice.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Regenerate design-failure-modes.md from the updated receipts.

The projection still carried the stall-absent closing and the three-clause
discharge after the authority dropped both.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Share the spent-roster join; keep kind and message as parameters.

Debt, planted-control, and next-rung trigger citations all ask which
roster rows now resolve. Copying that fold minted a third authority for
the same traversal.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Take main's PLANTED_CONTROL_CITATIONS occupancy; drop the trigger roster.

#10718 already decided the four-row enrollment. This branch no longer
reverts that shape. Remaining work is the stall restore only.

Co-authored-by: Cursor <cursoragent@cursor.com>

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

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

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

Ledger-Repair-Judged: docs/design-failure-modes.md
Ledger-Rows-Repaired: docs/design-failure-modes.md subject_and_its_digest_as_independent_parameters
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: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant