iter loop-recur.2: typecheck semantics — binder typing, recur checks, verify_loop_body

Second of three iterations of the standalone loop/recur milestone
(plan 5ac57fe). Replaces the iter-1 synth CheckError::Internal stub
for Term::Loop/Term::Recur with real binder typing + positional
recur arity/type checking via a new loop_stack: &mut Vec<Vec<Type>>
frame threaded as mut.2's mut_scope_stack, a new private
verify_loop_body tail-position pass (sibling of the byte-frozen
verify_tail_positions — 0 deletions there), and the four Recur*
diagnostics firing point-exactly on four negative fixtures. The
iter-1 loop_sum_to.ail fixture now also typechecks clean; an
infinite loop typechecks (no termination claim). NO codegen (the
iter-1 lower_term stub stays — iter 3); NO Diverge/guardedness
(spec boundary).

Three Boss design calls implemented verbatim and journalled:
RecurTypeMismatch is an Assign-style structural pre-check (not a
unify-propagate); loop_stack is positional Vec<Type> (binder names
via ordinary locals); diagnostic-code precedence is by pass
ordering (no explicit logic).

Two DONE_WITH_CONCERNS, both journalled: a plan-ordering defect
(Task 2's compile gate forced the check_fn threading the plan
deferred to Task 4 — resolved byte-identically, only resequenced)
and the recurring mut.2-class recon-undercount of cross-module
synth callers (resolved via the plan's compile-sweep oracle).

Boss systemic fix folded in: planner SKILL.md Step-5 gains item 7
(compile-gate vs. deferred-caller ordering) so the plan-ordering
defect class is scrubbed at plan time. cargo test --workspace
608 -> 616 / 0 red (Boss-reran independently).
This commit is contained in:
2026-05-17 23:33:43 +02:00
parent 5ac57fe8de
commit 1566ce0b29
16 changed files with 771 additions and 39 deletions
@@ -0,0 +1,13 @@
{
"iter_id": "loop-recur.2",
"date": "2026-05-17",
"mode": "standard",
"outcome": "DONE",
"tasks_total": 6,
"tasks_completed": 6,
"reloops_per_task": { "1": 0, "2": 0, "3": 0, "4": 0, "5": 0, "6": 0 },
"review_loops_spec": 0,
"review_loops_quality": 0,
"blocked_reason": null,
"notes": "Two DONE_WITH_CONCERNS on Task 2: (1) plan-ordering defect — check_fn loop_stack declaration+threading had to move from Task 4 into Task 2 because Task 2 Step 4's cargo-build 0-errors gate is unsatisfiable while check_fn is an unthreaded synth caller; resolved by executing the plan's Task-4 Step-3 block verbatim at the gate-forced point, only the verify_loop_body invocation stayed in Task 4. (2) recon under-counted cross-module synth callers (builtins.rs x2, lift.rs, mono.rs x2) — mut.2-class recon-undercount, resolved by mirroring the mut.2 fresh-stack pattern; the compile-driven sweep was the plan's designated exhaustive oracle. Zero review re-loops; all three Boss design calls implemented verbatim. cargo test --workspace 608 -> 616."
}