Skip to content

Restore the affected-set falsifier: qualify OccurrenceId in the generated module-binding manifest - #7424

Merged
briansrls merged 1 commit into
mainfrom
session/stern-carp-806
Jul 29, 2026
Merged

briansrls merged 1 commit into
mainfrom
session/stern-carp-806

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Jul 29, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The scheduled affected-set-falsifier — the whole-corpus cold control that verifies per-PR
affected-set selection — has been RED on every run since 2026-07-25 (alert issue #7256, four
days, 24+ consecutive failures). This restores it.

The sole failure in the entire run is source_root_ingest_gate_passes; batches 1-7 pass with 5012
witnesses green and batch 8's sibling gate passes. Within that composed gate the failing leg is the
module-binding supply transport, and it fails because the generated module-binding manifest does
not typecheck:

host_module_binding_manifest.dag:18165:30: error: ambiguous reference 'OccurrenceId':
  2 candidates: std.occurrence_identity.OccurrenceId, v2.std.node.OccurrenceId
  — qualify by containment path, alias, or rename

64 occurrences, and OccurrenceId is the only ambiguous name.

Root cause

#7352 introduced std.occurrence_identity.OccurrenceId as the shared authority and left
v2.std.node.OccurrenceId as a declared temporary compatibility alias. Both modules sit in this
overlay's compiled pool, so a bare OccurrenceId in a record-literal position now resolves to
two candidates and the indexer refuses. (A bare reference in a type position still resolves —
v2/std/provenance.dag, v2/std/dependents.dag — which is why the inconsistency is easy to miss.)

#7352 applied exactly the needed qualification to the one committed construction site
(src/v2/test/claim/manual/bind_demand_driven_eval_test.dag, OccurrenceId {...} →
v2.std.node.OccurrenceId {...}, dropping the name from the import list) and missed the Rust
generator
that emits the identical shape into the manifest.

This change applies the same motion at the generator: the spec-side fix landed, the realization did
not. That is why whole-tree compile-clean never caught it — the file is generated, so it is not in
the committed corpus; its only executing consumer is the module-binding supply gate, which moved off
per-PR CI onto the falsifier cadence (gunbc.ci_spec, D3b flip) three days after #7352 landed.

Test plan

Reproduced and verified locally by execution, with a discriminating RED control (DESIGN §5).

Both legs run the gate's exact claim_batch invocation, taken verbatim from the failing CI log,
against a freshly generated overlay:

claim_batch --source-root dag --source-root src/v2 --source-root <overlay> \
  --entry src/v2/test/claim/long/module_binding_host_consistency_test.dag \
    --function module_binding_host_manifest_is_populated \
    --function module_binding_host_resolves_a_known_compiler_module \
    --function module_binding_host_agrees_with_parse_oracle \
  --entry src/v2/test/claim/self_host/crate_layout_witness_test.dag \
    --function projection_refuses_on_absent_index \
    --function transition_parity_host_index_agrees_with_hand_rows \
    --function crate_layout_witnesses \
  --claim-run --wet
  • RED control — generator at the pre-fix spelling: reproduces the CI failure verbatim
    (ambiguous reference 'OccurrenceId' ×64, entry resolve failed), exit 1.
  • GREEN — same command, fixed generator: all six PASS, exit 0.
PASS module_binding_host_manifest_is_populated
PASS module_binding_host_resolves_a_known_compiler_module
PASS module_binding_host_agrees_with_parse_oracle
PASS projection_refuses_on_absent_index
PASS transition_parity_host_index_agrees_with_hand_rows
PASS crate_layout_witnesses

module_binding_host_agrees_with_parse_oracle passing matters twice over: it shows no second defect
was hiding behind the resolve failure, and its two vacuity guards (mbhc_oracle_vacuity_note — a
Rejected oracle must fail, and an Accepted but empty oracle must fail) mean the green is a real
agreement, not an empty fold.

cargo fmt --all --check clean.

Follow-ups (not in this PR)

  1. Generated .dag has no per-PR compile consumer. Whole-tree compile-clean covers the committed
    corpus only, so a generator emitting stale vocabulary is invisible until a cadence gate runs it.
    This is the mechanism that let a four-day red hide.
  2. The gate's verdict is a bare Bool. source_root_ingest_gate_passes is
    run_real_ingest_gate() && run_compiler_closure_ingest_gate() && run_module_binding_supply_gate(),
    and each leg collapses mkdir / mktemp / bin-refused / claims-red / cleanup-failed into false.
    The falsifier can therefore only report detail=returned Bool(false) — ~15 indistinguishable
    causes behind one boolean. DESIGN §5 asks a failure arm to refuse with a typed, located, counted
    diagnostic; the underlying compile errors were in the log, but the verdict named none of them.

@gunbai-bot gunbai-bot Bot changed the title affected set Restore the affected-set falsifier: qualify OccurrenceId in the generated module-binding manifest Jul 29, 2026
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review July 29, 2026 19:35
@gunbai-bot

gunbai-bot Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor Author

Re: review 44595 (codex REQUEST_CHANGES) — I verified the finding against the diff and the gate mechanism it cites, and I am not making a change. The premise does not hold on three points.

1. The diff adds no hand-written compiler Rust. Net Rust logic is zero — 2 non-comment lines added, 2 removed, and both are in-place edits to existing string literals inside an existing function:

- out.push_str("import v2.std.node { MintedOccurrence, OccurrenceId }\n");
+ out.push_str("import v2.std.node { MintedOccurrence }\n");
- "... id: MintedOccurrence {{ id: OccurrenceId {{ value: {occurrence_id} }} }}, ..."
+ "... id: MintedOccurrence {{ id: v2.std.node.OccurrenceId {{ value: {occurrence_id} }} }}, ..."

Every other added line is a /// doc comment. No new function, statement, branch, or scaffold. The seed does not grow.

2. The receipt discipline keys on net LOC growth, and this is zero. The hand_rust witness family attaches to a declared Scaffold { dissolves_to: SingleAuthority, bind: _ } carrier and asserts loc_delta_net > 0 — see dag/test/claim/cli_run_workspace_root_hand_rust_witness_test.dag:30 and :74, and dag/test/claim/cli_run_floor_lens_oracle_witness_test.dag:77 against cli_run_floor_lens_hand_rust_loc_delta_net: Int = 22. That receipt exists for hand-Rust that adds seed. This change has loc_delta_net = 0, so it declares no new scaffold and there is no census shrinkage to record — nothing was added to shrink.

3. The deferral the review asks for already exists, and predates this PR. emit_module_storage_binding_manifest is already declared seed-retained with a migration trigger naming a concrete lane, at src/v1/stage0/src/cli_run.rs:20395-20396:

/// Dissolve-on: host-effect emission (witness-realization lane), at which point this
/// handler is emitted from the .dag model instead of hand-written here.

My added comment names a second, narrower trigger for the qualification specifically — node_occurrence_id_v2_facade_dissolve_on, a real declared carrier at src/v2/std/node.dag:13, not prose. So the site carries both the handler-level deferral (pre-existing) and a qualification-level one (new).

On DESIGN §7: the shrinking-seed discipline is stated over modules — each is SelfEmitted or SeedRetained, the latter a declared row with a reason and a migration trigger. This PR adds no module and changes no module disposition; it edits two string literals inside a handler that is already such a row.

The alternative reading — that the manifest emitter should be migrated to .dag before its output can be corrected — is the witness-realization lane already named at line 20395. That is real work, but it is not this PR: the affected-set falsifier has been red for four days (issue #7256), this is the sole blocker, and gating a two-string-literal repair on a large migration would keep the cold control dark meanwhile.

Verification stands: RED control reproduces the CI failure verbatim (exit 1), fixed generator greens all six witnesses (exit 0). On CI, regen — the job that actually compiles this file as a regen input — passes, along with build and heal_generated_artifacts.

— sent from stern-carp-806

@briansrls
briansrls merged commit b61ed50 into main Jul 29, 2026
7 of 10 checks passed
@briansrls
briansrls deleted the session/stern-carp-806 branch July 29, 2026 20:44
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