# Next session — plan **Branch state (2026-10-18):** `master` and `resolve-check` are both at `95ca4d6` (merged, fast-forward) and pushed to `origin`. Work on `master`. **Baseline:** suite **239/239**, fixpoint **OK (3,812,771 bytes)**, corpus **405/612, 0 crashes**. The corpus harness resolves transitive imports (method from 2026-10-18). **Policy:** follow **Modula-2**, not gm2 degradation — declaration before use (only a `POINTER`'s base may forward-reference). In `docs/gaps/`, the `decl-order` and `gm2-ext` classes are **not targets**; the 44-file "undeclared identifier" bucket is inflated by them. --- ## P0 — generics: two instantiations of one generic (real bug, do first) Instantiating one generic twice with arguments from different families fails on the second instantiation: ```mod GENERIC DEFINITION MODULE GStack (T : TYPE); TYPE NodeRec = RECORD val : T; next : Node END; ... ``` `GStack(CHAR)` alone works; `GStack(INTEGER)` alone works; together, the second fails (`incompatible assignment` at `n^.val := v`). `INTEGER` + `CARDINAL` appears to pass only because the stale binding still type-checks. **Likely culprit:** `SymTab.EnterTypeParamBound` returns early when the formal is already visible, so the first instantiation's binding sticks: ```mod IF Lookup(name) AND (SymKind(name) = KindType) THEN RETURN TRUE END; ``` *Steps:* five-file repro (generic def/mod + two instantiations + a program); make the substitution per-instantiation (fresh alias); add a regression test with two distinct scalar families; keep the fixpoint green. ## P1 — quick, bounded corpus wins - **`gap22` `__FILE__`/`__LINE__`** (`packed`, +1). - **`gap09` scalar actual → `ARRAY OF BYTE`** (`aochar`, `arrayofbyte`, `bytearray`, +~3). ## P2 — structural - **`gap12`** variant records: empty arms, `ELSE`, untagged inner `CASE` (5 files). - **`gap11`** bare procedure value as a statement. - **`gap10`** `VAR`-param type leniency (decide whether to adopt gm2's same-size rule — non-standard). - **`gap13` remainder**: de-reserve the *standard* builtins (`ORD`, `CHR`, `VAL`, …) — contextual-keyword parser refactor (`ORDL` is done). - **`gap18`** set-typed `CASE` labels. ## P3 — conformance remainder (architectural) Forward references to module-level **variables/procedures** from a procedure body still work (the two-phase parse defers bodies). Strict declaration-before-use would require order-aware body checking; high risk, touches self-hosting. The declaration part is already strict. ## P4 — latent correctness The **size-sensitive V3 miscompile** ("removing `ASTDUMP` breaks the fixpoint") is still unroot-caused. Dedicated bisection session; a real correctness landmine. ## P5 — housekeeping - Consolidate `docs/summary_*.md` (see `docs/INDEX.md`). - (Merge of `resolve-check` → `master`: **done**.) --- ## Gates for every step `compiler/build.sh` → `compiler/run_tests.sh` (must stay 100%) → `bootstrap/fixpoint.sh` (**byte-identical**) → `corpusx.sh` (record OK/CRASH + note) → update `docs/gaps/` + `STATUS`/`README` → commit with a `v3-*` tag. ## Resume ```sh cd .../m2compiler-V3 git checkout master cd compiler && ./build.sh && ./run_tests.sh # 239/239 cd .. && TMP="$PWD/.scratch/fixpoint" ./bootstrap/fixpoint.sh M2FLAGS="" ./.scratch/corpusx.sh # 405 OK, 0 crash ``` **Recommendation:** P0 first (a real defect), then two P1 wins, and reserve a separate session for P4.