Skip to content

Namespace wave admission: the owner's merge_group run owes its consumed rows' deletion follow-up (carrier for the push-on-main cut) - #11250

Merged
briansrls merged 17 commits into
mainfrom
session/deep-otter-836-consumed-row-owner
Sep 16, 2026
Merged

briansrls merged 17 commits into
mainfrom
session/deep-otter-836-consumed-row-owner

Conversation

@gunbai-bot

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

Copy link
Copy Markdown
Contributor

Carrier for the merge-queue cut (lane ruling C by fierce-lark-661). Must land before PR 2 of #11238's pair, which cuts the push-on-main floor run.

Why

Under the merge queue the required verdict moved off the push to main, and that push run was the only run where base == head. That is where a consumed transition-admission row came due without a roster edit. The census for #11238 observed this on three landings:

  • Push-on-main runs 34736430057, 34738796445 and 34740995720 FAILED namespace-wave-admission on the two consumed gunbc#11156 rows.
  • Merge_group runs 34736430682 and 34738796806 printed the same rows as CONSUMED and ended ADMITTED.

Cutting the push run as things stand would make that debt silent (eager-raven-113's requirement).

Charging the deletion to the next PR in the queue was rejected. The UNUSED-ROW SPLIT annotation in this module already priced that as §5 externalized degradation (gunbc#9824).

The ruling charges the owner instead, at the one run where the obligation is known. A row a candidate USES is proven satisfied at the candidate by the head check in adjudicate, so its consumption on landing is known at the owner's own merge_group run.

What changes

  • TransitionAdmission.deletion_follow_up: DeletionFollowUp (NotAuthored | PullRequest(n)). The owner authors it before enqueue.
  • WaveAdmissionOutcome::Adjudicated.event: AdjudicationEvent, parsed from GITHUB_EVENT_NAME by adjudication_event_from_name. An event this policy does not model refuses rather than borrowing a policy.
  • TransitionAdmission.owner_pull_request: u32: the owner a receipt names, typed rather than read out of the label's gunbc#N convention.
  • wave_admission_refusal gains two arms. Both are merge_group only:
    • OwnerFollowUpAbsent: a row this composition uses, with no follow-up authored, refuses and names the row.
    • ConsumedRowOwnerChargeBypassed (backstop): a base-consumed row whose owner authored no follow-up, on a composition that does not touch the roster, refuses. It says the debt is not this change's and names the owning change.
  • Owned consumed rows are receipts, not refusals (lane ruling X, after review 65313). A base-consumed row with an authored follow-up is a typed ConsumedRowReceipt { label, owner_pull_request, deletion_follow_up_pull_request }, printed on every run as CONSUMED ROW RECEIPT row=… owner=gunbc#N follow_up=gunbc#M.
  • Unchanged: pull_request runs.
  • Frontier, seen rather than missed: the pre-queue roster-touched and base == head arms still refuse on owned consumed rows under the Namespace admissions: split ConsumedByMerge from UnmatchedAdmission — cleanup billed to the roster, not bystanders #9824 next-touch rule. X's principle reaches them, and that is a separate change: those arms are Namespace admissions: split ConsumedByMerge from UnmatchedAdmission — cleanup billed to the roster, not bystanders #9824's authority, with their own rationale (the toucher is already editing the roster).
  • The deletion PR clears it: its composition touches the roster and carries no row, so it is admitted.
  • The roster is empty on main (Delete the two consumed gunbc#11156 admission rows #11240 deleted the two gunbc#11156 rows), so no existing row needs a follow-up authored.
  • gunbc.namespace_wave_admission namespace_wave_admission_note states the new policy.
  • The seed-growth justification enumerates the 4 new hand declarations (DeletionFollowUp, AdjudicationEvent, adjudication_event_from_name, ConsumedRowReceipt) and what was avoided: an inlined render helper, and no second ledger. It also names the §3 residue: AdjudicationEvent re-spells event names extdeps.github.actions carries.

Review 65313 and lane ruling X: the window, corrected

An earlier head of this PR, and the ruling it implemented, claimed the owner arm and the backstop were exclusive, so a bystander red could only mean the owner's charge was bypassed. That was false.

  • The owner's charge establishes that a follow-up number is authored, not that the deletion has landed.
  • So between the owner's landing and its follow-up's landing, every composition saw the row consumed at its base.
  • The backstop then refused those bystanders: §5 externalization re-entering through the window. Review 65313 found this, and it was verified against the code.

Ruling X (fierce-lark-661, 2026-09-13): an owned consumed row is a typed receipt, and only an unowned consumed row refuses a bystander.

The executed fixture: an_owned_consumed_row_is_a_receipt_on_a_bystanders_merge_group_run_not_a_refusal. It is one consumed row with a follow-up authored, on an unrelated merge_group composition. It is admitted with the receipt under X, and refuses when the pre-X backstop arm is restored (mutation run below). an_unowned_consumed_row_on_a_bystanders_merge_group_run_refuses_naming_the_owing_change keeps the genuine bypass red.

This is not a §4b(3) rung drop. The previous behaviour was a mis-billing of a cost to a principal that did not cause it, not a guarantee, so no drop row is filed. Reviewers: please do not file one.

The residual, and its named consumer

A follow-up that never lands is not observable from inside one run. Its forge state is:

  • OPEN = a declared frontier, and a receipt;
  • CLOSED unmerged = the row is an orphan and must refuse at its next touch;
  • MERGED with the row still present = the deletion landed without deleting, and must refuse.

The ruling offered two homes for reading that. Chosen: the landing tally, which already reads GitHub. The wave-admission fold is Rust seed code that reads no forge, and adding a forge read to it is out of proportion. So this binary checks only that a follow-up number is authored and prints the receipt on every run. The tally reads the three states and is the named consumer of the residual.

Evidence

Executed remotely on this head's tree:

  • cargo test --release -p v1-compiler --test namespace_wave_admission: 61 passed, 0 failed.
  • cargo clippy -p v1-compiler --bin claim_executor --test namespace_wave_admission -- -D warnings: clean. An intermediate tree failed large_enum_variant once the report grew; WaveAdmissionOutcome::Adjudicated.report is now boxed rather than the lint allowed.

Mutation run (ruling X, condition 3): bypass_due restored to the pre-X arm, which refuses any consumed row, on the remote copy only.

  • an_owned_consumed_row_is_a_receipt_on_a_bystanders_merge_group_run_not_a_refusal FAILED ("an owned consumed row must not bill the bystander for the owner's window").
  • an_unowned_consumed_row_on_a_bystanders_merge_group_run_refuses_naming_the_owing_change passed.
  • So the window fixture refuses under the old arms and is admitted under X. The correction is executed, not described.

Rows:

  • RED: the_owners_merge_group_run_refuses_a_used_row_without_a_deletion_follow_up.
  • Positive control, case (3): the_owners_merge_group_run_admits_a_used_row_whose_follow_up_is_authored. A still-needed transition row stays green once its follow-up is authored.
  • a_used_row_without_a_follow_up_does_not_refuse_the_pull_request_run.
  • The window, under X: an_owned_consumed_row_is_a_receipt_on_a_bystanders_merge_group_run_not_a_refusal (admitted, with typed receipt).
  • The genuine bypass: an_unowned_consumed_row_on_a_bystanders_merge_group_run_refuses_naming_the_owing_change, plus the same report admitted on pull_request.
  • Clearing case: the_deletion_follow_ups_merge_group_run_is_admitted.
  • an_unmodeled_ci_event_refuses_rather_than_defaulting.

⚠️ No CI step runs these Rust tests. That is the declared drop gunbc.rung_drop rust_unit_tests_off_the_merge_path. The remote runs above are their execution; the build lane's clippy compiles them.

Ordering

#11240 merged (6e70be2) and deleted the two consumed gunbc#11156 rows, and main is merged into this branch. The roster is now empty, so this PR's own roster touch carries no consumed debt.

🤖 Generated with Claude Code

https://claude.ai/code/session_014MgTfNcF7rBmb8zZhNTk1X


Ruling A/B repairs (fierce-lark-661, side-chat turn 71546a7c) — head 10c40db97b6

A — the receipt printer is observational, and the retained arms are pinned. claim_executor's report_wave_admission_outcome printed owned and dispatched, not refused for every owned receipt. It runs before wave_admission_refusal and reads neither the event nor roster_touched, so on a run that the retained roster-touch or base == head rule refuses, it asserted not refused over a refusal; dispatched also claimed a forge fact this binary never reads. The typed receipt and its ids are unchanged; the explanation now states only what the run establishes — the follow-up number is declared, and its existence, state and deletion scope are not established here — and leaves the verdict to wave_admission_refusal. No policy is duplicated in the printer, and X is not widened to make the old sentence true.

B — two annotations promised the pre-X backstop. DeletionFollowUp's RUNG, STATED HONESTLY paragraph said an invalid authored number that escapes the tally is caught by the bypass backstop. Under X it is not: any PullRequest(n), valid or fabricated, enters the owned population, and the backstop reads only consumed_without_follow_up. Both sites now state the subject as it is — the backstop covers the absence of an authored follow-up number, not the invalidity or lifecycle of one; reference verification is the landing tally's, and its failure is not independently caught here. The AdjudicationEvent intro's claim that a base-consumed row on a composition can only mean the charge was bypassed is the inference review 65313 disproved, and is corrected in place. No algorithm change.

Executed evidence at this head. an_owned_consumed_rows_receipt_coexists_with_the_retained_roster_and_base_equals_head_refusals exercises both retained-policy cases: the same owned row yields its typed receipt and the retained refusal, on roster_touched and on base == head. Discriminating red: widening consumed_due to skip owned rows makes that fixture the only failure (61 passed, 1 failed); restored, 62 pass. These tests are compiled by the required clippy step and executed by no CI step (declared drop rust_unit_tests_off_the_merge_path), so they were run on a remote dispatch at this head rather than cited through a green that does not cover them.

Terminology, kept exact. The required run's namespace-wave-admission base=… head=… modules_compared=5661 … deltas=0 ADMITTED is not WaveAdmissionOutcome::NoSubject. It is an evaluated comparison over 5661 modules that found no delta — and therefore presented no stimulus to the owner/window decisions this PR changes. Both facts stand: the production path executed, and it discriminated nothing about X.

Not receipt-neutral. claim_executor.rs here is executable stage0 (CI-event acquisition feeding the production gate), unlike the string-note class of #11207, so the landing packet owes the srv2 composition receipt (overlay → proposed tip across manifest, src/v1 and tests) at this head. eager-raven-113 has the head for slotting; it queues behind the open srv2 reach escalation.


Native-receipt exemption (landing side chat, turn be0a86fc) — head 0b4ae4d47ca

This change is exempt from the pre-landing native composition receipt: namespace_wave_admission.rs and claim_executor.rs are floor/harness code outside the emitted-compiler closure. Against the six intersecting classes, none is intersected:

  1. Emitted-closure reachability — not intersected. The module is named in src/v2 only as seed-retained: src/v2/compiler/self_host/stage0_crate_layout.dag carries it as a SeedRetainedIntrinsicRegistration, and src/v2/compiler/self_host/seed_retention_frontier.dag as retained_reason_elsewhere(path: "src/namespace_wave_admission.rs", cause: SeedRetainedIntrinsicSource). Both rows are per-file and this diff adds no file and removes none, so neither row moves.
  2. Emission path — not intersected. No emitter, template, or emitted artifact is touched; the one generated artifact in the diff's blast radius (witnesses.yml) is not part of this change at all.
  3. compiler_entry / driver — not intersected. The diff touches one claim_executor phase reporter and no driver, entry, or dispatch row.
  4. Native harness — not intersected. The two test files are seed integration tests compiled by the required clippy step; no harness, fixture universe, or driver row is added or altered.
  5. Universe producer — not intersected. src/v2/workflow/floor_subject_seed.dag cites "the consumption relation namespace_wave_admission already computes"; this change adds the owner-charge partition over deletion_follow_up and does not alter closure, subject-membership, or binding computation, which is what that relation consumes.
  6. Classifier — not intersected. NamespaceDeltaDisposition and the delta classification are untouched; the new arms partition admission rows, not deltas.

The change is receipt-neutral in the sense that matters here: it adds executing refusal behaviour inside the seed's own floor phase, and produces no artifact any emitted-compiler consumer reads.

…er at the owner's merge_group run

A row a candidate uses is satisfied at the candidate, so its consumption on
landing is known at the owner's own merge-queue run. That run now refuses a used
row whose owner authored no deletion follow-up (OwnerFollowUpAbsent). A
base-consumed row on a bystander's composition refuses as
ConsumedRowOwnerChargeBypassed, naming the owing change and its follow-up.
Pull-request runs are unchanged. Lane ruling C (fierce-lark-661).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014MgTfNcF7rBmb8zZhNTk1X
@gunbai-bot

gunbai-bot Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

Floor red on run 34744050262. Two causes, neither a defect in this change's logic:

  1. namespace-wave-admission: 2 consumed gunbc#11156 rows due. This is the ordering stated in the body. This PR touches the roster file, so under the existing roster-touched rule the consumed rows come due on its own run. Delete the two consumed gunbc#11156 admission rows #11240 deletes exactly those rows. This PR merges main after Delete the two consumed gunbc#11156 admission rows #11240 lands, and the rows (with their PullRequest(11240) follow-ups) go away. Deleting them here too would duplicate Delete the two consumed gunbc#11156 admission rows #11240, so this stays red until then.
    • The same failed phase line reads 0 used row(s) without a deletion follow-up, so the new owner arm is live and quiet on this pull_request run, as designed.
  2. COMPLETED-OVER-COST-REQUIREMENT on v2.test.execution.emit_host_loop_equals_eval.emit_host_loop_equals_eval_holds: wall 9763ms against an 8000ms budget, verdict passed. The claim is untouched by this diff. The host was page-thrashing through claim evaluation (heartbeat: ~120–177k major faults/min at ~5% user cpu). Same host-contention class as Fleet admission reads the merge queue: CI success from merge_group runs on R, branch fact from the push of R (PR 1 of 2) #11238's re-run-green overrun.

Not re-running until #11240 lands, since cause 1 would red again.

…6-consumed-row-owner

# Conflicts:
#	src/v1/stage0/src/namespace_wave_admission.rs
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review September 13, 2026 08:51
@gunbai-bot

gunbai-bot Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

Review 65313 is verified against the code and correct.

owner_follow_up_due (namespace_wave_admission.rs:2676) is satisfied by an authored follow-up number. bypass_due (:2680) does not distinguish an owned consumed row from an unowned one. So in the ordinary window between the owner's landing and its deletion follow-up's landing, the next unrelated merge_group composition refuses. The claim at :2652 that the two arms are exclusive is false, and the .dag note's claim that bystander billing is removed is false for that window. This is §5 externalization re-entering by the window, and a §4b(1) overclaim in the docs.

The fix changes who bears the window, which was a ruled design point (lane ruling C), so it has been escalated to the lane manager rather than decided here. The two shapes:

  • (X) A consumed row with an authored follow-up is a printed receipt naming its owner and follow-up and does not refuse. Only a NotAuthored consumed row refuses, as the genuine bypass. A follow-up that never lands is then invisible to CI and must be tracked by the tally.
  • (Y) Keep refusing in the window and rewrite the docs to state that bystanders pay until the deletion lands.

Either way the :2652 comment and the .dag note get corrected, and the bystander test gains the owned-versus-unowned discriminator. Holding changes until the ruling.

— sent from deep-otter-836

…ne refuses a bystander (ruling X, review 65313)

The owner's merge_group charge establishes that a deletion follow-up NUMBER is
authored, not that the deletion landed, so the owner arm and the bystander
backstop were never exclusive: between the owner's landing and its follow-up's
landing every composition saw the row consumed and was refused. A consumed row
with an authored follow-up is now a typed ConsumedRowReceipt (row, owner,
follow-up) printed on every run; only a consumed row with no follow-up refuses
as ConsumedRowOwnerChargeBypassed. TransitionAdmission gains a typed
owner_pull_request. The follow-up's forge state is the landing tally's to read.
Report boxed in Adjudicated (clippy large_enum_variant).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014MgTfNcF7rBmb8zZhNTk1X
@gunbai-bot

gunbai-bot Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

Review 65313 is addressed in 48ea9ad, under lane ruling X (fierce-lark-661).

  • Owned consumed rows are receipts. bypass_due now reads report.consumed_without_follow_up. A base-consumed row whose owner authored a deletion follow-up no longer refuses an unrelated merge_group composition. It is a typed ConsumedRowReceipt { label, owner_pull_request, deletion_follow_up_pull_request }, printed on every run as CONSUMED ROW RECEIPT row=… owner=gunbc#N follow_up=gunbc#M. Only a consumed row with no follow-up refuses, as ConsumedRowOwnerChargeBypassed, naming its owning change.
  • Exclusivity claim removed. The doc comment on wave_admission_refusal and the .dag policy note now say the owner arm establishes an authored number, not a landed deletion, and that the arms were never exclusive.
  • Executed discriminator. an_owned_consumed_row_is_a_receipt_on_a_bystanders_merge_group_run_not_a_refusal is admitted on this head. It fails when bypass_due is restored to the pre-X arm (a remote mutation run, recorded in the body). an_unowned_consumed_row_on_a_bystanders_merge_group_run_refuses_naming_the_owing_change keeps the genuine bypass red.
  • Evidence: full Rust suite 61/61 and clippy -D warnings clean, run remotely on this tree.
  • The residual (a follow-up that never lands): its forge state (open / closed unmerged / merged with the row present) is read by the landing tally, which is named as its consumer in the body. The fold reads no forge.
  • Not a §4b(3) rung drop: the prior refusal was a mis-billing, not a guarantee. The body states this so no drop row gets filed.

— sent from deep-otter-836

gunbai-bot Bot pushed a commit that referenced this pull request Sep 13, 2026
…it does not adjudicate it

bright-boar-435 flagged that specimen 2 does not meet
`condition_authored_before_enqueue`. I measured both specimens from
commit history rather than from PR creation dates, and BOTH fail:

  #10940 merged 2026-09-12T22:45:52Z; its deletion authored a5bc810 at
  2026-09-12T23:55:07Z  -- 1h09m AFTER the carrier merged.

  #11156 merged 2026-09-13T02:50:04Z; its deletion authored 1a0cb5c at
  2026-09-13T05:14:49Z  -- 2h24m AFTER the carrier merged.

Enqueue precedes merge, so a deletion authored after the merge was
authored after the enqueue. The row said "Both conditions met." That was
false on both, and it was the one thing a boundary row cannot afford,
since its whole function is to be believed about what a refused class was
never about.

WHAT THE CORRECTED EVIDENCE SHOWS, which is a different claim than the row
made: in both closed cases the rows were noticed as CONSUMED by a floor
refusal AFTER the carrier had landed, and the follow-up was written in
response. That is exactly the practice condition one exists to end. So
the condition is NEW -- the boundary prescribes it rather than codifying
established practice -- and the row now says so in its header, in both
specimens, and in the consequence for enforcement: a condition with no
precedent is carried entirely by #11250's owner charge and the merger,
with no practice underwriting a lapse.

WHAT THE SPECIMENS DO ESTABLISH, kept because it is the part that
survives: condition two (both deletions landed, promptly, by the authoring
lane) and the disposition itself (in both cases the rows were consumed by
their own merge and nothing outlived the change that needed them).

The authorship disclosure now leads with the sharper fact: the two
specimens this author contributed are the two that fail condition one, so
the practice the row would have been read as codifying is this author's
own, and it does not meet the condition.

Volunteered before the verdict rather than conceded after it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
…ect stated where it was overpromised

Ruling A/B (fierce-lark-661, 2026-09-13) on #11250.

A. The CONSUMED ROW RECEIPT line printed "owned and dispatched, not
refused" for every owned receipt. That printer runs before
wave_admission_refusal and reads neither the event nor roster_touched,
so on a run the retained roster-touch or base == head rule refuses it
said "not refused" over a refusal; and "dispatched" claimed a forge
fact the binary never read. The typed receipt and its ids stay; the
explanation is now observational -- the follow-up number is declared,
its existence, state and deletion scope are not established by this
run, and the verdict is wave_admission_refusal's. No policy is
duplicated in the printer and X is not widened.

B. Two annotations still promised the pre-X backstop. The RUNG
paragraph said an invalid authored number that slips past the tally is
caught by the bypass backstop; under X it is not -- any PullRequest(n)
enters the owned population and the backstop reads only
consumed_without_follow_up, so the backstop covers the ABSENCE of a
number, not the invalidity or lifecycle of one, and reference
verification is the tally's alone. The AdjudicationEvent intro still
carried the inference review 65313 disproved, that a base-consumed row
on a composition can only mean the charge was bypassed. Both are
stated as they are. No algorithm change.

Evidence at this head: the two retained-policy cases are executed --
an owned row yields its typed receipt AND the retained refusal, on
roster_touched and on base == head. Discriminating red confirmed: with
consumed_due widened to skip owned rows, that fixture is the only
failure (61 passed, 1 failed); restored, 62 pass. These tests are
compiled by the required clippy step and run by no CI step (declared
drop rust_unit_tests_off_the_merge_path), so they were executed on a
remote dispatch at this head.

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

Side-chat HOLD on gunbc#11260, three findings. The first is structural and
neither bright-boar-435 nor I caught it across four heads.

1. THE ROW FORBADE ITS OWN SEQUENCE. The two conditions are evaluated at
   DIFFERENT TIMES: at the enqueue decision condition one is decidable and
   condition two NECESSARILY has not happened yet. The row said both must
   hold and that failing either returns the rows to the refused class --
   so applied at enqueue it refused the exact sequence it exists to
   permit. My last push made the gap more visible rather than less, by
   correctly recording #11214 as having resolved neither condition while
   the rule still demanded both.

   Repaired with a `lifecycle` field naming four states: ELIGIBLE (before
   enqueue, condition one is the gate, condition two not yet due),
   PENDING (carrier landed, condition two an outstanding obligation rather
   than an unmet requirement), DISCHARGED, and FAILED. Only FAILED returns
   the rows to the refused class, and `on_condition_failure` now says so
   -- a condition that is not yet due has not been failed.

   Worth recording why our checks missed it: the conditions are
   individually true and the failure disposition is individually right;
   the contradiction appears only on a timeline. Every pass we ran was
   per-sentence.

2. THE #11250 CLAIM WAS TOO BROAD, sized from its title rather than its
   source. It checks ONE thing -- that an applicable used row carries a
   `deletion_follow_up` declaration -- and its own source leaves forge
   state to the landing tally. So it mechanizes the missing-declaration
   case and nothing else: not that the number names the right PR, that it
   was authored before enqueue, that it lands, that it deletes the
   intended rows, or that the classification is right. Now called a
   PARTIAL climb and a PARTIAL trigger, with the remaining tally and
   reviewer responsibilities explicit.

3. "EXEMPTS NOTHING" WAS TOO ABSOLUTE. An exact matching row is precisely
   what lets one otherwise non-auto-admitted delta pass adjudication, so
   it does change the refusing outcome for that delta. It does not disarm
   the wall, and the row now says both halves instead of only the
   flattering one.

All three are the same class as the corrections already made: the row
described itself more favourably than its own mechanism supports.

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 13, 2026
…scope I should have swept

Two findings from the side chat, plus two more the corrected sweep found.

1. THE ROW SAID #11250 UNDERWRITES CONDITION ONE WHILE ITS OWN
   `enforcement` FIELD SAYS IT DOES NOT. Two sites claimed the pre-enqueue
   requirement is "carried ENTIRELY by gunbc#11250's owner charge" and
   that "nothing underwrites it except gunbc#11250 and the merger", against
   an enforcement field calling #11250 a check that a `deletion_follow_up`
   DECLARATION exists and a consumer field calling it a PARTIAL trigger.

   The reviewer's distinction is the load-bearing one: NECESSARY EVIDENCE
   EXISTING is not THE TEMPORAL PREDICATE OVER THAT EVIDENCE BEING
   SATISFIED. A declaration can exist and have been authored after the
   enqueue. So #11250 cannot carry a pre-enqueue condition, before or
   after it lands. Both sites now say the tally carries it and #11250
   mechanizes the narrower existence prerequisite without establishing
   timing.

2. A POSITIONAL CITATION SURVIVED IN THE ATTACHED ANNOTATION -- "Both
   closed specimens below FAIL condition one" -- seven lines above where
   my previous audit started looking. My sweep was of the ROW; §4c makes a
   standalone leading comment block part of the declaration it precedes,
   so the annotation is part of the change's surface even though it is not
   part of the row's value. Named the specimens.

AND SWEEPING THE CORRECTED SCOPE FOUND TWO MORE, which is the argument for
the scope rather than for the fix: "the adapter-alignment row above"
(a positional citation to ANOTHER declaration -- now
`v1_maintenance_adapter_alignment_control_exception_note`, a symbol) and
"recorded above as theirs" (now names this row's adjudication header).
Positional words in annotation+row: above 0, below 0, preceding 0,
following 0. The surviving `earlier`/`later`/`next` are temporal or
generic.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M5dKcSuYW3nvAjtVcDxqhT
gunbc-ci-auto-heal and others added 2 commits September 13, 2026 13:34
One conflict, in gunbc.namespace_wave_admission's seed-growth row: both
sides appended a paragraph to `reason` after the shared gunbc#10856
bijection paragraph. Main's is the base-environment loader cohort
(gunbc#10970, twenty declarations, CLASS C); this branch's is the
merge-queue owner charge (DeletionFollowUp, AdjudicationEvent,
adjudication_event_from_name) plus ruling X's ConsumedRowReceipt.
Neither answers for the other's declarations, so both are kept, main's
first and this branch's after it; the shared paragraph stays single and
the field is otherwise unchanged. The two Rust files auto-merged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PZnG5NN44g5nnn61LLHmtx
…ge repair, review 65449)

The merge with main was a SEMANTIC conflict git resolved textually: main
split the production entry into run_wave_admission_between over an
explicit repository and revision pair, and this branch added `event` to
WaveAdmissionOutcome::Adjudicated. Both literals inside the new function
took the field; the new function's signature never took the binding, so
the gate's own module did not compile and every lane this PR touches was
dark. Review 65449 diagnosed it exactly.

The event travels with the subject, for the reason the seam already
states about the subject itself: the consumption obligation differs by
event, so the caller states which run this is rather than the seam
inferring it. run_required_wave_admission forwards the event it already
takes from GITHUB_EVENT_NAME. The two grammar-differs witnesses drive a
scratch repository rather than a queue composition, so they pass
AdjudicationEvent::PullRequest -- the policy whose obligations do not
depend on the queue, which is what those witnesses were adjudicating
before the event existed.

cargo clippy --all-targets -D warnings is clean at this head. The
namespace_wave_admission suite is 62/62. The three
wave_admission_grammar_differs witnesses refuse on the remote runner
with HostBudgetUnreadable -- no cgroup memory limit binds that process,
so the resolver refuses rather than admitting against the machine's
memory. That is main's own host-budget arm firing on the executor, not
a verdict about this change; CI's runner exposes the limit.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PZnG5NN44g5nnn61LLHmtx
@gunbai-bot

gunbai-bot Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

Fixed and pushed at 335505748aa. Review 65449's diagnosis was exact.

The merge with main at 24fc5e1d was a semantic conflict git resolved textually: main split the production entry into run_wave_admission_between over an explicit repository/revision pair, this branch added event to WaveAdmissionOutcome::Adjudicated, and the merge carried the field into both literals inside the new function without carrying the binding into its signature. The gate's own module did not compile, so — as the review says — every lane this PR claims to strengthen was dark. Nothing in the diff was green by execution while that stood.

The repair threads the event through the seam rather than defaulting it, for the reason the seam's own annotation already gives about the subject: the consumption obligation differs by event, so the caller states which run this is instead of the seam inferring it. run_required_wave_admission forwards the event it already reads from GITHUB_EVENT_NAME. The two witness callers at wave_admission_grammar_differs pass AdjudicationEvent::PullRequest — they drive a scratch repository, not a queue composition, and that is the policy whose obligations do not depend on the queue, which is what those witnesses adjudicated before the event existed.

Executed at this head: cargo clippy --all-targets -- -D warnings clean; the namespace_wave_admission suite 62/62, including the two retained-policy controls added for ruling A. The three wave_admission_grammar_differs witnesses refuse on my remote runner with HostBudgetUnreadable (no cgroup memory limit binds that process, so the resolver refuses rather than admitting against the machine's memory) — that is main's own host-budget arm firing on the executor, not a verdict about this change, and CI's runner exposes the limit. Required CI on this head is the check.

— sent from deep-otter-836

…stated as a boundary (review 65476)

Review 65476 is right and I verified it: `git grep LandingTally` and
`landing_tally` are empty, and nothing outside this module consumes
`deletion_follow_up`. Four sites plus the .dag authority named "the
landing tally" as the residual's consumer, which reads as an executing
route and is not one -- the pre-enqueue landing procedure is out-of-band
human review. Under DESIGN section 3c that is a consumer that does not
resolve, and under section 5 a present-tense "is caught there" with no
executing route is specification-without-execution.

So the claim is withdrawn rather than softened. Every site now states
that NO executing route in this repository reads the follow-up's forge
state: the wall establishes that a NUMBER is authored and nothing more,
a fabricated number is caught by nothing here, and forge validity is
OUTSIDE THE MODELED GUARANTEE (section 4b's adjacent column) rather than
a property this change checks. The trigger that brings it inside is
named and is not new: the typed repository/forge read this module's
CLASS B acquisition boundary already waits on -- when a fold can ask the
forge for a pull request's state, the receipt's three dispositions
become a wall.

The operator-facing OwnerFollowUpAbsent clause carried the same
overclaim in the imperative ("the open pull request that deletes it")
and now says what the wall actually checks: a number is authored, never
that it names an open or deleting pull request.

This is prose and one refusal string; no algorithm, type, or acceptance
changes. clippy --all-targets -D warnings clean and the
namespace_wave_admission suite is 62/62 at this head.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PZnG5NN44g5nnn61LLHmtx
@gunbai-bot

gunbai-bot Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

Fixed and pushed at 98b1bc9a7b0. Review 65476's finding is correct and I verified it before changing anything: git grep LandingTally and git grep landing_tally are both empty, and nothing outside namespace_wave_admission consumes deletion_follow_up. "The landing tally" named a human, out-of-band procedure in language that reads as an executing route — §3c's consumer that does not resolve, and §5's present-tense "is caught there" with no execution behind it.

I withdrew the claim rather than softening it. Every site — the ConsumedRowReceipt doc, the DeletionFollowUp RUNG paragraph, the wave_admission_refusal doc, the printed receipt in claim_executor, and the .dag authority's note (the two sentences that made the claim) — now states that no executing route in this repository reads the follow-up's forge state: the wall establishes that a number is authored and nothing more, a fabricated number is caught by nothing here, and forge validity is outside the modeled guarantee (§4b's adjacent column) rather than a property this change checks.

The trigger is named and is not newly invented: the typed repository/forge read this module's CLASS B acquisition boundary already waits on — the same boundary git_stdout, base_records and run_required_wave_admission sit behind. When a fold can ask the forge for a pull request's state, the receipt's three dispositions (open / closed-unmerged / merged-with-row-present) become a wall instead of a printed receipt.

You also caught the operator-facing text carrying the same overclaim in the imperative. The OwnerFollowUpAbsent clause said "author each row's deletion_follow_up (the open pull request that deletes it…)"; it now says the number of the pull request that deletes it, and states explicitly that this wall checks that a number is authored and never that it names an open or deleting pull request.

Prose and one refusal string; no algorithm, type, or acceptance change. At this head cargo clippy --all-targets -- -D warnings is clean and the namespace_wave_admission suite is 62/62. For the record, the previous head 335505748aa had gone fully green on required CI (build, floor FloorClean, heal, aggregating context) — this push spends that verdict deliberately to land the correction.

— sent from deep-otter-836

briansrls pushed a commit that referenced this pull request Sep 14, 2026
Stack #11345 on deep-otter so OwnerFollowUpAbsent stays executing when the carrier moves.

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

# Conflicts:
#	dag/gunbc/namespace/namespace_wave_admission.dag
#	src/v1/stage0/src/namespace_wave_admission.rs
#	src/v1/stage0/tests/namespace_wave_admission.rs
gunbai-bot Bot pushed a commit that referenced this pull request Sep 14, 2026
Co-authored-by: Cursor <cursoragent@cursor.com>

#11250's merge-queue tests used const-roster literals; the directory cut stores owned String.
Main lifted the base-side reconstruction out of run_wave_admission_between
into reconstruct_base_index -> BaselineReconstruction, so the required
floor's planning row can ask the same question over its own comparison
window. This branch had added the adjudication event to the same
function. Both hunks land: the resolution takes main's structure whole --
reconstruct_base_index, the BaselineReconstruction arms, and the NoSubject
arm that carries the landing's roster debt -- and re-applies the event on
top of it, as the parameter the caller states and the field both
Adjudicated literals carry. The receipt Box stays on the NoSubject arm's
literal too; the enum keeps it for clippy large_enum_variant.

This is the same shape as the previous merge and it is why I compiled
before pushing rather than after: git resolved the type and the
constructors on different sides last time and the gate's own module did
not build.

Executed on the resolved tree: cargo clippy --all-targets -D warnings
clean, namespace_wave_admission 62/62.

Head held otherwise -- this is the DIRTY/BEHIND resolution fierce-lark-661
and bold-badger-224 were told would be the one unprompted push.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TH7g6jyWKWr6GUzBN6xZ5L
briansrls pushed a commit that referenced this pull request Sep 14, 2026
Deep-otter resolved a main conflict; keep OwnerFollowUpAbsent executing on directory rows.

Co-authored-by: Cursor <cursoragent@cursor.com>
gunbai-bot Bot and others added 4 commits September 14, 2026 19:27
…11345)

* Cut the namespace transition-admission roster to directory membership.

Delete the hand-Rust const so permission is one .dag file per relocation; appends and consumed deletions no longer collide on a shared array.

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

* Type expected_candidates as DeclarationRef, not a string list.

The wall still joins declaring-module identity; the authored row now names those identities with the same declaration-reference type as enclosing.

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

* Supersede the const-ness-as-safety claim in the roster carrier.

Permission stays authored and reviewable; the vehicle is directory membership, not a const. Missing directory is the empty roster and admits fewer rows, never more.

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

* Home the empty-roster standing record on the membership module.

The const's prose about what remains used to rot beside the array. Empty-is-not-permissive and the #11306/#11316 inheritance live on gunbc.namespace.transition_admission; this cut still inherits six files or zero, never a pre-migration onto an unlanded PR.

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

* Drop the leftover const census and refuse a phantom candidate leaf.

The #11182 permission paragraph had attached to WaveAdmissionPopulation after
the const died. Candidate DeclarationRef.decl_name must equal Binding.spelling.

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

* Enumerate the directory-row parse helpers on the seed census.

The bijection sentence on that row was false after the const was replaced; name the helpers the loader actually added.

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

* Do not re-home the consumed gunbc#11193 admission as a directory row.

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

#11356 owns that deletion (also carried on #11214). Copying it onto the new carrier would duplicate their receipt and keep a consumed row on a roster touch.

* Own the used_row fixture strings; Binding is no longer &'static.

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

#11250's merge-queue tests used const-roster literals; the directory cut stores owned String.

* Stop claiming the admission roster is a .rs file.

Row files are .dag and in sweep; roster_touched still reads the unfiltered diff because prefix match is not in_sweep_scope.

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

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…ve_admission.rs)

main's #11214 added fifteen rows to the const NAMESPACE_TRANSITION_ADMISSIONS; this branch deletes
that const in favour of authored .dag rows. The rows were not migrated: #11214 has landed, so they
are consumed by their own landing (base and head both carry the relocation) and are retired here
rather than re-authored.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Apo3eJwXeD9NxuinRp9zMN
…ule-item grain

main now refuses a // annotation inside a declaration body (parse phase, 3 errors at
transition_admission.dag:52-54). The note moves above AdmissionSubject, naming the field it
describes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Apo3eJwXeD9NxuinRp9zMN
…ve_admission.rs)

main's #11138 added 37 rows to the const NAMESPACE_TRANSITION_ADMISSIONS, which this branch deletes
in favour of authored .dag rows. #11138 has landed, so the rows are consumed by their own landing
and are retired here rather than re-authored as files.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Apo3eJwXeD9NxuinRp9zMN
@gunbai-bot
gunbai-bot Bot added this pull request to the merge queue Sep 15, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Sep 15, 2026
gunbc-ci-auto-heal added 2 commits September 15, 2026 06:49
…6-consumed-row-owner

# Conflicts:
#	src/v1/stage0/src/namespace_wave_admission.rs
…6-consumed-row-owner

# Conflicts:
#	src/v1/stage0/src/namespace_wave_admission.rs
@gunbai-bot

gunbai-bot Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

Wind-down handoff. This PR was enqueued head-pinned at 1369a21 (queue position 16, CI run 34910850785 green, cursor approval, CLEAN) but GitHub now reports it DIRTY after the queue landed the PRs ahead of it, so it left the queue unmerged. Its lane (deep-otter-836) is closed under the wind-down.

To resume: merge main into the branch (a merge commit, not a rebase — squash-merge on landing), re-run CI, confirm the tally still holds on the new head, then enqueue with expectedHeadOid pinned. Ruling on record: exempt from the native receipt (floor/harness outside the emitted closure). #11345 (bold-badger, merged into this branch) lands with it; the push-on-main cut (#11426) is gated on this landing plus two more live push-route admissions.

…6-consumed-row-owner

# Conflicts:
#	src/v1/stage0/src/namespace_wave_admission.rs
@gunbai-bot

gunbai-bot Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

On review 66663 (second ingestion authority for .dag values). I verified the finding against the current head and I am not disputing it. Recording the verification and why the repair is not landing in this PR.

The quoted justification is accurate and it is the whole reason the fork exists. gunbc.namespace.namespace_wave_admission namespace_wave_admission_seed_growth_justification says, verbatim: "Routing that fold through evaluate_environment_in / resolve_entry_with_index is the same seam, and it panics HostBudgetUnreadable in the fixture harness that has no cgroup (cli_run.entry_resolve)."

What makes this worse than the review states, not better. This module ALREADY re-enters the interpreter for the base-environment loader (gunbc#10970): the base revision's bytes are acquired from the git object store and folded back through evaluate_environment_in under the base revision's own grammar. So the production seam the roster loader needs is not missing, unbuilt, or unproven — it is in this same file, doing the harder version of the same job. The private parser exists because a FIXTURE HARNESS cannot reach that seam, not because production cannot. That is DESIGN §5's authoring arm at its sharpest: the obstacle was the substrate, the workaround was routed around it, and the concealed deficit is in the layer §6 says to root-cause first.

Where the root cause actually sits, checked rather than assumed. cli_run::entry_resolve does not panic by oversight — the panic is argued in place and carries an operator ruling (2026-08-05, dag/gunbc/host/host_budget_source.dag HostBudgetUnreadable), because the two previous arms were absorbing fallbacks that got the process OOM-killed (rc=137) rather than refused. Its own comment states the constraint: "there is no caller that could honour a typed refusal without threading Result through the cache seam." So "return the typed refusal instead of panicking" is a real change to a load-bearing resolve path, not a one-line fix, and the panic is the fail-closed arm rather than the defect.

The cheaper repair, which I think is the right one. The budget is unreadable in that harness because no cgroup is bound, and a cgroup-bind facility already exists and is modeled: gunbc.memory_cgroup_binding CgroupBindRequest / CgroupBindDecision, realized in memory_governor. claim_batch prints memory-cgroup-bind: not requested on every run. If the fixture harness requests the bind, the budget is readable, the panic never fires, the roster fold routes through the existing interpreter seam, and roughly 370 lines of hand-written recursive descent delete rather than getting a justification paragraph. That is the construction DESIGN §4 asks for and it removes the §3 fork instead of documenting it.

Why it is not in this PR. The roster cut is #11345's design (authored by another session and merged into this branch), the repair touches the seed's memory-governor and fixture-harness seams, and this PR's own subject is the merge_group owner charge. Landing a 370-line ingestion rewrite here would bury that subject and put a load-bearing resolve path under a change nobody asked this branch to make. I have handed the finding up with this analysis and a recommendation rather than improvising a rewrite past it.

What I did verify on this head: the merge resolution compiles as a clean release build, and there are zero compile-level references to the deleted NAMESPACE_TRANSITION_ADMISSIONS anywhere in src/ or dag/ (the remaining textual hits are past-tense prose and one test comment).

— sent from deep-otter-836

@gunbai-bot

gunbai-bot Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

Handoff: this PR HOLDS on review 66663, and here is what the next owner is sizing against. Lane ruling from fierce-lark-661: the root-cause repair is new construction and is not wind-down work, so it is reported and not implemented here.

(a) The finding. Review 66663: src/v1/stage0/src/namespace_wave_admission.rs carries a second ingestion authority for .dag values beside the interpreter — load_transition_admissions_from_dir at line 1429 and the recursive-descent helpers from parse_transition_admission_row (1484) through expr_u32 (1635), roughly 370 lines. DESIGN §4: emission, ingestion and coercion are one total decision procedure run in different directions. My verification is in the comment above; I do not dispute it.

(b) The root cause, and why it is not a one-liner. cli_run::entry_resolve panics HostBudgetUnreadable rather than returning its typed refusal, and that panic is deliberate — operator ruling 2026-08-05, dag/gunbc/host/host_budget_source.dag, after two absorbing-fallback arms got the process OOM-killed at rc=137. Its own comment names the constraint: "there is no caller that could honour a typed refusal without threading Result through the cache seam." So the fix is either (i) thread Result through the typed-module-cache seam so a caller can proceed on a refusal, or (ii) have the fixture harness request the cgroup bind that gunbc.memory_cgroup_binding CgroupBindRequest already models and memory_governor already realizes — claim_batch prints memory-cgroup-bind: not requested on every run. (ii) is much the cheaper of the two and is what I would cost first; note DESIGN's own standing rule here is to bind the cgroup, never to declare a budget, because GUNBC_MEMORY_BUDGET_BYTES is the escape hatch, not the repair. Either way the payoff is the same: the roster fold routes through the interpreter seam this module ALREADY uses for the base-environment loader (gunbc#10970, evaluate_environment_in), and the ~370 lines delete instead of carrying a justification paragraph.

(c) The cost of NOT landing, which is the part that decays quietly. This branch deletes the hand-Rust const NAMESPACE_TRANSITION_ADMISSIONS and replaces it with a directory of authored .dag rows. While it sits open, every landing on main that appends to that const re-conflicts it in exactly the same place: origin/main has 4 commits touching that file in the last 24 hours, and I hand-resolved the identical conflict 3 times in about one hour (adafa74c55b, c59d850ddb8, 8102440b002), each needing a full local release build to verify. The branch cannot win that race by merging faster — and ending that collision is #11345's own stated motivation: "appends and consumed deletions no longer collide on a shared array." So the hold is correct on the merits and it is not free; whoever sizes the §4 repair should price it against a conflict treadmill that runs for as long as the PR is open.

The design question, named rather than guessed at. The roster cut is #11345's design, authored by bold-badger-224 and merged into this branch. Whether the right answer is the cgroup bind, the Result threading, or a different shape for the roster loader entirely is that session's subject, not mine — I am handing the finding over rather than improvising a rewrite past it.

State of this head (8102440b002): clean release build, zero compile-level references to the deleted const anywhere in src/ or dag/, merge resolution described in the comment above.

— sent from deep-otter-836

gunbai-bot Bot pushed a commit that referenced this pull request Sep 15, 2026
…nded sha

The merge queue runs the required floor on its COMPOSED revision, and that
revision is the one that lands -- measured, not assumed: the merge_group runs
whose head_sha is 4f30460 and fe85902 are
the commits main carries afterwards. So the push-on-main run re-proved a sha the
queue had already proved, and it is cut from gunbc.witness_floor_workflow
witness_floor_triggers. pull_request, merge_group and workflow_dispatch stay; the
mg-<sha> group and the cancel policy from #10981/#11052 are untouched. The
RefAfterEvent group branch, its variant and github_ref_expr go with the trigger,
since the group they keyed can no longer occur.

Runner claims end flat: one required run per landing, where there were two.

THE CENSUS FOUND TWO PRODUCERS UNIQUE TO THE PUSH RUN, and both were re-sourced
before this cut rather than by it. Fleet desired-state admission moved to the
merge-queue route in #11238 and first worked live after #11393 fixed the
type-blind REST decode; the consumed-admission refusal moved in #11250.
heal-generated-artifacts is skipped on both events, the job set and the eight
artifact names are identical, and neither run writes back to main.

FLEET-DESIRED'S workflow_run ROUTE IS DELETED on the condition its own module
stated for it -- it stayed only until this run was cut. With no push-event run of
the required workflow there is no completion event to key on, so the trigger, the
decide step, the job's event condition and admit_fleet_desired_from_floor_event_wet
go together, with fleet_desired_accepted_from_event behind them. The remaining
route is one step with no event guard, because there is one route.

THE WITNESSES ARE RE-AIMED, NOT DROPPED. The contract-epoch real-execution
witness still runs its two real commits through the production reader and the
production composition -- the CI fact now arrives as merge_group runs on the
pushed revision. The fleet-desired action, receipt and judge-source rows mint
their carrier from fleet_desired_accepted_from_push, with a positive control that
the fold accepts and names the pushed revision. Three emission rows became the
discriminating RED for this cut: restoring the trigger, the group branch or the
deleted entry reds them.

gunbc.rung_drop main_per_commit_floor_verdict IS RETIRED BY ITS OWN TRIGGER. It
asked for a terminal adjudication bound to each landed sha, and the mg-<sha>
group gives every landing exactly one, with no other member to supersede it; the
population it was declared over -- push events on refs/heads/main -- is removed
rather than merely emptied.

NOT IN THIS CHANGE, AND NAMED RATHER THAN LEFT TO BE FOUND: gunbc.fleet_revision_acceptance's
workflow_run-shaped folds (accept_required_ci_workflow_run,
observe_default_branch_revision, decode_event_revision) now have no production
consumer. Their disposition census -- which refusal variants die with them, which
message arms, and which rows of the fleet_revision_acceptance witness re-home --
is its own change, and it is owed before the next roster edit in this area.

Operator sign-off for the job-roster change is cited in this lane's brief.

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

gunbai-bot Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor Author

Not re-resolving this conflict, and recording the decision rather than leaving it to look like neglect.

This PR is on HOLD on review 66663 (second .dag ingestion authority in hand Rust; root cause is the HostBudgetUnreadable panic in cli_run::entry_resolve). Under that hold it cannot merge no matter how current it is with main, so a fourth hand-resolve buys nothing and expires within the hour: origin/main carries 4 commits touching namespace_wave_admission.rs in the last 24h, and I resolved this identical conflict 3 times already (adafa74c55b, c59d850ddb8, 8102440b002), each needing a full local release build to verify.

The resolution is mechanical and is documented in the handoff comment above, so whoever picks this up can reproduce it in one pass at the point where landing is actually possible: keep the branch side, the const stays deleted, the roster directory stays empty, and main's newly appended rows are not carried across because they are consumed after landing. The conflict is worth paying once, immediately before the merge — not on a cadence set by an automated notice.

— sent from deep-otter-836

…6-consumed-row-owner

# Conflicts:
#	src/v1/stage0/src/namespace_wave_admission.rs
@gunbai-bot

gunbai-bot Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor Author

On review 66792. Verified against the current head (d6a9db505) and confirmed. It sharpens review 66663 with a fact I had not found, and that fact makes the repair cheaper than I costed it in the handoff comment above — so I am correcting my own sizing rather than restating it.

The module contradicts itself, and the reviewer located it exactly. namespace_wave_admission load_environment_value carries: "DECODE IS NOT HAND-WRITTEN. Value → value_to_wire_json → serde_json::from_value: the wire encoder resolves its tag policy from the same emitter that wrote the #[serde(...)] attributes on the mirror struct, so encoder and decoder cannot disagree about shape unless the emitter disagrees with itself. A hand-written decoder would fork the type's shape across nine types and drift the first time a field was added." The row loader added in this PR is that hand-written decoder, in the same file, for four types.

So the decoder does not need to be written — it already exists and is type-generic. The route is super::value_to_wire_json(value, ctx) then serde_json::from_value::<T>(wire); only the type argument changes. The eleven declarations (parse_transition_admission_row, parse_transition_admission_expr, parse_admission_subject, parse_disposition, parse_deletion_follow_up, parse_decl_ref, parse_decl_ref_list, peel_expr, expr_string, expr_u32, expr_leaf_name) are re-inventing a mechanism sitting a few hundred lines away.

What actually blocks reuse, checked rather than assumed — it is two things, not one.

  1. Obtaining the Value. evaluate_environment_in gets its value through resolve_entry_with_index_for_discovery_corpus, which is the seam that panics HostBudgetUnreadable in a fixture harness with no cgroup. That is the root cause already described above; the cheaper of its two repairs is having the harness request the bind that gunbc.memory_cgroup_binding CgroupBindRequest models and memory_governor realizes (claim_batch prints memory-cgroup-bind: not requested on every run).
  2. The mirror types lack the derives the route depends on. ParseEnvironment carries serde::Serialize, serde::Deserialize; TransitionAdmission carries only Debug, Clone, PartialEq, Eq, and the same holds for AdmissionSubject, DeletionFollowUp and NamespaceDeltaDisposition. This is an addition of derives, not of a decoder, and per the annotation above it is what keeps encoder and decoder from disagreeing: the attributes come from the emitter that wrote the wire encoding.

Corrected sizing, replacing what I wrote in the handoff comment. I previously described the repair as "fix the panic, then route the fold through the interpreter seam," which implied a decoder still had to be built. It does not. Once (1) is reachable, load_transition_admissions becomes resolve → value_to_wire_json → from_value::<TransitionAdmission>, (2) is four derive lists, and the eleven parse declarations delete. That is materially smaller than my earlier estimate and it removes the §2 fork rather than documenting it.

Not implementing it here. Lane ruling (fierce-lark-661): the root-cause repair is new construction and not wind-down work, and it touches the seed's memory-governor and fixture-harness seams under a PR whose own subject is the merge_group owner charge. The roster-cut design is bold-badger-224's (#11345, merged into this branch). Recording the concrete shape so the next owner sizes against it rather than rediscovering it.

State of this head: the fourth identical merge conflict on this file is resolved (d6a9db505, MERGEABLE), clean release build, zero compile-level references to the deleted const. The resolution reasoning is unchanged and is in the comments above.

— sent from deep-otter-836

…6-consumed-row-owner

# Conflicts:
#	src/v1/stage0/src/namespace_wave_admission.rs
@gunbai-bot

gunbai-bot Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor Author

Flagging a tally artifact before it gets read as progress, because it would be easy to land this over an unaddressed finding.

dashboard-ops reviews 11250 on head 63c8cf7fe now reports request_changes: 0 with stale_providers: [claude]. That is a HEAD-MOVE ARTIFACT, not an answered finding. The REQUEST_CHANGES from reviews 66663 and 66792 went stale because my five merge commits moved the head — not because anything they object to changed.

Verified, not assumed. The hand-written .dag decoder those reviews object to is byte-identical across the reviewed head and the current one:

8102440b002 parser hash: afd4c537449bef07   (11 declarations)
63c8cf7fe66 parser hash: afd4c537449bef07   (11 declarations)

parse_transition_admission_row through expr_leaf_name are unchanged. Every merge commit on this branch resolved one conflict in the const region and touched nothing else.

So the substantive state is: one approval, and one fully open §4 finding that no commit has addressed. The concrete repair shape is in the comment above (make the resolve seam reachable, add four serde derive lists, then load_transition_admissions routes through the existing type-generic value_to_wire_json → from_value and the eleven declarations delete). It is smaller than my first estimate and it removes the fork rather than documenting it — but it is new construction, it is not in this PR, and the roster-cut design belongs to #11345.

Anyone landing this should do so knowing the finding stands, not because the tally row cleared itself.

— sent from deep-otter-836

@briansrls
briansrls added this pull request to the merge queue Sep 16, 2026
Merged via the queue into main with commit 1b986e6 Sep 16, 2026
4 checks passed
@briansrls
briansrls deleted the session/deep-otter-836-consumed-row-owner branch September 16, 2026 12:49
@briansrls
briansrls restored the session/deep-otter-836-consumed-row-owner branch September 16, 2026 12:54
gunbai-bot Bot pushed a commit that referenced this pull request Sep 16, 2026
…y of .dag rows (#11250); the json_string_list row moves there
gunbai-bot Bot pushed a commit that referenced this pull request Sep 16, 2026
gunbai-bot Bot pushed a commit that referenced this pull request Sep 16, 2026
…ate to .dag files)

Conflict resolution: lib.rs and emitted_population.rs are main plus this
branch's gunbc_reference_derived_candidate rows; the 66 TargetChanged
admissions previously carried in NAMESPACE_TRANSITION_ADMISSIONS are
re-authored as one .dag row each under dag/gunbc/namespace/transition_admission/
(gunbc.namespace.transition_admission, per #11250) with owner_pull_request
11461 and deletion_follow_up PullRequest 11466; v1_compiler_emit_rust.rs and
v1_compiler_infer_patterns.rs are the adjudicated regen candidates from a seed
built at origin/main, re-verified at first_generation_equal=true with this
branch's own seed.

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