diff --git a/docs/JOURNAL.md b/docs/JOURNAL.md index 4af6fb3..cadfa71 100644 --- a/docs/JOURNAL.md +++ b/docs/JOURNAL.md @@ -11970,3 +11970,83 @@ all three bench gates 0 regressed (`bench/check.py`, proved one of the env-seeding "gaps" from 22-tidy was load-bearing, not defensive — a future iter that audits all four flagged sites is worth its cost. + +## 2026-05-10 — Audit: mono-pass env-seeding gaps (lib.rs sites + env.imports) + +Targeted audit of the four `lib.rs` env-table reads that 22-tidy +flagged as gap-related, prompted by the env.globals fix (entry +above). Found a fifth gap that 22-tidy had not flagged. + +**The four flagged sites** all read from `env.types` or +`env.ctor_index`: + +- `lib.rs:1266` — `check_type_well_formed`, bare `Type::Con` lookup +- `lib.rs:1853-1856` — `Term::Ctor` bare-name path +- `lib.rs:1978` — `Term::Match` exhaustiveness, bare scrutinee type +- `lib.rs:2314-2316` — pattern-ctor resolution, local hit + type lookup + +`env.types` and `env.ctor_index` are seeded workspace-flat by +`build_workspace_env` since commit 5c5180f (milestone 22c). +**All four flagged sites are therefore defensive, already +covered.** They were load-bearing *for* the 22c fix; after the +fix, they are protected. + +**The unflagged fifth gap: `env.imports`.** Walking the env +struct (`lib.rs:2447-2509`) field by field against +`build_workspace_env` (`mono.rs:367`) revealed that +`env.imports` is read at four sites in `lib.rs` — +`1254` / `1697` / `1836` / `2320` — but `build_workspace_env` +never seeds it. The typecheck path at lib.rs:1147-1152 builds +`env.imports` per-module from `m.imports`; the mono pass had +no analogue. RED-first repro: + +- Two-module workspace: `test_mono_imports_classmod` + (class + instance) and `test_mono_imports_main` (imports + classmod, has a top-level fn body referencing + `test_mono_imports_classmod.foo` qualified). +- `ail check` passes, `ail build` fails with + `monomorphise_workspace: unknown module prefix + test_mono_imports_classmod in qualified reference`. + +**Commits:** + +- `2bf827f` — `test: red for mono-pass unknown module prefix on qualified cross-module reference in class workspace` + - Fixture: `examples/test_mono_imports_classmod.ail.json` + + `examples/test_mono_imports_main.ail.json` + - RED test: `crates/ail/tests/mono_xmod_qualified_ref.rs` +- `a9c685d` — `fix: mono pass seeds env.imports for qualified cross-module refs in class workspace` + - New `Env::module_imports: BTreeMap>` field + - `build_workspace_env` populates it from `Workspace::modules` + - `collect_mono_targets` and `collect_residuals_ordered` seed + `env.imports` per-module from it after setting `current_module` + - Mirrors the per-module pattern of `env.globals` (commit 13b36cc), + not the workspace-flat pattern of `env.types` (5c5180f) — import + aliases collide across modules. + +**Verification:** RED tests for both today's bugs (`mono_recursive_fn`, +`mono_xmod_qualified_ref`) green; full workspace tests green; bench +gates 0 regressed. + +**Architectural observation (not actioned this iter).** Three +consecutive commits (5c5180f, 13b36cc, a9c685d) have patched the +drift between `build_workspace_env` (mono.rs:367) and +`check_in_workspace` (lib.rs near 1095) at three different env +fields. The pattern is: every time `synth` learns to read a new +env table, both construction paths must be updated, but only one +gets it. The third occurrence is the signal — this is no longer +"audit one more place"; this is structural. Two paths to construct +the same env shape diverge under feature pressure. + +**Queued for the next iteration:** unify the two env-construction +paths, OR introduce a shared helper that both call. The shape that +fits the existing code is a `build_check_env(ws: &Workspace, +current_module: Option<&str>) -> Env` in `lib.rs` (or +`workspace.rs`), with `check_in_workspace` and the mono pass both +calling into it. That removes the drift entirely, and a future +"synth needs to read env.X" change touches one site. + +This is now the strongest item in the JOURNAL queue ahead of +post-22 Prelude / operator-routing / primitive-name-set +consolidation. It is not gating any user-facing feature, but it is +where the next "mysterious mono failure" will come from if not +addressed.