Skip to content

Every v1-compiler binary target compiles — a standing derived from the manifest, after the floor - #9196

Merged
briansrls merged 3 commits into
mainfrom
fix/v1-bin-stale-typeenv
Aug 26, 2026
Merged

briansrls merged 3 commits into
mainfrom
fix/v1-bin-stale-typeenv

Conversation

@gunbai-bot

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

Copy link
Copy Markdown
Contributor

Adds one standing to witnesses.yml: every binary target v1-compiler declares must compile.

The gap

witnesses.yml builds two targets:

cargo build --release -p v1-compiler --bin claim_executor --bin gunbc

The manifest declares 16 [[bin]] targets (gunbc, plus 15 under src/bin — the manifest is
the denominator, not the directory listing), so 14 are absent from the build selection. With
the Rust suite removed from CI 2026-07-11, clippy 2026-07-08, and the compile-clean gate deleted in
the floor cut, no required phase compiled any of those 14.

The mechanism deserves its own words: a field was added to an authority and its hand-maintained
callers were not updated, because nothing compiles them.
A .dag caller would have refused loudly
at resolve. A Rust mirror has no such wall once nothing invokes rustc on it — silent staleness,
not a refused closure.

Historical positive specimen (recorded here because #9205 repairs it and the live evidence then
disappears): at main f84c91b774a, #8952 had added authored_import_names to TypeEnv without
updating infer_semantics_witness, whose six synthetic TypeEnv constructions failed E0063.
Measured, same command both arms: origin/main → exit 101, 6 × E0063; with the field set →
exit 0. The repair is #9205's; this PR is the standing that stops the next one.

Two populations, one of which had no answer

RuntimeArtifactPopulation the executables this job runs — claim_executor, gunbc
BinaryCompilePopulation every bin target the manifest declares

witness_floor_required_bins is the first and is left untouched — the rule above it ("naming a
binary that no step runs buys nothing and costs a compile") is about artifact production and stays
intact. Nothing answered the second.

Derived from the manifest — and no new argv word

The step calls repo_self_build_command(bins: []). gunbc.repo_self_build is the single authority
for how this repository builds itself, and its note instructs reviewers to refuse a new argv word
the modeled surface already owns — --bins is one. It is also unnecessary:
repo_self_build_empty_bins_note already records that an empty bin set renders the no-selector
package build, which is cargo's own meaning for "build every target in the package." So the
population is derived from Cargo, a new [[bin]] joins the standing with no edit anywhere, and no
second cargo authority is minted.

Build, not check — decided by measurement

From a cold CARGO_TARGET_DIR with the two-bin build already paid (CI's starting state):

marginal
cargo check --release --bins 52s
cargo build --release (every target) 12s — and it links

Cheaper and strictly stronger, so there was no tradeoff to split. Verified 5/5 named binaries
present on disk afterwards — including the previously unbuilt v1_src_dag_parse, parse_witness
and infer_semantics_witness — because a no-op and a successful link produce the same exit code
and the same silence.

Placement: last, and that is the load-bearing part

Ahead of the fold this step would be a second preparation mask — an auxiliary target failing to
compile would stop the job before the floor ran, and planned/executed/terminal would vanish behind
an unrelated compile error. It runs after the fold and after the three roster uploads, guarded
only by !cancelled() so a red floor still reaches it. Either standing may red the workflow;
neither may stop the other publishing its evidence.

Discriminating receipt — run 32873753939

Not asserted; executed. One field removed from one TypeEnv initializer in a bin outside the
runtime pair, then a real workflow_dispatch run:

step outcome
Build the witness fold success — the two-bin build is unaffected
Required CI: parse, regen, witness floor success
Upload the floor's admission roster / expected-red join / long-home agreement success ×3
Every v1-compiler binary target compiles failure

The floor published a complete ledger while the new step failed:

phases_run=4  (parse, regen, v2-emission, floor)
planned=11012 executed=11012 terminal=11012 passed=10860 failed=0

and the failure names the binary:

error[E0063]: missing field `authored_import_names` in initializer of `TypeEnv`
  --> src/v1/stage0/src/bin/infer_semantics_witness.rs:1041:17
error: could not compile `v1-compiler` (bin "infer_semantics_witness") due to 1 previous error

Exactly one error, not six — the other five sites were intact, so the planted mutation is the
sole cause rather than a coincidental break. That is the guard adding binary-target coverage
without becoming a preparation mask, which is the specific risk of putting a compile step in
this workflow at all.

What this establishes, and what it does not

Establishes: every declared v1-compiler binary target compiles and links under the release
profile. Does not: that any of them runs correctly, and nothing about test targets — this
command does not build them.

Not claimed: that the other 14 are permanently safe. They compile at this commit; the standing
is what makes that true tomorrow.

The guard's own before/after, across one external event

The strongest evidence a guard can offer is a state transition it did not author. This one has it,
and the boundary is an exact commit rather than a time window.

base run step "Every v1-compiler binary target compiles"
f84c91b77 — before fa31aaee56c 32878478753 FAILURE, naming src/v1/stage0/src/bin/infer_semantics_witness.rs at 317, 1040, … with E0063: missing field authored_import_names
fa31aaee56c — #9205's merge commit 32890178823 success

fa31aaee56c is #9205, which added the missing field at all six TypeEnv construction sites in
that bin. Zero commits on this branch changed the guard between those two runs — the only
variable that moved is the base, and it is named.

Verified rather than inferred: git merge-base --is-ancestor fa31aaee56c f84c91b77 returns
non-zero, so the earlier run provably could not see #9205. Both earlier runs on this PR predate it
by 1h33m and 17m respectively — that red was inherited, not a finding.

The step is confirmed to have executed in the green run, not skipped:

success   Required CI: parse, regen, witness floor
success   Every v1-compiler binary target compiles

Two independent demonstrations, not one. Beside the transition above, run
32873753939 planted a mutation —
one field removed from one of the six sites, in a bin outside the two-bin pair — and the arm
reported exactly one error rather than six. Discriminating, not merely correlated.

A guard authored after its subject was fixed can never show either of these.

@gunbai-bot gunbai-bot Bot changed the title Adopt two orphaned PRs whose sessions are gone: #8938 (inference endpoint binding, mergeable, never ran checks) and #9051 (reach fold endpoint projection, CONFLICTING, operator-paused) Main is red: set authored_import_names at the six synthetic TypeEnv sites in infer_semantics_witness Aug 25, 2026
witnesses.yml builds 2 of the 16 bin targets v1-compiler declares, so 14 are absent from the
build selection and nothing required compiles them. Combined with the Rust suite removed from CI
2026-07-11, clippy 2026-07-08, and the compile-clean gate deleted in the floor cut, a bin can go
stale silently -- and one had: #8952 added authored_import_names to TypeEnv without updating
infer_semantics_witness, leaving main red at 'cargo check -p v1-compiler'. That specimen is being
repaired separately in #9205; this is the standing that stops the next one.

Two populations were answered by one roster:
  RuntimeArtifactPopulation -- the executables this job RUNS (claim_executor, gunbc)
  BinaryCompilePopulation   -- every bin target the manifest DECLARES
witness_floor_required_bins is correct as the first and is left alone.

Derived, not a second roster: the step calls repo_self_build_command(bins: []), whose no-selector
form gunbc.repo_self_build already documents as cargo's meaning for 'build every target'. A new
[[bin]] joins the standing with no edit anywhere, and no new argv word is minted.

Build rather than check, decided by measurement: from a cold target dir with the two-bin build
already paid, building every target cost 12s against 52s for 'cargo check --release --bins', and
it additionally links.

Placed LAST, after the fold and the roster uploads, guarded by !cancelled(): ahead of the fold it
would be a preparation mask, and an auxiliary compile error would take the floor's ledger with it.
@gunbai-bot
gunbai-bot Bot force-pushed the fix/v1-bin-stale-typeenv branch from 4db9261 to c896d83 Compare August 25, 2026 17:32
@gunbai-bot gunbai-bot Bot changed the title Main is red: set authored_import_names at the six synthetic TypeEnv sites in infer_semantics_witness Every v1-compiler binary target compiles — a standing derived from the manifest, after the floor Aug 25, 2026
@gunbai-bot

gunbai-bot Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor Author

The failing check is this PR working, not this PR broken — please do not "fix" it

Automated notice says CI is failing at c896d83 and blocks merge. That failure is expected and
correct
, and the fix is not in this PR.

This PR adds a step that compiles every binary target v1-compiler declares. main currently does
not: infer_semantics_witness has six TypeEnv initializers missing authored_import_names since
#8952, and until now no required phase compiled that binary, which is exactly the gap this
standing closes. So the new step is reporting main's own pre-existing defect — on its very first
run, against a real specimen nobody planted.

The repair for that specimen is #9205 (operator-authored, one file). This PR deliberately does
not contain it: an earlier revision did, and it was removed so the two cannot collide. Re-adding
it here to turn this check green would both recreate that collision and destroy the thing this PR
demonstrates.

So this stays red until #9205 lands, and then goes green with no change to this branch. Holding
rather than racing.

That the guard does not simply fail-always is established separately, by execution: on run
32873753939 a planted single-field mutation produced exactly one E0063 naming
bin "infer_semantics_witness", while the two-bin build still succeeded and the floor still
published a complete ledger (phases_run=4, planned=11012 executed=11012 passed=10860 failed=0).
The full receipt is in the PR body.

— sent from loyal-dove-837

gunbc-ci-auto-heal added 2 commits August 25, 2026 19:32
gunbai-bot Bot pushed a commit that referenced this pull request Aug 26, 2026
…rror

Main tip 151e771. ONE conflicting path: the generated mirror
src/v1/stage0/src/v1_compiler_infer.rs. src/v1/04_infer.dag (+104 from main) and
cli_run.rs (-373 from main) both AUTO-MERGED, verified by a tree-wide grep for
conflict markers returning only the mirror.

THE MERGE DRIVER DID NOT FIRE, and that is the second time on this PR. It is
enrolled by BASENAME while the population is defined by a HEADER, so it protects
2 of 136 stage0 mirrors and v1_compiler_infer.rs is outside it. On #9196 the same
driver DID refuse a generated .yml and printed the regeneration recipe; here git
left ordinary conflict markers and would have accepted a hand-resolution.

REGENERATED, NOT HAND-RESOLVED -- and the binary vintage mattered, measurably:

  binary built from f57bc0e (pre-merge):  drift = extdeps_uri.rs,
                                           v1_compiler_compile.rs,
                                           v1_compiler_infer.rs, v1_rt.rs   (4)
  binary built from the MERGED tree:       drift = v1_compiler_infer.rs      (1)

Same tree, two binaries. Three of the four were EMITTER VINTAGE, not tree drift:
this diff touches inference and has nothing to do with extdeps_uri.rs or v1_rt.rs.
Installing the first candidate would have written an old emitter's bytes over
mirrors main had already advanced -- silently, and it would have read as a clean
regen. A drift list wider than the change is a claim about the instrument.

So the recipe's order is wrong when the binary predates the merge: REBUILD FIRST,
then regenerate once. The binary was dated before use -- it now accepts
--required-lane and routes phases by lane, which the pre-merge one rejected.

RECEIPTS, from a rebuild off the installed seed:

  required-regen: first_generation_equal=true planned=135 executed=135
                  declared_divergent=1 [main.rs]
  installed sha256 12110f0a3dc440ef... recorded BEFORE the confirming run and
  re-emitted identically by the rebuilt binary; diff -rq shows no other file
  differing.
  v1_src_dag_parse: 3998 file(s) parse-clean.

The three #9192 functions stay 1/1 dag-to-rs: select_formal_for_call_argument,
call_argument_formal_at_position, call_formal_claimed_by_a_label.
@briansrls
briansrls merged commit 902e757 into main Aug 26, 2026
3 checks passed
@briansrls
briansrls deleted the fix/v1-bin-stale-typeenv branch August 26, 2026 01:46
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