Skip to content

required-regen: the population gate compared two key spaces and refused vacuously on every run - #8518

Merged
briansrls merged 1 commit into
mainfrom
fix/required-regen-can-execute
Aug 19, 2026
Merged

briansrls merged 1 commit into
mainfrom
fix/required-regen-can-execute

Conversation

@gunbai-bot

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

Copy link
Copy Markdown
Contributor

generated_basenames_from_emit inserted the full emit key ("src/std_nat.rs") while
committed_generated_basenames inserts file_name() ("std_nat.rs"), and
validate_compared_populations compares the two sets directly. The two key spaces
cannot intersect, so the ENTIRE population mismatched in both directions on every
run since the check was written. Nothing behind that gate was ever checked, and the
real rows were buried under 264 lines of noise.

Both sides now key on file_name(). The two hand-maintained predicates already
agreed (is_hand_maintained_path takes the basename, same roster), so this was the
only fork.

WHAT THIS CLAIMS. required-regen executes end to end -- parse, typecheck, emit,
candidate write attempted. It still REFUSES, and the refusal is now correct and
readable: 10 real rows instead of 264 noise rows.

emitted_not_committed = [v1_compiler_trait_bound_witness.rs]
committed_not_emitted = 9 files absent from HAND_MAINTAINED_STAGE0_FILES

Those 10 are genuine debt and are NOT addressed here. They are not uniform -- two
have live .dag sources, one does not, several are hand-authored with no authority,
one is produced by a different generator -- so they need separate dispositions, not
nine names added to a roster to make the gate green. That would silence the signal
this change exists to expose, and the roster is itself generated ("do not
hand-edit", authority v2.compiler.self_host.stage0_crate_layout).

SCOPE REDUCED SINCE THE FIRST HEAD, AND ONE CLAIM RETRACTED. This branch previously
also carried a change to src/v1/trait_bound_witness.dag, and asserted that a
single-variant coproduct is not expressible in this dialect. THAT ASSERTION WAS
FALSE. #8519 landed the correct form -- = | Variant, with a leading pipe, an
established corpus idiom (extdeps.ipc.dpmx, extdeps.npm,
extdeps.advertising.google_ads). I had executed two spellings, seen both refuse, and
generalized to impossibility without grepping for how the corpus already writes one.
Verified after the fact: main's leading-pipe form typechecks, reaching the population
gate with no unresolved-type diagnostic. The .dag half is dropped; #8519 owns it.

Verified remotely with a must-fail control so a no-op cannot read as a pass:
Applied patch src/v1/stage0/src/required_regen_host.rs cleanly.
CONTROL_EXIT=101 (cargo check -Z definitely-not-a-real-flag)
BUILD_EXIT=0 compiling=105
REGEN_EXIT=1 with the 10-row refusal above

KNOWN AND NOT FIXED HERE (found by snappy-seal-402, confirmed by reading the code):
write_emitted_tree iterates every emit key with no .rs filter and runs the Rust
normalizer over each, so a non-Rust entry aborts the tree write. Same key-space fork
as this one -- the comparison filters .rs, the write does not. Follow-up, with the
10-row disposition.

Companion: #8516 (fix-forward for the #8468 merge). Supersedes the .dag half in favour of #8519.


🤖 Generated with Claude Code

https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

gunbai-bot Bot pushed a commit that referenced this pull request Aug 19, 2026
… silently reverted

#8468 was merged with a stale resolution of one generated file. The
generated-artifact merge driver refuses rather than answering: it leaves the
path unmerged with the OURS side in the worktree and NO conflict markers. The
ours side was the branch's seed, which predated main adding the function-value
call lowering, so the merge reverted it in the committed seed only:

                                     dag   seed(merged)   seed(now)
  call_semantics_is_function_value     3        0             3
  emit_typed_function_value_call       2        0             2
  rust_callable_return_wrap            2        0             2
  callee_is_function_value             9        0             7

No other seed file referenced those symbols, so the tree still built. The
regression was SILENT, not loud -- 04_infer.dag still constructs
FunctionValueCallSemantics, so the variant is live and the running compiler
stopped lowering it. Nothing would have reported this.

RECONSTRUCTED, NOT PATCHED. The file is taken from pre-merge main
(8b20599) with #8468's intended delta re-applied on top, rather than
hand-adding the missing symbols back. Verified by diffing the result against
pre-merge main: it contains the hand_maintained_map_key_required_type_names
roster wired into the same fixpoint and NOTHING ELSE, and
callee_is_function_value is back to its pre-merge count of 7.

The PR's other two intended changes needed no action here and are confirmed
intact on main: std::hash::Hash on ItemKind (v1_compiler_infer_items.rs is
byte-identical to main -- it survived the bad merge) and obs_human_elapsed
(v1_compiler_runtime_rust.rs was never conflicted).

Verified remotely with a must-fail control so a no-op cannot read as a pass:
  Applied patch src/v1/stage0/src/v1_compiler_emit_rust.rs cleanly.
  CONTROL_EXIT=101 (cargo check -Z definitely-not-a-real-flag)
  BUILD_EXIT=0  compiling=105  finished=1  errors=0

THIS IS THE INTERIM, NOT THE FIX. It hand-resolves generated bytes, which is
precisely what caused the problem. required-regen cannot currently produce the
authoritative bytes (see #8518, which makes it execute but not pass), so
regeneration is unavailable. The regenerated bytes supersede these the moment
it can produce them, and this file should not be treated as authoritative in
the meantime.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5
…ed vacuously on every run

`generated_basenames_from_emit` inserted the full emit key ("src/std_nat.rs") while
`committed_generated_basenames` inserts `file_name()` ("std_nat.rs"), and
`validate_compared_populations` compares the two sets directly. The two key spaces
cannot intersect, so the ENTIRE population mismatched in both directions on every
run since the check was written. Nothing behind that gate was ever checked, and the
real rows were buried under 264 lines of noise.

Both sides now key on `file_name()`. The two hand-maintained predicates already
agreed (`is_hand_maintained_path` takes the basename, same roster), so this was the
only fork.

WHAT THIS CLAIMS. required-regen executes end to end -- parse, typecheck, emit,
candidate write attempted. It still REFUSES, and the refusal is now correct and
readable: 10 real rows instead of 264 noise rows.

  emitted_not_committed = [v1_compiler_trait_bound_witness.rs]
  committed_not_emitted = 9 files absent from HAND_MAINTAINED_STAGE0_FILES

Those 10 are genuine debt and are NOT addressed here. They are not uniform -- two
have live .dag sources, one does not, several are hand-authored with no authority,
one is produced by a different generator -- so they need separate dispositions, not
nine names added to a roster to make the gate green. That would silence the signal
this change exists to expose, and the roster is itself generated ("do not
hand-edit", authority v2.compiler.self_host.stage0_crate_layout).

SCOPE REDUCED SINCE THE FIRST HEAD, AND ONE CLAIM RETRACTED. This branch previously
also carried a change to src/v1/trait_bound_witness.dag, and asserted that a
single-variant coproduct is not expressible in this dialect. THAT ASSERTION WAS
FALSE. #8519 landed the correct form -- `= | Variant`, with a leading pipe, an
established corpus idiom (extdeps.ipc.dpmx, extdeps.npm,
extdeps.advertising.google_ads). I had executed two spellings, seen both refuse, and
generalized to impossibility without grepping for how the corpus already writes one.
Verified after the fact: main's leading-pipe form typechecks, reaching the population
gate with no unresolved-type diagnostic. The .dag half is dropped; #8519 owns it.

Verified remotely with a must-fail control so a no-op cannot read as a pass:
  Applied patch src/v1/stage0/src/required_regen_host.rs cleanly.
  CONTROL_EXIT=101 (cargo check -Z definitely-not-a-real-flag)
  BUILD_EXIT=0  compiling=105
  REGEN_EXIT=1 with the 10-row refusal above

KNOWN AND NOT FIXED HERE (found by snappy-seal-402, confirmed by reading the code):
`write_emitted_tree` iterates every emit key with no `.rs` filter and runs the Rust
normalizer over each, so a non-Rust entry aborts the tree write. Same key-space fork
as this one -- the comparison filters `.rs`, the write does not. Follow-up, with the
10-row disposition.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5
@gunbai-bot
gunbai-bot Bot force-pushed the fix/required-regen-can-execute branch from 1a16dd0 to 497c7b9 Compare August 19, 2026 05:35
@gunbai-bot gunbai-bot Bot changed the title required-regen can execute: unparseable module, inexpressible declaration, vacuous population gate required-regen: the population gate compared two key spaces and refused vacuously on every run Aug 19, 2026
@gunbai-bot

gunbai-bot Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor Author

RETRACTION, and a scope reduction, both on this PR's prior head.

I claimed a single-variant coproduct is not expressible in this dialect. That was false. #8519 landed the correct form while this branch was open:

type TraitBoundWitnessScope
  = | BoundedToDirectTopLevelMatchBody

A leading pipe, and an established corpus idiom — extdeps/ipc/dpmx.dag:24, extdeps/npm.dag:75, extdeps/advertising/google_ads.dag:91, all findable with one grep I never ran. I had executed exactly two spellings (type X = V inline and multi-line), seen both refuse with unresolved type, and generalized from two samples to a claim about the whole language.

Verified after the fact rather than assumed: main's leading-pipe form reaches the population gate with no unresolved-type diagnostic, so it parses and typechecks.

Consequence for this PR: the .dag half is dropped entirely and #8519 owns it. What remains is one defect — the population gate comparing src/-prefixed emit keys against bare basenames, so it refused vacuously on every run since it was written. That fix is unaffected by the retraction and independently verified.

The earlier approval was scored against a head that contained the false claim and the now-superseded .dag change, so it should not carry forward; this head is materially different and wants a fresh look.

Also recorded here so it is not lost: write_emitted_tree iterates every emit key with no .rs filter and runs the Rust normalizer over each, so a non-Rust entry aborts the tree write — found by snappy-seal-402, confirmed by reading the code. It is the same key-space fork as the one fixed here (the comparison filters .rs, the write does not), and it is a follow-up rather than a fourth fix on an approved head.

— sent from smart-ram-730

briansrls pushed a commit that referenced this pull request Aug 19, 2026
… silently reverted (#8516)

#8468 was merged with a stale resolution of one generated file. The
generated-artifact merge driver refuses rather than answering: it leaves the
path unmerged with the OURS side in the worktree and NO conflict markers. The
ours side was the branch's seed, which predated main adding the function-value
call lowering, so the merge reverted it in the committed seed only:

                                     dag   seed(merged)   seed(now)
  call_semantics_is_function_value     3        0             3
  emit_typed_function_value_call       2        0             2
  rust_callable_return_wrap            2        0             2
  callee_is_function_value             9        0             7

No other seed file referenced those symbols, so the tree still built. The
regression was SILENT, not loud -- 04_infer.dag still constructs
FunctionValueCallSemantics, so the variant is live and the running compiler
stopped lowering it. Nothing would have reported this.

RECONSTRUCTED, NOT PATCHED. The file is taken from pre-merge main
(8b20599) with #8468's intended delta re-applied on top, rather than
hand-adding the missing symbols back. Verified by diffing the result against
pre-merge main: it contains the hand_maintained_map_key_required_type_names
roster wired into the same fixpoint and NOTHING ELSE, and
callee_is_function_value is back to its pre-merge count of 7.

The PR's other two intended changes needed no action here and are confirmed
intact on main: std::hash::Hash on ItemKind (v1_compiler_infer_items.rs is
byte-identical to main -- it survived the bad merge) and obs_human_elapsed
(v1_compiler_runtime_rust.rs was never conflicted).

Verified remotely with a must-fail control so a no-op cannot read as a pass:
  Applied patch src/v1/stage0/src/v1_compiler_emit_rust.rs cleanly.
  CONTROL_EXIT=101 (cargo check -Z definitely-not-a-real-flag)
  BUILD_EXIT=0  compiling=105  finished=1  errors=0

THIS IS THE INTERIM, NOT THE FIX. It hand-resolves generated bytes, which is
precisely what caused the problem. required-regen cannot currently produce the
authoritative bytes (see #8518, which makes it execute but not pass), so
regeneration is unavailable. The regenerated bytes supersede these the moment
it can produce them, and this file should not be treated as authoritative in
the meantime.


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

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
@briansrls
briansrls merged commit 2286381 into main Aug 19, 2026
1 check passed
@briansrls
briansrls deleted the fix/required-regen-can-execute branch August 19, 2026 07:31
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