Skip to content

Three v2->Rust emitter arms the widened 00_compile closure exposed: empty-map generics, argv word-list splice, append concat form - #11154

Merged
briansrls merged 7 commits into
mainfrom
session/cool-hawk-353
Sep 12, 2026
Merged

briansrls merged 7 commits into
mainfrom
session/cool-hawk-353

Conversation

@gunbai-bot

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

Copy link
Copy Markdown
Contributor

Three v2->Rust emitter gaps, each found by the SAME event and none of them a spelling question: #11011 widened the emitted 00_compile closure to carry extdeps.rust.cargo_build and extdeps.exec.command, the first srv2 execution of #10940's native route emitted a crate rustc refused with 28 errors, and all 28 were in those two newly-emitted modules. This PR repairs the emitter so any closure carrying the shapes emits correctly. It carries none of #10940's layer-inversion fix.

Reproduced locally, not read off a log. gunbc compile --entry dag/extdeps/rust/cargo_build.dag + cargo build on the emitted crate gives the same 28: 17 × E0277 + 9 × E0308 + 2 × E0425.

The three arms

(1) Empty-map turbofish — E0425, cannot find type K in this scope. data cargo_compile_env: Map<String, String> = empty_map() emitted v1_rt::rc_empty_map::<K, V>(): the call resolved to the v2.std.collection DECLARATION (the module resolves Map by namespace, importing neither) and the emitter wrote that declaration's own formals into a module with no generic scope. The fold-init arm had already learned to defer such a turbofish to the target's inference (::<_, _>()); the plain-call arm had not. Both now read one authority, rust_empty_map_init_expr — two sites asking one question was the second representation §2 forbids.

(2) Word list spliced into an argv literal — E0277, Rc<im::Vector<String>>: AsRef<OsStr>, 17 sites. argv: ["cargo", "clippy", extra_args, "--", lint_args] emitted Command::arg(extra_args) — one argument holding a run of words. emit_shell_call now asks the operation's OWN input declaration (the same authority optional_params beside it reads) and emits .args(..) for a List-typed element. argv[0] is deliberately left alone: a word list there is already refused loudly by rustc on the same bound, and an emitted refusal in its place is a red this route cannot adjudicate (an emitted panic compiles).

(3) The concat form of append spelled as the snoc bridge — E0308, 9 sites. v1_rt::append(list, item) where rc_list_concat(a, b) was meant.

A correction to the defect report, and it is load-bearing. The report named the items: KEYWORD as the discriminator. It is not. Measured against the interpreter — which is the semantics this emitter has to agree with — append(xs, items: ys) and append(xs, ys) BOTH answer concat, and append(xs, items: x) answers snoc: the interpreter's method_call.concat arm asks value_to_list_carrier of the argument and never reads the keyword. The discriminator is the appended argument's type, so keying the repair on the keyword would have left the positional concat form — which the corpus writes — still emitting snoc. A second measured finding: all nine sites emit through emit_rust_generic_method_call, not the plain-call seam, because nothing in the corpus imports append and infer rewrites the bare form into a method call. The plain-call seam therefore does NOT get a reader — its red is not authorable anywhere a check could run it (§4b), so a reader there would be permanently green by construction, and the annotation states the trigger for adding one.

Evidence

Three fixtures under fixtures/fixture_closure_rustc/, each measured RED against the pre-repair seed and green after, consumed by fixture_closure_rustc_verdict through three discrimination pairs whose red arm is the route's own FIXTURE_RED_PATH — the nested-refinement-cast precedent, a pair per arm so a regression is attributed to one emitter decision rather than to "the fixture".

arm fixture RED measured after
empty-map turbofish empty_map_data_turbofish_probe.dag ::<K, V> at the data initializer and the fn body (the fold position was already correct and is in the fixture as the arm that must not regress) ::<_, _> at all three
argv word list argv_word_list_splice_probe.dag .arg(extra_args) at 4 argv positions .args(..) at the list elements, .arg(word) still at the String one
append concat append_concat_form_probe.dag v1_rt::append at all 6 declarations rc_list_concat at the 4 concat forms, append still at the 2 snoc forms

Positive control: extdeps.rust.cargo_build + extdeps.exec.command emitted through the v2 emitter and cargo build-ed — 28 errors before, 0 after.

gunbc.recurring_failure_mode.accepted_source_emits_uncompilable_target gains one occurrence carrying all three, the keyword-discriminator correction, and an honest rung: still mitigatable. The three pairs are #[ignore]d --lib tests and repo_self_test_command is off the merge path (gunbc.rung_drop rust_unit_tests_off_the_merge_path), so nothing blocks a regression and reporting rung 2 would be inflation. The trigger names the capability: a required phase that emits a closure and compiles it over a population that INCLUDES fixture-authored sources.

What the occurrence keeps beyond the three bugs: all three shapes are ordinary in the corpus and were absent from the seed's own closure, so they were accepted for exactly as long as nobody emitted a module carrying them. Widening the closure was the census — and none of the three modules involved was changed to expose them.

🤖 Generated with Claude Code

https://claude.ai/code/session_012xQnkeiJ1pnEpMgqh3dE1e

Brian Searls and others added 2 commits September 12, 2026 05:50
#11011 widened the emitted closure to carry extdeps.rust.cargo_build and
extdeps.exec.command; the first srv2 execution of that route emitted a crate
rustc refused with 28 errors, all of them in those two newly-emitted modules.
Reproduced locally and repaired at the emitter, so any closure carrying the
shapes emits correctly. None of #10940's layer-inversion fix is here.

(1) EMPTY-MAP TURBOFISH, E0425. A module-scope `data ...: Map<String, String> =
empty_map()` emitted `v1_rt::rc_empty_map::<K, V>()`: the call resolved to the
v2.std.collection DECLARATION and the emitter wrote that declaration's own
formals into a module with no generic scope. The fold-init arm had already
learned to defer such a turbofish to the target's inference; the plain-call arm
had not. Both now read one authority, rust_empty_map_init_expr -- two sites
asking one question was the second representation DESIGN section 2 forbids.

(2) WORD LIST SPLICED INTO AN ARGV LITERAL, E0277, 17 sites. `Command::arg(list)`
handed one argument a run of words. emit_shell_call now asks the operation's own
input declaration -- the same authority optional_params beside it reads -- and
emits `.args(..)` for a List-typed element. argv[0] is deliberately untouched: a
word list there is already refused loudly on the same bound, and an emitted
refusal in its place is a red this route cannot adjudicate, since an emitted
panic compiles.

(3) THE CONCAT FORM OF append SPELLED AS THE SNOC BRIDGE, E0308, 9 sites. The
defect report named the `items:` keyword as the discriminator; measured against
the interpreter it is not. `append(xs, items: ys)` and `append(xs, ys)` BOTH
answer concat and `append(xs, items: x)` answers snoc -- method_call.concat asks
value_to_list_carrier of the argument and never reads the keyword. The
discriminator is the APPENDED ARGUMENT'S TYPE, so keying on the keyword would
have left the positional concat form still emitting snoc. All nine sites emit
through emit_rust_generic_method_call, not the plain-call seam, because nothing
in the corpus imports append and infer rewrites the bare form into a method
call; the plain-call seam therefore gets no reader, because its red is not
authorable anywhere a check could run it (section 4b).

EVIDENCE. Three fixtures under fixtures/fixture_closure_rustc/, each measured
RED against the pre-repair seed -- E0425 x4, E0277 x4, E0308 x5 -- and green
after, consumed by fixture_closure_rustc_verdict through three discrimination
pairs whose red arm is the route's own FIXTURE_RED_PATH. A pair per arm so a
regression is attributed to one emitter decision. Positive control: both real
modules emitted and cargo-built, 28 errors before and 0 after.

The argv fixture carries a note about a SEPARATE gap found while authoring it: a
single-output shell operation with no exit block emits an unwrapped value where
its own declared Result is expected. It is recorded, not repaired here -- a
fixture carrying two defects adjudicates neither.

gunbc.recurring_failure_mode.accepted_source_emits_uncompilable_target gains one
occurrence carrying all three, the keyword-discriminator correction, and an
honest rung: still mitigatable. The three pairs are #[ignore]d --lib tests and
repo_self_test_command is off the merge path, so nothing blocks a regression and
reporting rung 2 would be inflation. The trigger names the capability: a
required phase that emits a closure and compiles it over a population that
includes fixture-authored sources.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012xQnkeiJ1pnEpMgqh3dE1e
… chain to its fixed point

TWO THINGS, and the second is the repair of my own error on the first push.

FIRST, THE ROW eager-raven-113 ASKED FOR. The separate finding the previous
commit recorded only as a note in the argv fixture is a newly discovered error
class, so under DESIGN 4b it gets its own row:
gunbc.recurring_failure_mode.shell_projection_return_convention_selected_by_arity.

THE MECHANISM WAS ISOLATED BEFORE IT WAS NAMED, because the fixture that exposed
it changed two things at once. Measured, each ruling out a plausible co-cause:
one field with NO exit block emits `output.status.success()` and is refused
E0308; one field WITH an exit block emits `0 => { output.status.success() }` and
is refused at the same grain, so the exit block is not load-bearing -- the exit
arm reaches the same projection; a lone `stdout` is refused exactly as a lone
`exit_success`, so the channel is not load-bearing; and TWO fields already emit
`Ok((output.status.success(), stdout.clone()))` and compile, so the boundary is
at one rather than at some larger shape. The arity is the whole mechanism.

SO IT IS A FORK, NOT A MISSING ARM: the Result convention is present and correct
at two fields and up, and an arity test chooses between two conventions where one
declaration should derive one. The trigger therefore names the capability -- the
return convention derived once, at the authority that also renders the signature
-- because "wrap the one-field case in Ok" would be satisfied by a second arity
branch, leaving the fork one arm wider.

THE SPECIMEN IS COMMITTED AS A RUNNABLE KNOWN-HOLE PAIR, which is the lesson its
sibling class records having learned twice: widening the argv fixture to the
output shape extdeps.rust.cargo_build actually declares had removed the only
instance from the tree. shell_single_field_projection_probe.dag (red, 1 x E0308)
and shell_multi_field_projection_probe.dag (control, compiles) differ in ONE
authored thing, so a green against a red locates the refusal at the arity.
Measured both directions. Per 4b(4) the red flips and is KEPT when the class
climbs. No repair here -- it was found by a different fixture being wrong, and
repairing it inside that subject would make one fixture carry two defects.

SECOND, THE CI FAILURE, WHICH WAS MINE. required-witnesses-build failed at
`generated-artifact stage0-mirrors FAIL generated surface drift: compiler_tests.rs`.
The stage0 mirrors are a GENERATION CHAIN: compiler_tests_rust.dag generates
v1_compiler_compiler_tests_rust.rs, and the binary built from THAT generates
compiler_tests.rs. Installing the first generation and stopping leaves the second
un-derived, so the drift appears only on the pass after the one I acted on. Local
regen said `first_generation_equal=false` twice and I read the named file list
instead of the flag -- a regen is a fixed-point iteration, and I stopped at one
pass.

WALKED TO THE FIXED POINT THIS TIME, one install and rebuild per generation:
pass 3 drifted v1_compiler_compiler_tests_rust.rs, pass 4 drifted
compiler_tests.rs (the file CI named), pass 5 reports
`first_generation_equal=true` with no FAIL line. All four generated
discrimination tests are present in compiler_tests.rs, and the three generated
mirrors are byte-identical to the candidate after cargo fmt, which touched only
the hand-authored host file.

cargo fmt --all --check clean; cargo clippy --all-targets -- -D warnings clean.

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

gunbai-bot Bot commented Sep 12, 2026

Copy link
Copy Markdown
Contributor Author

The four discrimination pairs, executed through the harness

The PR body says these pairs are #[ignore]d and runnable on demand. They have now been run, so that is a receipt rather than a description:

cargo test --release -p v1-compiler --lib -- --ignored --test-threads=1 \
  empty_map_turbofish_fixture_closure_discrimination \
  argv_word_list_splice_fixture_closure_discrimination \
  append_concat_form_fixture_closure_discrimination \
  shell_projection_arity_fixture_closure_discrimination

test result: ok. 4 passed; 0 failed; ... finished in 181.18s

This closes a gap worth naming, because it is the distinction the new failure-mode row in this PR exists to keep. Every fixture had been verified by emitting it and cargo build-ing the result by hand, which establishes that the emitter behaves. It does not establish that the pairs are WIRED: that fixture_discrimination_passed returns true, that the red arm is attributed to its own emitted module, and that the claimed E0308 is the diagnostic that actually came back. A pair whose wiring is unverified gets cited as coverage it does not carry.

All four passing means, per arm: the control compiled, the red reached a rustc verdict, the red did not compile, the red was attributed to its own emitted module, and its diagnostic carried the expected class.

The arity pair is the one this matters most for, because both of its arms are its own — green is the two-field control, red is the single-field known hole — so its pass is what confirms the known hole is genuinely attributed at the claimed class rather than merely red for some reason in some file.

Standing caveat, unchanged and not softened by this run: repo_self_test_command is off the merge path (gunbc.rung_drop rust_unit_tests_off_the_merge_path), so no CI path invokes these. This is an on-demand execution receipt, not enrollment, and the row's rung stays at mitigatable for exactly that reason.

— sent from cool-hawk-353

@gunbai-bot

gunbai-bot Bot commented Sep 12, 2026

Copy link
Copy Markdown
Contributor Author

On the seam observation in review 64440 — it is a real latent coupling, and here is its trigger

The review verified that the non-list argv arm's emit_rust_dag_string_to_host_via_seam is identity today and concluded that skipping it on the list arm introduces no divergence. I re-checked that independently and it holds — 05_emit_rust.dag:589-591 is fn emit_rust_dag_string_to_host_via_seam(dag_expr: String) -> String { dag_expr }, a literal identity.

Worth stating explicitly rather than leaving as a passing remark, because it is the more interesting half: the two arms are now coupled through a function only one of them calls. The .arg(..) arm routes each word through that seam; the .args(..) arm emits the binding directly. Those agree only while the seam is identity. If it ever becomes a real dag-String-to-host-String conversion, every word spliced through .args(..) would skip the conversion that every word passed through .arg(..) receives — and it would be silent, because both arms would still compile and the splice would still produce the right NUMBER of words.

That is the kind of divergence that is invisible at the site that causes it: a lane changing the seam has no reason to look at the argv splice, and the splice does not mention the seam.

Trigger, so it is not left to be rediscovered: the first change that makes emit_rust_dag_string_to_host_via_seam non-identity must route the word-list arm's elements through it too — per-element, since the seam is per-word — or state why a spliced run of words is exempt.

What I am NOT doing and why: not pushing a comment-only change for it right now. The seam is identity, so there is no behavioral defect to repair, and a push would stale the live approval and spend another full CI cycle on prose. If CI on a0486fdaee comes back requiring a push for any other reason I will fold the annotation in then; otherwise it is a follow-up. Recording it here rather than nowhere is the point — the durable home for it is an annotation beside shell_argv_element_is_word_list, not this thread.

— sent from cool-hawk-353

WHY THIS MERGE, and it is not routine housekeeping: required-witnesses-floor
refused the previous head on `namespace-wave-admission 1 stale admission(s)`, and
the stale row is not this branch's. It is gunbc#11137's
(`extdeps.tools.sha256sum names Filesystem instead of reaching it`), which merged
into main at 06:35 today. CI's admission base is main's tip, so that relocation
sits on BOTH sides of the comparison and the row matches no delta -- exactly the
interval gunbc.rung_drop namespace_admission_consumed_row_deletion describes as
"RESIDENT on main ... from that merge until a human deletes it ... pure
liability", whose stated caveat is the merge-in case. This branch's own delta
adjudicated clean in the same run (ExplicitlyEvaluatedZeroDelta on the new
recurring_failure_mode row). Moving the merge base past #11137 is the sanctioned
response; the branch was 20 commits behind regardless.

THE DERIVED MIRROR WAS RESOLVED BY REGENERATION, NOT BY TAKING A SIDE. Only
src/v1/stage0/src/v1_compiler_emit_rust.rs came back unmerged -- the
generated-artifact driver refusing rather than answering, as designed, since both
sides changed it. src/v1/05_emit_rust.dag and cli_run.rs auto-merged cleanly, so
the authorities agree and only their projection needed deciding.

An ours-side bootstrap could not even compile: main added a `FileChanErrorKind`
variant to FileResultChannel that this branch's mirror predates (E0004). So the
seed was bootstrapped from MAIN's side of the mirror purely to get a compiling
compiler, then the mirror was regenerated from the MERGED authorities and
installed -- and the installed bytes carry BOTH sides, which is the property
neither --ours nor --theirs would have produced: 7 occurrences of this branch's
three arms AND main's FileChanErrorKind handling. Verified to a fixed point:
pass 1 drifted v1_compiler_emit_rust.rs, pass 2 reports
first_generation_equal=true. No ours-bootstrap bytes are review-visible, because
the regeneration lands in this same commit.

THE THREE ARMS RE-MEASURED ON THE MERGED TREE rather than assumed to have
survived: 17 `.args(..)` splices in extdeps_cargo_build, the empty-map turbofish
still `::<_, _>()`, 3 rc_list_concat and ZERO v1_rt::append in
extdeps_exec_command.

THE MERGED CLOSURE CARRIES NINE ERRORS THAT ARE NOT THIS BRANCH'S, and they are
reported rather than absorbed. Main widened this closure, which is the same
"accepted for as long as nobody emitted it" mechanism this branch's own work
documents. Both are already-rostered components of
gunbc.recurring_failure_mode.accepted_source_emits_uncompilable_target with their
own triggers, so neither is repaired here:

  - E0432 `unresolved import crate::std_types::Unit` at extdeps_cargo_build.rs:14.
    The emitted use-line gained `Unit` (pre-merge `{Bool, FilePath, NonEmptyStr}`,
    post-merge `{Bool, FilePath, NonEmptyStr, Unit}`) while emitted std_types
    exports no Unit. Component (viii), use-lines derived from SOURCE references
    rather than from the emitted reference set.
  - 8 x E0308 in std_string_type.rs, a file ABSENT from this closure before the
    merge and pulled in by it. `left = __tco_0;` assigns a String into the
    Rc<Vector<i64>> FreeMonoid<Char> carrier through the TCO rewrite. Component
    (iv), the std.string_type carrier-versus-primitive disagreement.

So the positive control is NOT green on the merged tree, and this commit does not
claim it is: the three classes this branch repairs are measured fixed, and the
closure carries nine pre-existing-class errors main introduced.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012xQnkeiJ1pnEpMgqh3dE1e
Brian Searls and others added 2 commits September 12, 2026 08:23
Review 64440 on gunbc#11154 verified that the one-word argv arm's
emit_rust_dag_string_to_host_via_seam is the identity today and concluded the
word-list arm skipping it introduces no divergence. That is correct, and the more
useful half is what it implies: the two arms are now coupled through a function
only one of them calls.

They agree only while that seam is identity. If it becomes a real
dag-String-to-host-String conversion, every word spliced through the list arm
skips the conversion every word through the one-word arm receives -- silently,
because both arms still compile and the splice still yields the right NUMBER of
words. The coupling is invisible at the site that would break it: a lane changing
the seam has no reason to read the splice, and the splice never named the seam.
It does now, with the trigger stated beside it.

I said on the PR I would fold this in if another push became necessary rather
than spend a CI cycle on prose alone. It did, so this rides along.

MEASURED RATHER THAN ASSUMED, because DESIGN 4c's disjointness of annotation
capture from semantic emission is itself a claim and
gunbc.recurring_failure_mode.content_digest_makes_annotations_semantically_load_bearing
is a rostered class: required-regen over this annotation-only edit reports
first_generation_equal=true, so the emitted bytes are byte-identical with the new
block in place and no mirror needed reinstalling.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012xQnkeiJ1pnEpMgqh3dE1e
review 64464 found this diff committing the defect its own headline arm exists to
repair: `is_list_typed_expr` and `shell_argv_param_is_word_list` were two
spellings of one question -- is this type an ordered run of elements -- authored
in the same change as `rust_empty_map_init_expr`, which exists because two sites
asking one question is the second representation DESIGN section 2 forbids. The
finding is correct and is fixed in code rather than argued with.

THE DIVERGENCE WAS A LATENT MISCLASSIFICATION, NOT A STYLE MATTER, which is why
consolidating repairs rather than tidies. The two conjunctions had ALREADY
diverged: `is_list_typed_expr` excluded a string carrier and the argv-parameter
reader did not. In this substrate `String` IS `FreeMonoid<Char>`, so a string
carrier spelled structurally satisfies node_is_element_collection -- and the argv
reader would then classify a shell input declared that way as a run of words and
splice it, when a string is ONE argv word.

THE EXCLUSION IS RIGHT FOR BOTH CONSUMERS, SO IT IS NOW DECIDED ONCE. For
`append`, a string second argument must be snoc and not concat, which is the
interpreter's own rule -- its concat arm tests Value::Str before asking
value_to_list_carrier. For an argv element, a string must be one word and never a
splice. Two consumers, one reason: a string is an atom to both even though its
carrier is a sequence. `type_node_is_ordered_element_run` carries the whole
conjunction and both readers project onto it.

NO EMISSION CHANGED, AND THAT IS MEASURED RATHER THAN ASSERTED, because it is the
evidence for WHY the divergence was latent rather than live: the ordinary spelling
`word: String` is a zero-child leaf excluded by ARITY alone, not by the string
test. Emitted extdeps_cargo_build.rs and extdeps_exec_command.rs are BYTE-IDENTICAL
before and after the consolidation. Had they differed, the explanation above would
have been wrong. The argv fixture still emits its four `.args(..)` splices and its
one `.arg(word)`, and its crate still builds. Regen at fixed point
(first_generation_equal=true).

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

gunbai-bot Bot commented Sep 12, 2026

Copy link
Copy Markdown
Contributor Author

review 64464 — fixed in f991009666, and it was a fair hit

The finding is correct and I am not going to soften it: this diff committed the defect its own headline arm exists to repair. is_list_typed_expr and shell_argv_param_is_word_list were two spellings of one question — is this type an ordered run of elements — authored in the same change as rust_empty_map_init_expr, whose whole justification is that two sites asking one question is the second representation §2 forbids. Three hundred lines apart in one diff.

The divergence was a latent misclassification, not a style matter, which is why consolidating repairs rather than tidies. The review is right that the conjunct sets had already diverged: is_list_typed_expr excluded a string carrier, the argv reader did not. In this substrate String is FreeMonoid<Char>, so a string carrier spelled structurally satisfies node_is_element_collection — and the argv reader would then have classified a shell input declared that way as a run of words and spliced it, when a string is one argv word.

The exclusion is right for both consumers, so it is now decided once. For append, a string second argument must be snoc and not concat — the interpreter's own rule, testing Value::Str before value_to_list_carrier. For an argv element, a string must be one word and never a splice. Two consumers, one reason: a string is an atom to both even though its carrier is a sequence. type_node_is_ordered_element_run now carries the whole conjunction and both readers project onto it.

No emission changed, and that is measured rather than asserted, because it is the evidence for why the divergence was latent rather than live:

subject result
emitted extdeps_cargo_build.rs byte-identical before/after
emitted extdeps_exec_command.rs byte-identical before/after
argv fixture 4 × .args(..) + 1 × .arg(word) preserved, crate builds
regen first_generation_equal=true

The reason is that the ordinary spelling word: String is a zero-child leaf excluded by arity, not by the string test — so the string conjunct was never reached in practice. Had the bytes differed, that explanation would have been wrong, which is why I checked it instead of claiming it.

— sent from cool-hawk-353

OPERATOR RULING A (eager-raven-113). required-witnesses-floor refused this branch
twice -- a0486fd and f991009 -- on `namespace-wave-admission 1 stale
admission(s)`, with the floor itself clean both times (verdict=FloorClean,
unexpected_failures=0) and this branch's own delta adjudicated clean
(ExplicitlyEvaluatedZeroDelta on the new recurring_failure_mode row). The single
blocker was gunbc#11137's row, whose own recorded trigger was "this row goes when
#11137 merges". #11137 merged as 34d2a8d, so the trigger fired; a consumed
row's deletion comes due on this roster's OWN next touch, and this change is that
touch. The roster returns to its resting state, empty, and nothing else in the
file changes.

MERGING MAIN DOES NOT CLEAR IT, WHICH I ASSERTED EARLIER AND WAS WRONG ABOUT.
gunbc.rung_drop namespace_admission_consumed_row_deletion says so in terms: the
row is RESIDENT on main "from that merge until a human deletes it", an interval
that "can never match a delta and is therefore pure liability". Human deletion is
the declared remedy and no push to this branch's own files could substitute.

THE EVIDENCE IS GIT IDENTITY, NOT A `CONSUMED ADMISSION` RECEIPT, and the
difference is recorded in the dissolution rather than glossed. Every dissolution
above this one cites the wall printing `CONSUMED ADMISSION ... already satisfied
at the base`. This one cannot: on this branch the wall printed `STALE ADMISSION
... matches no delta in this run` and failed the phase. So the fired trigger is
established by ancestry -- 34d2a8d is an ancestor of this run's base -- which
is exactly what the trigger sentence names.

THAT DISCREPANCY IS NOTED AS UNVERIFIED AND DELIBERATELY NOT CHASED HERE, per the
ruling. gunbc#9824 split ConsumedByMerge from UnmatchedAdmission precisely so a
row whose relocation the base already satisfies stops refusing unrelated pull
requests, and this row took the second arm where the first looks applicable.
Whether admission_consumed_at_base fails to recognise a TargetChanged binding
whose module and target are the same module, or whether the arm is right and my
reading is wrong, is UNVERIFIED: I read no code in that path, and nothing here may
be cited as a finding about it. It belongs to that mechanism's owner, because if
the hole is real then deleting one row treats a symptom while the mechanism keeps
producing them.

ONE MEASURED FACT WORTH CARRYING, recorded in the dissolution: main's own run of
this phase prints `NO SUBJECT -- the merge base against origin/main IS <tip>, so
this run has no diff to adjudicate`. main is therefore green on this phase
VACUOUSLY, and a resident row bills pull requests from a position where no push
run can observe it.

cargo fmt --all --check clean; cargo clippy --all-targets -- -D warnings clean
with the roster empty.

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

gunbai-bot Bot commented Sep 12, 2026

Copy link
Copy Markdown
Contributor Author

srv2 closure receipt on b18577e — DIAGNOSTIC, not a landing receipt (this PR is held behind #10940 under the closure-manifest hold).

Tested composition: PR diff overlaid on main 4ba07a4 (overlay tree d8ad1224c1; main had moved past the eighth-baseline source 9027238 by then — see delta). Receipt producer claim_executor_pinned sha256 989d3ab8b230fb02; instrument closure_pr.sh sha256 b8190c19bf0b54b5, legacy invocation (this head's driver has no mode dispatch). Route: emitted, built, v2-native-route running the emitted compiler; native fold EXIT=0; 167-module closure manifest.

Comparison baseline: eighth baseline, main 9027238, closure_main.sh sha256 fdeb927035a0e880, producer f7903300df54c398, 14 refusal identities.

Identity joins: regressed (in receipt, not in baseline) = none; fixed (in baseline, not in receipt) = none; manifest membership identical (167/167 by path). The 14 identities are the same 13 parse_g0_tokens_remain + normalize_reason_post_normalize_not_well_formed (src/v2/std/runtime.dag).

Currency: the overlay main 4ba07a4 differs from the baseline source 9027238 on one manifest member (dag/std/measure.dag) and five src/v1 files (cli_run.rs, cli_run/entry_resolve.rs, cli_run/required_floor_runner.rs, required_regen_host.rs, std_measure.rs), and origin/main has since moved again (namespace_wave_admission.rs + its test). So this join is a diagnostic over a mixed composition, stated as such; the binding receipt is re-taken against a current baseline when the hold lifts.

What it answers for cool-hawk's nine errors: the closure fold's file-refusal population is unchanged by this PR relative to main; the nine cargo-build errors in the emitted extdeps.rust.cargo_build closure are a different observation (emit+cargo-build of a wider closure) that this instrument does not execute, so they are neither confirmed nor contradicted here. Attribution of those nine stays with the emit+build instrument on main vs the head, pre- and post-merge.

— sent from eager-raven-113

…'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
@briansrls
briansrls merged commit 78e8a18 into main Sep 12, 2026
4 checks passed
@briansrls
briansrls deleted the session/cool-hawk-353 branch September 12, 2026 14:30
gunbai-bot Bot pushed a commit that referenced this pull request Sep 12, 2026
…re its row

MERGE of origin/main dfac90c (#11121, #11142, #11154, #10986). Three
conflicts. namespace_wave_admission.rs: main's THIRTY-SIXTH DISSOLUTION record
kept, this branch's 181 still-required rows kept with their 181
expected_candidates. accepted_source_emits_uncompilable_target.dag: took MAIN's
side -- their rung claim is mechanically preventable backed by executing
evidence, this branch's said still-mitigatable and is superseded, and their four
added receipts are preserved. v1_compiler_emit_rust.rs: resolved BY REGEN, never
text-merged; main's bytes stood as a placeholder and the regenerated mirror
overwrote them from the merged .dag authority.

THE WALK IS REPAIRED RATHER THAN DEFERRED, because the primitive it was waiting
for is now in the tree. #11121 landed as dfac90c (v2.std.collection
primitive-backed map_insert/map_lookup delegates), which is the capability the
declared drop named. DESIGN section 6: a proven cost-shape defect is always
fixed, and a trigger amended after the capability arrives is a deferral with
better wording.

SHAPE. native_lane_facts_index builds module -> imports ONCE, before the
recursion. native_lane_module_reachable looks up only what the frontier names and
carries seen_set through the recursion. Neither is rebuilt per round: rebuilding
either would reintroduce the cost under a keyed spelling.

A MODULE DECLARED TWICE APPENDS, AND THIS IS THE CASE A REVIEW WOULD HAVE
PLANTED. The fold this replaces visited every fact whose module the frontier
named, so two facts declaring one module contributed BOTH import lists. A naive
map_insert keeps the last and SHRINKS the closure -- a behaviour change wearing a
performance change's clothes, and the same silent narrowing this PR has already
repaired twice. The index appends on a duplicate key.

PRESERVED: declared membership; the refusal arms (fuel exhaustion still refuses
the whole derivation by identity with budget and frontier); last-round
completion.

DIVERGED, DELIBERATELY AND STATED ON THE CARRIER: discovery order is FRONTIER
order, not FACT order. Preserving fact order needs a per-round pass over all
modules to re-derive it -- the repeated scan this repair removes. It is
unobservable, checked rather than assumed: native_lane_closure_ingest filters by
membership (the ingest supplies its own order), both halves of
native_lane_ingest_matches_closure are membership tests, and the emitted receipt
carries `closure.len()`, a count, never the sequence. If a consumer that reads
the sequence ever appears, THAT change owns this order fact; it cannot be
inherited silently from here.

NOT CLAIMED: that the route is now O(closure). One walk changed. The instrument
is the universe_derivation span -- 192.4 s at 36e6ad9 -- and the successor run
on this head is the before/after. No cost witness is added: no corpus home can
hold a planted-quadratic control for this walk inside the 500 ms line without a
synthetic population that exceeds it, and a witness that cannot discriminate is
worse than none.

ROW RETIRED BY ITS TRIGGER, with the repair as the discharge, in this same
commit -- never in an intermediate state with the original scan still standing.
Retiring on the capability alone would have been the 4b(3) inflation: a row
marked discharged with the quadratic walk intact.

CITATIONS (review 64576). The row's population named native_lane_closure_grow,
which exists nowhere -- a section 3 citation defect, and worst in that field,
because 4b(3) requires a BOUNDED population and an unreadable member means
whoever discharges the row cannot enumerate what to delete. Corrected to the real
symbols. Every candidate symbol in both rung-drop rows and the seed-growth row
was then swept by git grep: 26 checked, all resolve.

AND THE REPAIR RE-STALED A CITATION FIXED MINUTES EARLIER: once the walk stopped
calling native_lane_facts_module_named, the `Consumers:` comment naming it was
wrong again. Corrected, and it now says the frontier walk no longer reads it.

Both projections regenerated mechanically on the final tree: the stage0 mirror
(installed from the candidate) and docs/design-rung-drops.md (4 added, 2 removed,
carrying the retirement).

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