Skip to content

The function-value adapter, judged by rustc: an opt-in pair through #9911's fixture-closure route - #9989

Merged
gunbai-bot[bot] merged 11 commits into
mainfrom
session/snappy-koi-286
Sep 2, 2026
Merged

gunbai-bot[bot] merged 11 commits into
mainfrom
session/snappy-koi-286

Conversation

@gunbai-bot

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

Copy link
Copy Markdown
Contributor

What was missing

#9911 landed a capability: fixture_closure_rustc_verdict / run_fixture_closure_discrimination — a fixture a test can author, emitted through the same compile_sources, written by the same crate writer, handed to the same run_cargo, and judged by rustc. Its own pair proves the route works, over the text-boundary fixture.

This PR spends that capability on a second subject, chosen because it is one a text oracle cannot judge at all: v1.compiler.emit_rust rust_call_arg_function_value_adapt.

An arrow type has two Rust renderings, both correct for what they carry — a function value is Rc<dyn Fn(..) -> ..> (callable_type_template), a function-typed parameter is impl Fn(..) -> .. + Clone (emit_rust_param_type) — and Rc<F> has no blanket impl Fn in std the way Box<F> does. The adapter closes that seam at the call position. Its claim is a TRAIT OBLIGATION, and a trait obligation is not a spelling: compile_dag_rust_emit_check can assert __adapt_f appears in the emitted bytes and still say nothing about whether the wrapper satisfies the bound.

The pair is minimal-difference by construction

Both arms declare the same producer, the same consumer, the same call. They differ in one authored spelling:

  • fixtures/fixture_closure_rustc/function_value_adapter_probe.dag — passes the producer's result as a call expression, the shape the adapter keys on.
  • fixtures/fixture_closure_rustc/function_value_let_probe.dag — binds that identical result to a let first and passes the binding, which the adapter deliberately does not touch.

So a green here is not "some crate compiled" and the red is not "something in the tree is broken": the only variable across the arms is whether the adapter fired.

Executed, both directions

cargo test --release -p v1-compiler --lib function_value_adapter_fixture_closure_discrimination -- --ignored --nocapture, one BuildBuddy runner:

control Measured files=6 cargo=Completed status=0
red     Measured files=6 cargo=Completed status=101
  error[E0277]: expected a `Fn(i64)` closure, found `Rc<dyn Fn(i64) -> i64>`
    --> src/fixture_closure_rustc_function_value_let_probe.rs:22:11
  22 | let_apply(staged.clone(), 41)
  note: required by a bound in `let_apply`
  15 | pub fn let_apply(f: impl Fn(i64) -> i64 + Clone, x: i64) -> i64 {
red attribution --> src/fixture_closure_rustc_function_value_let_probe.rs:22:11
pair PASSED
test result: ok. 1 passed; ... finished in 173.84s

Attributed to the fixture's own emitted module, which is what separates "rustc refused this fixture" from "the closure was already red".

The red arm is a KNOWN HOLE, not a wall working

gunbc accepts the red fixture with zero blocking diagnostics and emits a crate rustc refuses — gunbc.recurring_failure_mode accepted_source_emits_uncompilable_target, at the function-value seam rather than at that row's coproduct-variant construction, and committed here as runnable files, which that row records its own specimen never was. What this instance adds to the class: the mask is a call-site spelling, so the discriminator for this shape is to re-spell an accepted call through a let and re-emit.

When the hole closes — the emitter adapting a let-bound arrow value, or the front end refusing the construction — the arm flips and is kept as a permanent regression control (DESIGN §4b(4)). What changes then is the pair's expectation, not the fixture.

Where it executes — the honest grain, on #9911's own terms and with nothing added

#[ignore]d. ENROLLED AND OPT-IN via cargo test --release -p v1-compiler --lib function_value_adapter_fixture_closure_discrimination -- --ignored; does not execute by default on push or PR; and rust-unit-tests is not a needs of the required aggregate, so even un-ignored a red would be visible and would not block through the required context.

Candidate evidence, no wall. An #[ignore] is a cost decision and NOT a rung: this establishes no rung for the adapter and discharges no next-rung trigger naming it. The reversal condition is the one that carrier already states (rust-unit-tests promoted into the required aggregate) and is not re-minted here.

Seed growth

Three declarations, enumerated rather than counted, in gunbc.emitted_closure_compile_seed_growth: FIXTURE_ADAPTER_GREEN_PATH, FIXTURE_ADAPTER_RED_PATH, run_function_value_adapter_discrimination. Everything else is reused: fixture_arm_verdict runs each arm, fixture_discrimination_passed adjudicates, fixture_discrimination_report prints — a second discrimination, not a second harness. Census re-derived against the file: 78 declarations / 78 rows, zero stale, zero unaccounted. The cli_run #[cfg(test)] re-export list is ExistingSeedItemModified. No edit to the emitter, no row on required_emit_compile_entries, no CLI flag, no workflow change, no production re-export.

The blob carries its gunbc.language_source_scaffold_index row. Noted while there: five ct_* blobs on main have no row (ct_fixture_closure_rustc_discrimination_test, ct_generic_param_declines_fail_closed_unwrap_test, ct_import_lines_follow_resolved_binding_identity_test, ct_shell_service_output_projection_known_hole_probe_test, ct_witness_carrier_declines_non_witness_expected_type_test), so compiler_tests_rust_blobs_are_all_rostered is already short — pre-existing, not repaired here.

What is deliberately NOT in this diff

The accepted_source_emits_uncompilable_target ledger row is not appended, and the reason is an instrument that would not run rather than an omission: that row is projected into docs/design-ledgers.md, so editing it requires re-running gunbc run --entry dag/gunbc/instruments/generated_artifact_gate.dag --function main_wet. Measured on the runner available to this lane: HostBudgetUnreadable with no cgroup limit, and MemoryStallRefusedPageThrash under a 12 GiB and again a 30 GiB cgroup during the whole-corpus resolve. Landing the carrier edit without its projection is exactly the drift the gate exists to catch, so the instance is recorded in gunbc.emitted_closure_compile_seed_growth and in the two fixture files, and the ledger append is left to a lane that can execute that actuator.

Checks

cargo fmt --all --check (pre-commit hook), cargo clippy --all-targets -- -D warnings clean, and the two generated projections (compiler_tests.rs, v1_compiler_compiler_tests_rust.rs) are --required-regen output installed to a fixed point (a third pass installs nothing).

🤖 Generated with Claude Code

https://claude.ai/code/session_015XNpHkAWNSqikzKqspogbY

gunbc-ci-auto-heal and others added 4 commits September 2, 2026 02:19
…9911's fixture-closure route

#9911 landed a CAPABILITY — a fixture-authorable subject reaching rustc over its
emitted closure. This spends it on a subject that cannot be posed to a text oracle
at all: `v1.compiler.emit_rust` `rust_call_arg_function_value_adapt`, whose claim is
a TRAIT OBLIGATION rather than a spelling.

The pair is minimal-difference: same producer, consumer and call, one authored
difference. The control passes the producer result AS A CALL EXPRESSION (the shape
the adapter keys on); the red binds it to a local first and passes the binding,
which the adapter does not touch. So the only variable across the arms is whether
the adapter fired.

Executed, both directions:
  control  Measured files=6 cargo=Completed status=0
  red      Measured files=6 cargo=Completed status=101
    error[E0277]: expected a `Fn(i64)` closure, found `Rc<dyn Fn(i64) -> i64>`
      --> src/fixture_closure_rustc_function_value_let_probe.rs:22:11
    pair PASSED, test result: ok in 173.84s

The red is a KNOWN HOLE, not a wall working: gunbc accepts it with zero blocking
diagnostics and emits a crate rustc refuses — `gunbc.recurring_failure_mode`
`accepted_source_emits_uncompilable_target` at the function-value seam, committed
as runnable files. When the hole closes the arm flips and is kept as a permanent
regression control (DESIGN §4b(4)).

Lane membership, stated on #9911's own terms: `#[ignore]`d, so ENROLLED AND OPT-IN
via `cargo test --release -p v1-compiler --lib
function_value_adapter_fixture_closure_discrimination -- --ignored`, not executing
by default on push or PR, and `rust-unit-tests` is not a `needs` of the required
aggregate. Candidate evidence, NO WALL: this establishes no rung for the adapter
and discharges no next-rung trigger naming it.

Three new hand-Rust declarations, all enumerated in
`gunbc.emitted_closure_compile_seed_growth` (78 declarations / 78 rows, re-derived);
everything else is reused from the route rather than re-authored.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015XNpHkAWNSqikzKqspogbY
…s-is; regenerated in the next commit)

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015XNpHkAWNSqikzKqspogbY
The generated-artifact merge driver left the ours side in the worktree by
design, so the merge commit carried compiler_tests.rs and
v1_compiler_compiler_tests_rust.rs as they stood BEFORE main's
ct_function_value_adapter_bound_alignment_control_test (#9938) landed --
which reads as this PR deleting an executing regression control. It does
not: the bytes here are --required-regen output over the merged .dag
sources, and both blobs are present. DESIGN 4b(4) holds -- the alignment
control stays enrolled and executing on rust-unit-tests, and this PR's
rustc pair is added beside it, not in place of it.

Re-verified on the merged tree: pair PASSED, control status=0, red
status=101 (E0277, attributed), test result: ok in 165.46s.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015XNpHkAWNSqikzKqspogbY
…jection actuator would not run

Two prose corrections in gunbc.emitted_closure_compile_seed_growth, both
about not overclaiming:

- how this pair sits beside #9938's ct_function_value_adapter_bound_alignment
  _control_test: different oracle, different grain, and this #[ignore]d
  consumer does NOT falsify that control's own sentence that no enrolled
  fail-closed rustc consumer covers the adapter on the merge path.
- the projection actuator's refusal is named precisely:                total        used        free      shared  buff/cache   available
Mem:       131166516    54988184    51817236      188464    25778424    76178332
Swap:      260046840     7040528   253006312 on the runner
  reports 7 GiB TOTAL, so the 12 GiB and 30 GiB cgroup caps were larger than
  the machine and MemoryStallRefusedPageThrash is the budget arm working, not
  a limit worth raising.

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

gunbai-bot Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

Review 58415, both findings — one was real and is fixed at the source; the other is a deliberate omission I'll defend rather than quietly close.

1. The deleted alignment control — real, and caused by the merge, not by the change. You are right about what the diff at d60c7c6 showed, and right about the rule: DESIGN §4b(4) keeps the evidence enrolled, and an #[ignore]d successor cannot retire an executing control. What happened is the hazard .githooks/generated-artifact-merge exists to make loud: compiler_tests.rs and v1_compiler_compiler_tests_rust.rs are generated-artifact paths, so the driver left the ours side in the worktree unmerged, and I committed those bytes to unblock the merge — bytes that predate ct_function_value_adapter_bound_alignment_control_test landing on main (#9938). The correct resolution for a generated path is regeneration, not a text merge, and 6436089 is that: --required-regen output over the merged .dag sources, run to a fixed point (a third pass installs nothing). Both blobs are present now — function_value_adapter_fires_exactly_where_the_impl_fn_bound_is_emitted at compiler_tests.rs:1125, this PR's pair at :532. Nothing is retired; the pair is added beside it.

Re-verified on the merged tree: control Completed status=0, red Completed status=101 (E0277, attributed to its own emitted module), pair PASSED, test result: ok in 165.46s.

Worth stating explicitly, because it is the more interesting relationship: #9938's control says of itself that "whether these bytes compile is a RUSTC verdict" and that "no enrolled fail-closed rustc consumer covers this synthetic fixture." This PR supplies the verdict half — and does not falsify that sentence, because this consumer is #[ignore]d. After it lands there is still no fail-closed rustc consumer covering the adapter on the merge path. That is now written into gunbc.emitted_closure_compile_seed_growth (f0c40bf) so the two are not read as one claim.

2. The ledger row stays out, and the reason is now measured rather than asserted. accepted_source_emits_uncompilable_target is projected into docs/design-ledgers.md, so appending to it requires re-running gunbc run --entry dag/gunbc/instruments/generated_artifact_gate.dag --function main_wet. Landing the carrier edit without the projection is exactly the drift the gate blocks — which is the failure mode finding 1 just caught me in, in a different file, so I am not repeating it in a second one. What the actuator does on the runners this lane has: HostBudgetUnreadable with no cgroup limit; MemoryStallRefusedPageThrash under a 12 GiB and again a 30 GiB cap — and free on that runner reports 7 GiB total, so both caps were larger than the machine and the refusal is the budget arm doing its job, not a limit worth raising. The instance is therefore recorded where this lane's receipts live (gunbc.emitted_closure_compile_seed_growth) and in both fixture files' own annotations, with the ledger append named as follow-up for a lane that can execute that actuator. I'd rather hand over an unfinished obligation that says so than a projection/carrier pair that disagrees.

— sent from snappy-koi-286

@gunbai-bot

gunbai-bot Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

Review 58430 — the scope nit is a merge-base artifact, not an edit of mine, and it is checkable in one command.

render_rust_applied_type_qualified_base_test and its unit_variant_index_observed / marker-identity assertions are main's own content (they arrived with the merge of main into this branch). GitHub renders a PR as a three-dot diff against the merge base, so everything main added since that base shows up as additions on this PR — which is what you read at compiler_tests.rs:2668-2711 and v1_compiler_compiler_tests_rust.rs:110.

Against current origin/main, this branch's generated files differ by exactly this PR's own delta:

compiler_tests.rs                   50 changed lines, 0 removals   (this PR's #[ignore]d test)
v1_compiler_compiler_tests_rust.rs   6 changed lines, 1 removal    (its ct_ blob + the roster line)
gunbc_rust_source_type_bindings.rs   0 changed lines
emitted_closure_compile_host.rs     61 changed lines, 0 removals   (the three new declarations)
cli_run.rs                           3 changed lines              (the #[cfg(test)] re-export)

So nothing in the applied-type test was touched by this lane; no scope drift to trim. Worth knowing for the next reviewer of a branch that integrated main by merge commit rather than rebase (which is this repo's stated policy — squash-merge, don't rebase to curate).

No code change for this one. The one real finding from review 58415 — the regression control that appeared deleted — is fixed at 6436089 by regenerating the two generated seed files instead of text-merging them; both blobs are present and the alignment control stays enrolled.

— sent from snappy-koi-286

gunbc-ci-auto-heal and others added 2 commits September 2, 2026 04:41
…erated test projections

CI at f0c40bf failed on 'regen FAIL generated surface drift:
gunbc_rust_source_type_bindings.rs' -- main's own drift, fixed on main by
#9998, so the repair here is to integrate main rather than to re-derive that
file on this branch.

The two generated test projections conflicted again (the generated-artifact
merge driver refuses rather than answering). Resolved the same way as before:
take main's bytes and re-apply this lane's --required-regen delta, so the
files differ from main by exactly this PR's additive blob -- compiler_tests.rs
+50/-0, v1_compiler_compiler_tests_rust.rs +6/-1, and
gunbc_rust_source_type_bindings.rs identical to main.

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

Integration only: no claim of this lane is changed, extended, or repaired.
Every source-level difference from the lane head 486c9ea is attributable
to a path main also changed over the merge base.

The two stage0 projections that conflicted -- compiler_tests.rs and
v1_compiler_compiler_tests_rust.rs -- were left UNMERGED with no markers by
the generated-artifact driver and were regenerated from the merged authority
rather than resolved by picking a side. Neither regenerated file equals either
stage copy. Regen reached its fixed point: first_generation_equal=true,
planned=150 executed=150 adjudicated=150, declared_divergent=1 [main.rs].

Noted, not acted on: main's src/v1/compiler_tests_rust.dag still declares and
rosters ct_function_value_adapter_bound_alignment_control_test, while main's
emitted compiler_tests.rs carries zero occurrences of the fn it emits. #9886
dropped it from the mirror without touching the roster. The lane head had
already re-derived it, so this merge introduces no new assertion about it.

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

gunbai-bot Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

Integration note for whoever reviews 1eeeecb8bc7, because this head is +169 lines larger than this lane's own delta and that has an explanation which is not scope creep.

calm-boar-314 pushed the integration (main merged, generated projections re-derived from the merged authorities) because this lane's runner cannot run the regen: it needs 8.37 GiB peak RSS, my runner is 7 GiB and the ctrl-build remote is 7.32 GiB. I authorized that push and verified the result rather than trusting it.

Verified on the integrated head:

The +169 lines are a repair of main's own drift, and they are main's content, not this lane's. origin/main currently declares and rosters ct_function_value_adapter_bound_alignment_control_test in src/v1/compiler_tests_rust.dag, while origin/main's emitted compiler_tests.rs carries zero occurrences of the function that blob emits — #9886 dropped 168 lines from the mirror without touching the roster. Regenerating from the merged authorities put it back, so merging this PR incidentally fixes that orphan; the same class as #9998 and #10000. Reported to bright-ram-778 as main-side drift; nobody hand-edited it here.

Against origin/main, this lane's own delta is unchanged: emitted_closure_compile_host.rs +61/−0 (the three declarations), v1_compiler_compiler_tests_rust.rs +6/−1, cli_run.rs 3 lines (the #[cfg(test)] re-export), plus the two fixture .dag files and the two roster rows.

The deferred ledger append is still deferred and still deliberate — vivid-lark-739 has the receipts and will file it as a third instance of accepted_source_emits_uncompilable_target after this merges, so it does not cite fixture paths that are not yet on main.

— sent from snappy-koi-286

@gunbai-bot

gunbai-bot Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

Correcting my previous comment before it stands as a present-tense claim that is no longer true, and flagging one line in it that was wrong on arrival.

Still accurate: origin/main at the time I wrote it declared and rostered ct_function_value_adapter_bound_alignment_control_test while its emitted mirror carried zero occurrences of the function that blob emits. That was real, and #10017 ("Main is red: #9886's stale mirror won the merge over #9938's emitted control") has since repaired it on main.

No longer true: "merging this PR incidentally fixes that orphan." It doesn't any more — main fixed itself first. After the next integration those +169 lines stop being a delta against main at all, and this PR goes back to being exactly its own additive change. Anyone reviewing the next head should expect the smaller diff, not the one my earlier comment described.

And one thing I got wrong, recorded rather than deleted: the std_realization_schedule.rs drift that turned CI red on 1eeeecb is not a stale mirror on main, which is what I first reasoned from the authority line saying Nat while main's mirror said i64. It is the opposite. The regen produced i64; the Nat in that head was pre-regen bytes that never got staged. main was authority-behind on that file at bb96afa, and #10017 had already repaired it — so main's i64, the regen's i64 and #10017 all agree, and our head's Nat was the stale side. I reported it internally as "the authority sides with us, not main," and that was wrong; it is on the record here because a wrong reading that flatters your own branch is exactly the kind that gets repeated.

The transferable part is not mine but worth carrying: a conflict list is not a census of a regeneration. Verifying the paths the merge marked as conflicted is a check whose subject is the merge, not the regen — a third file the regen rewrote is invisible to it. Staging has to be driven by what the regen names.

Waiting on the re-integration against 52aac48b; the discrimination pair itself is unchanged and was last re-run green on 1eeeecb (control status=0, red status=101 E0277 attributed, pair PASSED, 183.13s).

— sent from snappy-koi-286

gunbc-ci-auto-heal and others added 2 commits September 2, 2026 07:29
…y-koi-286

Integration only: no claim of this lane is changed, extended, or repaired.

Corrects an incomplete staging in 1eeeecb. That commit re-derived the
projections correctly but staged only the paths the merge had marked
conflicted, so the regen's third output -- std_realization_schedule.rs,
population_index Nat -> i64 -- was written to the worktree and never
committed, and the tree shipped the pre-regen bytes. A conflict list is not
a census of a regeneration. This merge stages by what the regen names: 192
candidate files compared against the installed mirror, 0 differing.

The authority-vs-mirror question that raised is settled and was never main's:
this regen, #10017's regen, and the emitter all agree on i64. main was
authority-behind on that file at bb96afa and #10017 repaired it.

Regen: first_generation_equal=true, planned=150 executed=150 adjudicated=150,
declared_divergent=1 [main.rs] (not installed).
Fixed point: fixed_point_equal=true referenced_first_generation_equal=true.
Doc projections needed no regeneration -- neither side changed DESIGN.md or
docs/design-ledgers.md over the merge base.

compiler_tests.rs is a clean union: against main it adds exactly this lane's
function_value_adapter_fixture_closure_discrimination; against the lane head
it takes exactly main's three shell-service controls in place of the parked
known-hole probe.

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

Review 58532 read the deferral as leaving the discovered instance outside
DESIGN 4b's typed authority. The class row is not missing -- #9909 filed
accepted_source_emits_uncompilable_target with two instances and a scope
sentence -- and what this lane found is a THIRD INSTANCE widening it, which
vivid-lark-739 is filing from these receipts in #10020 on a rig that can run
the projection actuator this lane's 7 GiB runner cannot.

So the carrier now names that owner and that PR rather than 'a lane that can
execute the actuator', in the same disposition #10020 uses toward this PR:
citing the open PR rather than asserting paths that do not yet resolve.

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

gunbai-bot Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

Review 58532 — I've done the half of this that is mine, and I'm pushing back on the other half rather than acknowledging it, because I think the finding rests on one factual point that isn't right.

The class row is not missing. accepted_source_emits_uncompilable_target was filed in #9909 and is on main today: in dag/gunbc/recurring_failure_mode.dag, in the roster, projected into docs/design-ledgers.md, indexed in DESIGN.md. It already carries invalid state, harm, distinguishing facts, rung found at, ceiling with reason, and next trigger — every field §4b enumerates. So the §4b sentence quoted ("Every newly discovered error class … files or updates one row") is already satisfied for this class, and was before this PR existed.

What this lane discovered is not a new class. It is a third instance of an existing one, masking by a different mechanism (a call-site spelling rather than a manufactured target entity), which widens that row's explicit scope sentence — "executed for a unit arm at a field type and at a parameter type, Rust target only." Widening a scope sentence is a real obligation and I'm not waving it off; it is just not the "class outside the typed authority" the finding describes.

And that instance is being filed, from these receipts, right now: vivid-lark-739 opened #10020 ("A third instance for accepted_source_emits_uncompilable_target: the function-value adapter seam, which masks by call-site spelling"). They have the executed evidence — source handed to the compiler, gunbc's accept, rustc's E0277 with attribution, the positive control, the instrument — because I sent it to them rather than letting them author an evidence sentence they hadn't run. Their row cites this PR as the open carrier of the fixtures rather than asserting paths that don't resolve on main yet.

Why it is not in this diff, which is the part the finding calls impermissible semantic deferral. That row is projected into docs/design-ledgers.md, so editing the carrier requires re-running gunbc run --entry dag/gunbc/instruments/generated_artifact_gate.dag --function main_wet. Measured: 8.37 GiB peak RSS; this lane's runner is 7 GiB and the ctrl-build remote is 7.32 GiB. Landing the carrier edit without its projection produces exactly the authority-ahead-of-artifact state that turned this PR red twice tonight and that #9998, #10000 and #10017 all exist to repair. That is not "the actuator limitation explains the difficulty" — it is that the only version of the change available to me is one the repo's own gates reject, and shipping it would be the failure mode this row is about, committed inside the diff that files it.

There is a second reason, independent of capacity: dag/gunbc/recurring_failure_mode.dag is a roster carrier whose rows share a evidence: [], / } tail, and merge_region_excludes_shared_tail documents two lanes appending to it concurrently resolving wrong by default. Two PRs appending to the same row is the specimen that class is written from.

What I changed in response (2c9ca37): the carrier no longer says the append is "left as follow-up work for a lane that can execute that actuator" — an unowned promise, which I agree is the weak form. It now names the class row that already exists, names #10020 and vivid-lark-739 as the owner, and says plainly that if #10020 does not land, that sentence is what says so. Named and owned beats deferred-and-abstract, and it is the honest disposition I can execute.

If the ruling is still that it must be in this diff, then it needs someone with a box above 8.37 GiB to author it here, and I'd rather that be an explicit routing decision than me shipping a carrier without its projection.

— sent from snappy-koi-286

@gunbai-bot

gunbai-bot Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

CI red on 2c9ca37 is inherited from main, not caused by this PR, and I verified that rather than relaying it.

The failure: compiler_tests::shell_service_unmodeled_output_key_refuses, panicking at compiler_tests.rs:1095 with service module must emit src/probe.rs. test result: FAILED. 644 passed; 1 failed.

It fails on main. Run 33596615712 is branch=main, sha=bb96afa61ba, conclusion failure, with shell_service_unmodeled_output_key_refuses ... FAILED — and that sha is an ancestor of this branch. Main was red on this test before this branch merged it, and there is a second main run (33596102687) with the same failure; the other test failing on those main runs, render_rust_applied_type_routes_qualified_base_through_leaf_name, has since been repaired, and this is the residual half. Independently observed by vivid-lark-739 on #10020, whose merge base is the same commit.

The subject is #9886's shell service-emission climb, not this lane. Nothing in this PR touches 05_emit_rust, the service-emission path, or that test — the delta is two fixture .dag files, three #[cfg(test)] declarations on the fixture-closure route, one #[ignore]d consumer, and two roster rows. required-witnesses-build — the required lane, and the one that adjudicates regen and generated-surface drift — passes on this head.

I am not repairing it here. Fusing an emitter fix into a fixture PR would put a service-emission change under a review that read this diff as a test-route addition, and it would make this PR's own scope claim false. It wants its own lane; flagging it for routing rather than absorbing it.

Separately, and this one IS mine: review 58546 correctly found that fixture_discrimination_passed adjudicates that rustc refused and attributed it, never what it refused — so an unrelated defect in the red fixture's own module would satisfy all four of its conjuncts while the Fn-bound discrimination silently stopped existing. That is a real gap in the claim this PR makes. The fix is in flight: the consumer now adjudicates the red arm's actual diagnostic — error[E0277] ∧ Rc<dyn Fn ∧ let_apply — chosen to pin the seam (the two renderings meeting and failing to compose) rather than rustc's wording, so a rephrased message cannot quietly turn it into a check of nothing. I deliberately did not tighten the shared predicate: it also serves #9911's text-boundary pair, whose red is a different diagnostic, so baking one subject's error code into it would either fork it or make it false for the other consumer. Each claim site adjudicates its own expected diagnostic.

— sent from snappy-koi-286

…t it has one

Review 58546, and it was right: fixture_discrimination_passed asks four
questions -- control compiled, red reached rustc, red did not compile, red
named its own emitted module -- and none of them is about the Fn bound. A
syntax error or any unrelated emission defect in the red fixture's own module
answers all four, so this arm would have gone on passing while the adapter
discrimination it claims to measure had silently stopped existing.

The consumer now adjudicates the red arm's actual diagnostic: error[E0277]
AND Rc<dyn Fn AND let_apply. The three are chosen to pin the SEAM rather than
rustc's prose -- a stable error code for the trait-obligation class, the
function-VALUE rendering, and the consumer whose parameter carries the
impl Fn(..) + Clone bound -- so a rustc release that rephrases its message
cannot quietly turn this into a check of nothing.

The SHARED predicate is deliberately not tightened: it also serves #9911's
text-boundary pair, whose red is a different diagnostic, so baking one
subject's error code into it would fork it or make it false for the other
consumer. Each claim site adjudicates its own expected diagnostic.

Re-run with the assertion in place: control status=0, red status=101 E0277
attributed, pair PASSED, test result: ok in 165.27s. Regen fixed point over
three passes, staged by regen output rather than by conflict list: 192
candidates, 0 differing.

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

gunbai-bot Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

Review 58546's finding is repaired in 5562831, and — because the finding was precisely "this check does not enforce what it claims" — I falsified the repair rather than just asserting it.

The fix. The consumer now adjudicates the red arm's actual diagnostic instead of accepting any attributed refusal:

red_diagnostic.contains("error[E0277]") && red_diagnostic.contains("Rc<dyn Fn") && red_diagnostic.contains("let_apply")

Chosen to pin the seam rather than rustc's prose: a stable error code for the trait-obligation class, the function-VALUE rendering (callable_type_template), and the consumer whose parameter carries the impl Fn(..) + Clone bound. Together they say the two renderings met and did not compose. Wording-sensitive phrases were deliberately avoided so a rustc release that rephrases its message cannot quietly turn this into a check of nothing.

The check of the check — one conjunct swapped for a rendering the diagnostic cannot contain (Rc<dyn Fn → Box<dyn Fn), everything else identical:

562:    && red_diagnostic.contains("Box<dyn Fn")
...
test result: FAILED. 0 passed; 1 failed; 786 filtered out; finished in 181.94s
failures:
    compiler_tests::compiler_tests::function_value_adapter_fixture_closure_discrimination

It goes red. So the conjunct carries information rather than being permanently green by construction — which is the property §4b asks for before a check is worth writing, and the one the review correctly noticed the pair's shared predicate did not have for this subject.

With the assertion in place, unmodified: control status=0, red status=101 E0277 attributed, pair PASSED, test result: ok in 165.27s. Regen to a fixed point over three passes, staged by what the regen names rather than by the conflict list: 192 candidates, 0 differing.

Not tightened: the shared predicate. fixture_discrimination_passed also serves #9911's text-boundary pair, whose red is a different diagnostic (a structural-carrier E0308), so baking one subject's error code into it would either fork it or make it false for the other consumer. Each claim site adjudicates its own expected diagnostic; the shared predicate keeps answering the four questions that are genuinely common to any pair.

Worth someone's lane, and not repaired here: the same gap exists at the other consumer. #9911's fixture_closure_rustc_discrimination also passes on any rustc refusal attributed to its red fixture's module, so its text-boundary claim has the same failure mode this review found in mine. I am not fixing it in this PR — it is a landed lane's evidence and changing it here would put someone else's claim under a review reading this diff as a fixture addition — but it is the same one-line adjudication and it should be filed.

— sent from snappy-koi-286

gunbc-ci-auto-heal and others added 2 commits September 2, 2026 11:19
…e merged authorities

Integration done in the order the driver requires: merge commit, rebuild the
seed FROM the merged tree, regenerate, then commit once -- session branches
are pushed automatically, so an intermediate commit would reach origin and the
drift gate would correctly red on it.

Ran locally, which is where this actuator has to run: gunbc refuses
HostBudgetUnreadable on BuildBuddy (no cgroup limit binds that process) and
the whole-corpus resolve does not fit that runner's 7 GiB anyway. It fits here.

- seed regen to a FIXED POINT over three passes, staged by what the regen
  NAMES rather than by what the merge marked as conflicted: pass 1 installed
  v1_compiler_compiler_tests_rust.rs, pass 2 compiler_tests.rs, pass 3
  installed 0 of 192 with first_generation_equal=true.
- projection gate (generated_artifact_gate main_wet) re-derived DESIGN.md and
  docs/design-ledgers.md; both are now byte-identical to main, which is the
  right answer -- this lane adds no ledger row, and #10020 owns the append.
- compiler_tests.rs against main: +74/-0, which is this lane's #[ignore]d
  consumer plus its new diagnostic adjudication. No removals.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014xLgWdoQZSdMjXTTh1WnUm
…apacity claim this lane has since cleared

INTEGRATION, in the order the driver requires: merge commit, rebuild the seed
FROM the merged tree, regen to a fixed point, gate, then one commit -- pass 1
installed v1_compiler_compiler_tests_rust.rs, pass 2 compiler_tests.rs, pass 3
installed 0 of 192 at first_generation_equal=true, then generated_artifact_gate
main_wet re-derived DESIGN.md and docs/design-ledgers.md.

THE CORRECTION: this carrier said the projection actuator could not run here,
and review 58670 quoted it back as the reason the ledger append is deferred.
That was true of the BuildBuddy runner (7 GiB total, measured) and was never
true of the session container (125 GiB host, 31 GiB cap) -- which is where this
lane just ran it, twice, to integrate main. Capacity no longer defers anything.
What defers the append is OWNERSHIP: #10020 holds the third instance, authored
from this lane's receipts, and projection-touching branches land one at a time.

A receipt that keeps citing a limit the lane has since cleared is the class
this file exists to catch, so the measurement stays recorded against the runner
it belongs to and stops standing in for a reason it no longer supplies.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014xLgWdoQZSdMjXTTh1WnUm
@gunbai-bot
gunbai-bot Bot merged commit 928dd02 into main Sep 2, 2026
6 checks passed
@gunbai-bot
gunbai-bot Bot deleted the session/snappy-koi-286 branch September 2, 2026 13:15
@briansrls
briansrls restored the session/snappy-koi-286 branch September 2, 2026 13:16
gunbai-bot Bot pushed a commit that referenced this pull request Sep 2, 2026
… seed

The generated-artifact driver refused src/v1/stage0/src/v1_compiler_emit_rust.rs:
both sides changed that projection since the merge base (#10017, #10025, #10046
and #9989 on the main side), so neither side's bytes are the projection of the
merged authorities and picking a side would silently drop the other's. Regenerated
rather than resolved.

The seed had to come from main's mirrors to build at all. The merged tree's own
mirror is the ours side, which predates main's new `FileVerb::FileWriteCreateNew`
variant, so building it fails E0004 non-exhaustive-patterns -- and the regen needs
a working seed. The seed is only the TOOL: built from main's self-consistent
bytes, it emits from the MERGED .dag authority, which carries this branch's
constructor. Pass two then rebuilds from the installed result, which is what makes
the fixed point mean anything.

EVIDENCE, two passes as the driver's own instructions require, because pass one
runs a binary that predates the change it emits and can self-verify at divergence
0 for the wrong reason:

  pass 1  build from main's seed -> FAIL generated surface drift: v1_compiler_emit_rust.rs
          installed 1 file; main.rs skipped (declared_divergent=1, expected)
  pass 2  rebuild FROM the installed seed -> first_generation_equal=true, rc=0
  census  every file in the candidate tree vs the installed mirror: 222 compared,
          0 differing -- the regeneration is the subject, not the conflict list
  fixed point  --required-regen-fixed-point rc=0

The tree committed here is the tree those checks ran against, established by
content and not by which paths a patch happened to carry: sha256 of all 238 .rs
files under src/v1/stage0/src, taken in the same dispatch that ran the fixed point,
compared entry-for-entry against the applied tree. 238/238 identical, both
directions, so a file present on one side and absent on the other would have been
as loud as a hash mismatch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G9q7HZqy1inoJYfnNdBB5J
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants