Skip to content

Derive admission consumption from exact candidate sets - #11165

Merged
gunbai-bot[bot] merged 5 commits into
mainfrom
session/quick-carp-281
Sep 12, 2026
Merged

gunbai-bot[bot] merged 5 commits into
mainfrom
session/quick-carp-281

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 12, 2026 •

Copy link
Copy Markdown
Contributor

A binding admission could authorize a multi-member result but never prove it consumed: Binding.target named one module and the consumption predicate required a singleton. #11137 (34d2a8d) documented a three-to-two narrowing, so its promised CONSUMED outcome was unreachable and it instead reported STALE on unrelated PRs. This was a structural lifecycle defect, not evidence of neglect.

Binding admissions now author the exact expected candidate set. The evaluator checks equality against the head before granting admission, rejecting extra or missing members with expected/observed diagnostics; it reuses that proof at the base to derive consumption. The current row no longer predicts a lifecycle verdict in prose. Lifecycle output comes from evaluation; historical wrong predictions remain incident receipts. The authored namespace-delta disposition remains, because it specifies which semantic change is permitted and is a different concept.

Main's equal-base/head path now checks a nonempty roster and refuses with row labels, the source path, and a deletion remedy. Proven consumed rows also retain their roster-edit refusal. Stale rows and unadjudicated deltas refuse every PR: the earlier blanket exemption for inherited stale rows is removed. The spent #11137 row is deleted under the roster's existing shrink rule; deleting too early exposes an unadjudicated delta rather than failing open.

Update the existing a_written_row_is_not_a_firing_mechanism receipt with both directions of mistaken prediction (the sixteenth-entry STALE prediction that evaluated CONSUMED, and #11137's inverse), the older 53/314/#9689 recurrence history, and #10994/#11014/#11162's structural refusals, including #11162's byte-identical inherited source. Policy remains in gunbc.namespace_wave_admission.namespace_wave_admission_note; no new host declarations are added.

Validation: formatting and diff checks pass. After CI exposed an unescaped literal brace in the failure receipt, 483b9f2 corrected the string; v1_src_dag_parse passed with all 5,606 files parse-clean on that head (remote run). The revised admission suite passed all 54 tests (remote run), covering three-to-two admission, two-member consumption, extra/missing members at both head and base, named mismatch diagnostics, singleton safety, stale refusals, and landing remedies. After that test snapshot, result rendering was simplified from an is_ok/unwrap_err branch to a match and its consumed-row text was clarified. Targeted cargo clippy -p v1-compiler --test namespace_wave_admission -- -D warnings passed on the final implementation (remote run).

Limits: main enforcement awaits execution of its push run; this is not synchronous Git retirement. No PR-number parsing or API lookup is introduced. Removing the current predicted sentence does not make arbitrary future prose impossible; the class receipt states that remaining limit explicitly. Observed self-refusal of the earlier roster-editing head: run 34683145465, floor job 103525348594, PR head acf2ba9 tested as merge 49da49b against 0c93af0. The namespace phase reported zero deltas, one STALE admission and zero CONSUMED admissions; its final refusal named #11137 and the deletion action, with floor_class=structural. This validates that earlier roster-edit refusal and remedy, not the subsequent exact-set implementation; the current head has its own test/CI obligations.

@gunbai-bot

gunbai-bot Bot commented Sep 12, 2026

Copy link
Copy Markdown
Contributor Author

Verified review 64466 against the current head: the retained #11137 row does make this roster-editing PR owe deletion, so this head is not merge-ready. That is already an explicit dependency in the PR body, not a claim that the debt is discharged.

The assignment and parent explicitly prohibit a fifth independent deletion and direct this lane to integrate the already-owned cleanup, likely #11162. I will merge main once that deletion lands, which removes the row from this PR's resulting tree and satisfies this finding before asking for merge. I am keeping the refusal armed while waiting. No passing CI or observed production self-refusal is claimed yet.

— sent from quick-carp-281

@gunbai-bot

gunbai-bot Bot commented Sep 12, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 64466 in bf3681b: removed the spent #11137 admission, leaving the roster empty. The parent authorized carrying this shared deletion if the existing cleanup had not landed when the committed-head test run finished; that condition occurred. Also merged current main. All 53 admission tests, including named-remedy controls, passed on acf2ba9 before the data-only deletion: https://app.buildbuddy.io/invocation/18dd8cfd-7e89-44eb-94d1-14acdf98ec69 . The earlier production self-refusal remains a prediction, not an observed receipt.

@gunbai-bot gunbai-bot Bot changed the title Charge stale admission roster debt to its landing Derive admission consumption from exact candidate sets Sep 12, 2026
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
…sposition

My dissolution record ended by proposing that retirement be derived from the
merge rather than written in a sentence. That work already exists: gunbc#11165,
"Derive admission consumption from exact candidate sets", checks
Binding.expected_candidates by equality at head before admission is granted,
derives consumption from the same proof at base, and removes the hand-written
lifecycle prediction so the evaluator prints the computed disposition.

So the paragraph would have been stale the moment that lands, and worse, it read
as my proposal for something someone else had already built. It now states the
defect as it stood today and NAMES the fix as a declared frontier with its
trigger beside it: when #11165 lands, a row's retirement stops being a sentence
anyone has to honour, stale means NEGLECT rather than structural impossibility,
and the unreachable-CONSUMED shape becomes unwritable rather than documented.

Verified the PR's subject and files before citing rather than relaying the
description.

The recurring_failure_mode row this PR carries is untouched and is not
duplicated by #11165's: mine is a diagnostic asserting a standing nothing
evaluated, theirs is a written row not being a firing mechanism. Neighbours, not
one claim.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AQGTwRrSBe8r3bmR3epQsL
@gunbai-bot
gunbai-bot Bot merged commit 8bc6ec1 into main Sep 12, 2026
4 checks passed
@gunbai-bot
gunbai-bot Bot deleted the session/quick-carp-281 branch September 12, 2026 10:27
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
Fresh floor against current main (namespace-wave STALE row gone). Does not change the canary delta.
@briansrls
briansrls restored the session/quick-carp-281 branch September 12, 2026 10:32
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
Take main's namespace-wave admission file (#11165 candidate-set shape, empty roster). Re-author the 17 sizing TargetChanged rows with expected_candidates as the head sets the required floor printed for those identities.

Co-authored-by: Cursor <cursoragent@cursor.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
The roster was already empty on both sides -- this branch retired the #11137
admission one commit earlier, main retired it in #11165 -- so the only conflict
was the doc comment recording the retirement. Main's text is taken as the
authority's record. No code changed.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NQnvBvFGNu9tNL544NJe2j
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
Main landed #11165, which replaced `AdmissionSubject::Binding`'s
`target: &str` with `expected_candidates: &'static [&'static str]` -- the
EXACT candidate set after the admitted transition, checked at the head
before admission and at the base to derive consumption.

The 37 `string_eq` rows are rewritten to it. Each names
`&["v2.std.text"]`, which is the whole post-transition set for these
sites, not merely one member of it: after the collapse exactly one module
declares `string_eq`, so the singleton IS the set and the stricter check
is satisfiable rather than merely tolerated.

That schema change is a strictly better instrument for what these rows
claim. The old `target` field was documentation -- `admission_subject_matches`
ignored it, matching on module, declaration and spelling alone -- so a row
could name any target and still match. The new field is checked, which
means a row whose transition does not land exactly where it says now
fails instead of passing quietly. I would not have caught a wrong
`target` in the old shape; I would now.

ALSO IN THIS MERGE: main has already retired the `gunbc#11137` row and
recorded the retirement, so nothing is re-deleted here. That deletion was
owed once and four branches reached it independently; main is where it
landed, and this branch simply adopts that history.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
Main landed #11165, replacing `AdmissionSubject::Binding`'s `target`
with `expected_candidates` -- the EXACT candidate set after the admitted
transition, checked at the head before admission and at the base to
derive consumption.

Both rows are rewritten to it, with the sets read off the floor's own
delta lines rather than shortened to the winner:

  extdeps.provisioning.ubuntu_seeded_install_media_remaster --
  five modules. The base carried
  `extdeps.filesystem.filesystem_io` as a SIXTH candidate and the
  narrowed import drops it; the surviving five are the module itself,
  `extdeps.shell`, and the three `extdeps.tools.*` it imports.

  gunbc.srv3_boot_once_cd -- one module. base {} -> head
  {extdeps.filesystem.filesystem_io}: the name resolved to nothing the
  author had named and now names its declaring module, so the singleton
  IS the set.

THE SCHEMA CHANGE IS A BETTER INSTRUMENT FOR WHAT THESE ROWS CLAIM, and
worth saying so rather than treating it as churn. `target` was
documentation -- `admission_subject_matches` ignored it, matching on
module, declaration and spelling alone -- so a row could name any target
and still match its delta. `expected_candidates` is checked, so a
transition landing anywhere other than where the row says now fails
instead of passing quietly. My first row named
`extdeps.provisioning.ubuntu_seeded_install_media_remaster` as its
`target` and would have matched regardless of the other four survivors;
under the new field that shortcut is not available, which is the point.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
briansrls pushed a commit that referenced this pull request Sep 12, 2026
…'s

A sibling lane landed the identical gunbc#11137 row deletion first, so
src/v1/stage0/src/namespace_wave_admission.rs conflicted. Resolved to MAIN's
version of that file verbatim, which is this file's own documented convention for
the case -- the note above the thirty-fourth entry records "THIS BRANCH'S OWN
DISSOLUTION ENTRY FOR THE gunbc#10324 ROWS IS DROPPED, NOT RENUMBERED" for exactly
this collision. My THIRTY-SIXTH DISSOLUTION entry is therefore dropped rather than
renumbered or merged alongside.

TAKING MAIN'S SIDE IS NOT A SHORTCUT HERE, IT IS THE BETTER AUTHORITY. gunbc#11165
("Derive admission consumption from exact candidate sets") landed in the same range
and rewrote the retirement note itself, so main's copy carries the mechanism
owner's own words plus the evaluator change behind them. Taking my side would have
reverted that code.

AND #11165 ANSWERS THE QUESTION MY DISSOLUTION RECORDED AS UNVERIFIED. I noted that
the row reported STALE where #9824's ConsumedByMerge looked applicable, said I had
read none of that code, and left it to the mechanism's owner. Their note gives the
cause: "The old sentence predicted CONSUMED for a two-member result that the
singleton proof could never accept" -- the consumed proof required a singleton
candidate set and this row's was two-member. The symptom was real, the restraint
was right, and the repair belonged where it landed.

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

Co-authored-by: Cursor <cursoragent@cursor.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
The required floor refused on a stale #11137 namespace-wave admission; main already retired that row in #11165.
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
…ollision

MERGE. origin/main at 8bc6ec1 merged with a merge commit (no rebase). One
conflict, src/v1/stage0/src/namespace_wave_admission.rs.

#11165 CHANGED THE SHAPE, NOT THE SPELLING. AdmissionSubject::Binding no longer
carries `target` (the single module a spelling now binds); it carries
`expected_candidates`, the EXACT candidate set after the transition. That
difference is the point of the change: `target` named a winner and could not see
a second candidate standing beside it. All 181 rows on this branch used
`target`, so converting them is mechanical in FORM and a CLAIM in SUBSTANCE --
each singleton asserts the named module is the ONLY candidate at that site.

THE CLAIM IS GROUNDED BY EXECUTION, NOT BY THIS MESSAGE. An earlier revision of
this work converted every row to a singleton and annotated that the wrong ones
would "refuse loudly, which is their own repair". That is authoring rows their
author expects to be wrong: a refusal you predict is not a resolution. The
witnesses lane was run against the merged tree instead:
  namespace-wave-admission ADMITTED — every delta is auto-admitted or named by
  a transition admission
with all 181 rows ADMITTED and ZERO expected-versus-found mismatches, each row
printing its own sets (base {A} -> head {B}). Reconfirmed on a second
independent run. No site turned out to have a two-member set; the singletons are
verified rather than assumed, which is a different state from being correct.

Main's roster is empty at the base and that empty state is preserved as main
authored it, with this PR's still-required admissions authored into it -- 181 is
what remains required, not a target.

RECURRING FAILURE MODE FILED: a_shared_probe_root_lets_one_run_compile_anothers_source.
Two route runs on one host materialize their generated crate into a directory
keyed by WHAT is built, not WHO builds it. Measured here: a baseline run of the
base revision and a successor run of this branch ran concurrently; the successor
refused EmittedCompilerBuildFailed with E0063 naming three missing cost-row
fields, and the emitted main on disk was the BASE revision's, written minutes
earlier by the baseline. The wrong verdict was computed against an innocent tree.

THE ROW SAYS THE MECHANISM EXISTS AND ONE CALLER BYPASSES IT, because a first
draft of it claimed no lock existed and that was FALSE.
gunbc.emitted_closure_compile_host acquire_probe_root_lock takes an exclusive
lock and refuses a concurrent run with a typed located cause, and its annotation
argues the design; run_required_emit_compile takes it. The v2-native route
selects the same root through lane_emit_compile_probe_root and acquires nothing.
So the ceiling is structural and most of the distance is already travelled -- a
selector returning an OWNED root leaves no spelling by which a caller holds the
path without the exclusion -- and the trigger refuses the tempting repair:
adding the lock call to the one bypassing caller fixes this instance and
discharges nothing.

VERIFICATION, stated at its actual grain: the witnesses lane is green
(FLOOR_EXIT=0) on a tree identical to this one except for this row's string
contents, and this exact tree completes --required-regen (REGEN_EXIT=0,
first_generation_equal=true, no drift), which compiles the whole corpus and is
what a malformed row would break. Two earlier floor runs refused on two
local-repo-wet witnesses; the cause was neither TMPDIR nor this tree but a
missing target/release/gunbc in the worktree -- those witnesses shell out to
`gunbc compile` to write the probe crate's main.rs, so with no generator cargo
reports `can't find bin witness` and names the wrong subject.

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

THE SAME RECEIPT WAS DELETED TWICE, and the second time is the one worth
recording, because I had already fixed it once and repeated it anyway.

My first resolution of this conflict removed 36 of main's doc lines,
including `THE gunbc#10671 ROWS DISSOLVED HERE` -- the adjudication
carrying the three-direction join that ESTABLISHED consumption for those
four rows rather than asserting it. That is the identical loss review
64522 caught on the wall branch an hour earlier, from the identical
cause: resolving by replacing a REGION of the doc chain rather than by
taking a SIDE, which silently swallows text neither side was in conflict
about.

It was caught this time by the check that failure produced -- counting
main's deleted doc lines before committing -- not by noticing while
editing. The habit is what worked; the instinct had not changed.

RESOLVED THE WAY THAT WORKS: take main's file whole, then add this
change's two rows and their adjudication to it. Nothing of main's is
re-derived, so nothing of main's can be lost. Verified the same way:
`git diff origin/main` deletes ZERO of main's doc lines.

Both rows carry `expected_candidates` on #11165's exact-set schema, with
the sets read off the floor's own delta lines: five surviving modules for
the `ubuntu_seeded_install_media_remaster` anchor narrowing, and the
single declaring module for the `srv3_boot_once_cd` resolution.

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

0 participants