a163c8c34a
Two minimal edits in ailang-check that bring the resolver's acceptance set into line with what prep.1's workspace pre-pass (`prepare_workspace_for_check`) actually produces. The pre-pass itself is unchanged — its qualification rules are correct per spec § "Realisation mechanism — workspace pre-pass". RED tests landed in 4d39fdc; both turn GREEN, both fieldtest fixtures that surfaced the bugs now `ail check` clean. F1 — same-module type-scoped call (kem_2b_min_repro.ail). The dot-qualified `Term::Var` arm in `synth_term` (`crates/ailang-check/src/lib.rs` ~line 3425) was unconditionally rewriting the resolved fn signature via `qualify_local_types`, so a call like `(app Counter.value c)` from inside Counter's home module produced a return type `<this>.Counter` — but the matching `Term::Ctor` arm (~line 3644) and the pre-pass itself both leave own-module type-names bare. The two halves of the resolver disagreed. Fix: branch on `target_module == env.current_module` — when true, skip the qualification (the raw type is already in the form the rest of the resolver speaks); when false, qualify as before. `owner_types` lookup moved inside the else-branch since it's only consulted when qualification runs. A short comment names the pre-pass and the sibling Term::Ctor arm so a future reader sees the three-way symmetry. F3 — kernel-tier qualifier acceptance (kem_3_stub_consumer.ail). The env-builder paths `build_check_env` (~line 1653) and `check_in_workspace` (~line 1807) force-injected only `"prelude"` into `env.imports` / `env.module_imports`. The loader meanwhile derives the implicit-imports list from `modules.values().filter(|m| m.kernel)` (since prep.3) — so `kernel_stub` flows into runtime resolution but not into the checker's qualifier-validity check (~line 1968). Bare `StubT` got qualified by the pre-pass to `kernel_stub.StubT`, then bounced off the validity check as "unknown module prefix". Fix at both sites: keep the unconditional `"prelude"` literal injection AND additively insert every workspace module with `kernel: true` into the per-module import map (skip self-injection). Idempotent for production (where prelude also carries `kernel: true`) and preserves the `bare_name_resolves_through_implicit_import_to_free_fn` unit-test contract — that test deliberately constructs a prelude module with `kernel: false` to pin the legacy "prelude is always implicit" guarantee per se, independent of the kernel flag. Mirrors the loader's kernel-flag filter, making the env-builder and the loader speak the same set. Sibling pin `crates/ailang-check/tests/env_construction_pin.rs` (the frozen-reproduction copy of `build_check_env`'s `module_imports` loop) updated in lockstep so it remains a meaningful drift detector after the env-builder change. The pin is intentionally designed to track legitimate behavioural changes. Verification: - tests::type_scoped_call_in_same_module_resolves GREEN - tests::kernel_tier_module_qualifier_resolves_… GREEN - examples/fieldtest/kem_2b_min_repro.ail ail check ok - examples/fieldtest/kem_3_stub_consumer.ail ail check ok - cargo test --workspace 666 / 0 (664 prior baseline + 2 RED→GREEN this iter) Implementer notes: one re-loop on the F3 site after the first edit replaced the legacy "prelude" literal injection wholesale with the kernel-flag filter — that broke the unit-test contract above. Restored the literal AND added the filter on top per the "don't adapt tests to bugs" memory. No spec-review or quality-review loops. prep.1's pre-pass design (spec § "Realisation mechanism") was correct as written — the symmetry between owner-side `qualify_local_types` and consumer-side `prepare_workspace_for_check` holds. What was missing was uniform resolver-side acceptance of the qualifiers the pre-pass produces. With these two edits, the following equivalences hold throughout the checker: bare T ≡ <this-module>.T (F1, same-module rule) bare T ≡ <kernel-module>.T (F3, kernel-tier rule) via the loader-driven implicit-imports list that now drives both the checker's import map and the type-validity check.