66%

Intelligence Reconnaissance

Queries run 2026-04-17 (preserved) + 2026-04-20 (editor re-scope):

  • scripts/intel-query.sh --human file-symbols "ori_diagnostic" --repo ori — inventory ori_diagnostic crate symbols (error builder, suggestion API) before auditing E2005 wording.
  • scripts/intel-query.sh --human callers "AmbiguousType" --repo ori — find all E2005 construction sites to confirm the message string is set in exactly one place.
  • scripts/intel-query.sh --human similar "empty list type annotation suggestion" --repo rust,elm --limit 5 — prior art for actionable empty-collection type-inference suggestions (Rust E0282 “type annotations needed”, Elm explicit annotation prompts).
  • scripts/intel-query.sh --human symbol-plans "AmbiguousType" --repo ori — cross-reference which plans/sections/bugs reference E2005; used to confirm §05 owns the canonical corpus and §06 is the audit-only consumer.
  • scripts/intel-query.sh --human file-symbols "default_unbound_vars_from_empty_literals" --repo ori — confirm the [Never]-defaulting pre-pass surface before deciding which legacy files to annotate vs leave to defaulting.

Results summary (≤500 chars) [ori]: AmbiguousType (E2005) constructed in ori_types/src/type_error/check_error/; message string lives in the message.rs mapping. default_unbound_vars_from_empty_literals lives in infer/mod.rs with call sites in check/bodies/{functions,impls,tests}.rs + infer/body_finalize/mod.rs — the defaulting corpus at tests/spec/types/empty_literals/ (21 files) MUST NOT be touched by §06 mechanical annotation. [rust]: E0282 “type annotations needed, cannot infer type” uses the exact imperative pattern. [elm]: Type.Error suggestions show concrete annotated form.


Section 06: Diagnostics + Spec-Test Audit

Status: In Progress — §06.1/§06.3 complete; §06.2/§06.2B/§06.2C in-progress (close-out tail items gated on §09/§10/§11 completion and the §06.4.4 INVERTED-TDD reconciliation); §06.4 fully gated on §09/§10/§11 completion.

Goal (post-2026-04-23 supersession): Close §03.N’s E2005 ledger via a two-phase resolution: (a) mechanical annotation sweeps in §06.2 (empty-literal class) and §06.2B (lambda-parameter class) for the 35-file initial ledger — complete; (b) compiler-side fixes in §09/§10/§11 for the residual 28-file §06.2C sub-ledger, which §06.2C originally scoped as a “polymorphic-constructor” annotation sweep but which 2026-04-23 root-cause investigation (CLAUDE.md §The One Rule + §INVERTED-TDD) reclassified as seven distinct typeck gap classes. §06 retains the E2005 diagnostic wording deliverable (§06.1 complete), the stdlib audit (§06.3 complete), and the §06.4 regression-verification gate that runs AFTER §09/§10/§11 complete.

This is NOT the “clean-up after the fix” section anymore — it is the CROSS-REFERENCE

  • REGRESSION-GATE section. It does NOT add new negative pins or #compile_fail tests (§05 owns those) and does NOT add new defaulting tests (§03.BUG-FIXES owns the tests/spec/types/empty_literals/ corpus). Any residual .ori test modifications in the §06.4 arc are forbidden per §09/§10/§11 compiler-fix-only success criteria.

Depends on: §01 (Value Restriction), §02 (Validator Module), §03 (Bodies-Pass Integration + BUG-FIXES defaulting), §04 (Codegen Assertions), §05 (Test Matrix — canonical negative-pin corpus and semantic pins land first so §06 never adds redundant #compile_fail coverage).

Sequencing rule: §06 MUST NOT start until §03’s validator is live on all four body-group passes AND §05’s canonical empty-literal corpus exists at tests/spec/types/collections/empty_list/ AND §04’s codegen assertions have landed their primary seam. §03 already emits E2005 across the 35-file ledger; starting §06 before §05 lands risks §06 accidentally owning #compile_fail coverage that belongs to the canonical corpus. Starting §06 before §04 lands means the “no unresolved type variable at codegen” success criterion from 00-overview.md cannot be verified alongside the annotation sweep.

Two failure classes, one section: Per §03.N Known Failing Tests table, the ledger has TWO distinct E2005 classes that §06 resolves with DIFFERENT annotation shapes:

ClassExampleAnnotation form§06 subsection
Empty-literal, no constraining uselet x = [], [].iter(), [].len(), {}.keys(), [] + [1, 2, 3]Add let x: [T] = [] / {str: int} = {} binding annotation§06.2
Lambda-parameter inference in method chainslist.map(x -> x.method()), list.filter(x -> ...) — receiver’s element type does not propagate bidirectionally into the closure bodyAnnotate the closure parameter AND the return type (spec grammar.ebnf §lambda typed_lambda rule requires both when any param is annotated): .map((d: Duration) -> int = d.minutes())§06.2B

Skipping §06.2B (only sweeping \[\s*\]) leaves ~26 lambda-parameter files in the ledger — the comprehensive rg '\[\s*\]' regex does NOT match lambda parameters. The §03.N table names both classes; §06 MUST resolve both.


06.1 E2005 Diagnostic Wording

Target message: "cannot infer the type of this empty list; add a type annotation like let x: [int] = []"

Per impl-hygiene.md §Error Handling — Diagnostics:

  • All errors have spans (the empty-list expression span)
  • Imperative suggestions (“add a type annotation”)
  • No “unexpected X” without “expected Y because Z”

Known limitation from §03.N close-out: validate_body_types currently emits E2005 with “expression” as the context label regardless of where the unresolved Tag::Var appears (parameter, return type, body expression). §06.1 refines the message to distinguish empty-list sites from lambda-parameter sites.

  • Add a dispatch in the E2005 message builder (see ori_types/src/type_error/check_error/message.rs) that selects message text based on the expression’s ExprKind at the error site:
    • ExprKind::List([]) / ExprKind::ListWithSpread([])"cannot infer the type of this empty list; add a type annotation like \let x: [int] = []`“(per00-overview.md:106Design Principle 4: specialized E2005 wording targets lists only;Map/MapWithSpread/Set` empty-literal sites stay on the generic fallback to preserve the overview’s list-only scope).
    • ExprKind::Lambda { params, .. } where a parameter has unresolved Tag::Var"cannot infer the type of this closure parameter; add a full typed-lambda annotation like \(x: int) -> ReturnT = body`“(per specgrammar.ebnf:550-553typed_lambda rule — param type + return type +=body all required together; shorthand forms like(x: int) -> body` are parse errors).
    • All other positions → preserve the current generic wording.
  • Span discipline: the primary span SHALL point to the [] or {} literal (empty-literal class) or to the parameter token (lambda-parameter class), NOT to the enclosing let binding or method call.
  • Matrix test (TDD): extend compiler/ori_types/src/check/validators/tests.rs with two new cells exercising the two message forms — test_e2005_message_for_empty_list and test_e2005_message_for_lambda_param — asserting the exact message string AND the span byte range.
  • Negative pin: add test_e2005_message_falls_back_to_generic_for_signature_var so a fresh Tag::Var in a FunctionSig.param_types[0] position (unannotated parameter, not a lambda inside a body) still gets the original generic wording — regression guard against over-eager lambda-message dispatch.

Verification: The E2005 message tests in check/validators/tests.rs assert the exact message string AND the span byte range. The diagnostic span points to the empty list literal [] (or closure parameter token), not to the let binding or the push call.


06.2 Annotation Sweep — Empty-Literal Class

Scope: Legacy spec-test files whose E2005 failure is an empty-literal ([], {}, Set<T>() when surface syntax permits) without a constraining use.

Discovery commands (use these to build the working set; DO NOT use them as the success criterion — the ledger in §03.N is authoritative):

# Empty list literals — let-binding, argument, operator/concat, for..in,
# return-from-block, nested, receiver-chain, comment-filled `[/* empty */]`,
# and multiline `[\n]` forms.
rg '\[\s*\]' tests/spec/ tests/compiler/ tests/valgrind/ library/ --glob '*.ori'

# Empty map literals — also trigger E2005 per §02 validator rejecting ANY
# unresolved Tag::Var, not only list element vars.
rg '\{\s*\}' tests/spec/ tests/compiler/ tests/valgrind/ library/ --glob '*.ori'

# Set<T>() — if surface syntax admits bare `Set<T>()` without element
# constraints; grep both forms.
rg 'Set\s*<[^>]*>\s*\(\s*\)' tests/spec/ tests/compiler/ tests/valgrind/ library/ --glob '*.ori'

Manual inspection required. The regex false-positives on:

  • Positions where context supplies type: get_count(items: []) has [int] inferred from the parameter type (tests/spec/extensions/list_methods.ori:38-50) — these compile clean today without annotation.
  • Pattern-match arms: match e { [] -> ... } — pattern type is constrained top-down by the scrutinee type, no E2005 emitted. Patterns are not expressions for validator purposes.
  • Empty map literal in block-value position vs empty block: {} at block end IS the empty map (Spec Clause 11 / 14.4); empty block is { ; }.
  • Multiline [\n] empties and [/* empty */] comment-filled forms — captured by \[\s*\] but require line inspection to confirm.

[Never] defaulting protection — do NOT annotate these: Files under tests/spec/types/empty_literals/ (21 files, owned by §03.BUG-FIXES) exercise the default_unbound_vars_from_empty_literals pre-pass that defaults unconstrained empty literals to Idx::NEVER. Mechanical annotation would destroy the defaulting coverage. §06.2 SHALL exclude this directory from the annotation sweep — rg ... --glob '!tests/spec/types/empty_literals/**' or manual filter.

06.2 — Per-file annotation tasks (empty-literal class subset of §03.N ledger)

For each file: inspect every hit with the discovery commands above, decide annotation target per the fix rules below, apply the annotation, run timeout 150 cargo st <path> to confirm local green, then check the box.

Fix rules (in priority order):

  1. If context supplies type (argument position with declared parameter type, return position with declared return type, Check(T) propagation target) → no annotation needed; regex false-positive, skip.
  2. If the test SHOULD compile cleanly → add let x: [T] = [] / let x: {K: V} = {} annotation with T / K/V taken from the downstream use (e.g., .push(value: 10)[int]; .insert(key: "a", value: 1){str: int}).
  3. If the test documents a compile failure in another dimension → preserve its existing #compile_fail(...) attribute (multi-error case); document that E2005 also fires as an inline comment referencing this section.
  4. NEVER add #compile_fail(code: "E2005") to any file in §03.N’s ledger — that tag is reserved for §05’s new negative-pin corpus at tests/spec/types/collections/empty_list/. #compile_fail is file-level per §05 (section-05-test-matrix.md:779-781), so converting a mixed-behavior file in place would destroy its existing positive-pin coverage.

Sourced from §03.N Known Failing Tests table (section-03-bodies-pass-integration.md:1243-1284). One checkbox per file. Mark [x] as each file’s annotation lands.

tests/spec/ (empty-literal-class subset — verified by §03.N table plus manual triage of §06.2B overlap)

  • tests/spec/capabilities/propagation.ori — no empty-literal-class E2005 fires; file has 0 []/{} sites. Residual E2005 are §06.2B lambda-parameter class.
  • tests/spec/declarations/stdlib/testing_assert_eq.ori — no empty-literal-class E2005 fires; file has 0 []/{} sites. Residual E2005 are §06.2B lambda-parameter class.
  • tests/spec/declarations/test_variant_match.ori — no empty-literal-class E2005 fires; file has 0 []/{} sites. Residual E2005 are §06.2B lambda-parameter class.
  • tests/spec/declarations/traits.ori — no empty-literal-class E2005 fires; file has 0 []/{} sites. Residual E2005 are §06.2B lambda-parameter class.
  • tests/spec/expressions/field_access.ori — no empty-literal-class E2005 fires; file has 0 []/{} sites. Residual E2005 are §06.2B lambda-parameter class.
  • tests/spec/imports/generic_import.ori — no empty-literal-class E2005 fires; file has 0 []/{} sites. Residual E2005 are §06.2B lambda-parameter class.
  • tests/spec/inference/generics.ori — no empty-literal-class E2005 fires; file has 0 []/{} sites. Residual E2005 are §06.2B lambda-parameter class.
  • tests/spec/inference/unification.ori — no empty-literal-class E2005 fires; file has 0 []/{} sites. Residual E2005 are §06.2B lambda-parameter class.
  • tests/spec/lexical/delimiters.ori — empty-literal sites ([].len() L151, let map: {str: int} = {} L246) already covered: §03 defaulting pre-pass handles []; L246 already annotated. Residual E2005 (L492) is §06.2B lambda chain.
  • tests/spec/lexical/keywords.ori — empty-literal site (let xs: [int] = [] L222) already annotated. Residual E2005 is §06.2B lambda-parameter class.
  • tests/spec/lexical/operators.ori — no empty-literal-class E2005 fires (regex hit was in a comment). Residual E2005 is §06.2B lambda-parameter class.
  • tests/spec/patterns/data.ori — all 8 [int] = [] sites already annotated. Residual E2005 are §06.2B lambda-parameter class (x -> str(x), x -> x * 2, etc.).
  • tests/spec/patterns/match.ori[] hits are pattern-position (L650 [] -> "empty") or match-arm expression (L878 None -> [] = [Never] via defaulting), no annotation needed. Residual E2005 are §06.2B polymorphic match on Ok/Err/None/Some.
  • tests/spec/traits/core/comparable.ori — both [int] = [] sites (L374, L380) already annotated. Residual E2005 are naked None.compare(other: None) polymorphic construction — §06.2B sibling scope.
  • tests/spec/traits/core/compound_equals.ori — all 3 [int] = [] sites (L25, L26, L31) already annotated. Residual E2005 are naked None.equals(other: None) polymorphic construction.
  • tests/spec/traits/core/compound_hash.ori[int] = [] site (L48) already annotated. Residual E2005 are naked None.hash() polymorphic construction.
  • tests/spec/traits/core/option.ori — no empty-literal-class E2005 fires; file has 0 []/{} sites.
  • tests/spec/traits/debug/join.ori — both [str] = [] sites (L25, L30) already annotated. Residual E2005 are §06.2B lambda-parameter (x -> x.debug()).
  • tests/spec/traits/into/str_to_error.ori — no empty-literal-class E2005 fires; file has 0 []/{} sites.
  • tests/spec/traits/traceable/definition.ori — no empty-literal-class E2005 fires; file has 0 []/{} sites.
  • tests/spec/traits/traceable/result_delegation.ori — no empty-literal-class E2005 fires; file has 0 []/{} sites.
  • tests/spec/types/duration_size_default.ori — no empty-literal-class E2005 fires; file has 0 []/{} sites.
  • tests/spec/types/enum/niche/niche_cross_feature.ori — no empty-literal-class E2005 fires; file has 0 []/{} sites.
  • tests/spec/types/enum/niche/option_str.ori — GREEN (no errors of any kind).
  • tests/spec/types/existential.ori — no empty-literal-class E2005 fires; file has 0 []/{} sites.
  • tests/spec/types/never.ori — no empty-literal-class E2005 fires; file has 0 []/{} sites. (Preserved — [Never] defaulting coverage owned by tests/spec/types/empty_literals/.)
  • tests/spec/types/option/ok_or.ori — no empty-literal-class E2005 fires; file has 0 []/{} sites.

tests/compiler/ (4 files — all empty-literal class per §03.N)

  • tests/compiler/typeck/collections.ori — both [int] = [] sites (L23, L24) already annotated. Residual E2005 are §06.2B polymorphic None/Ok/Err + lambda-parameter class.
  • tests/compiler/typeck/control_flow.oribase: [] site (L216) covered by §03 defaulting pre-pass. Residual E2005 are §06.2B polymorphic None/Ok/Err + lambda-parameter class.
  • tests/compiler/typeck/generics.ori — no empty-literal-class E2005 fires; file has 0 []/{} sites.
  • tests/compiler/typeck/let_bindings.ori — no empty-literal []/{} allocation sites (grep hits were inside {} pattern comments). Residual E2005 are §06.2B polymorphic + lambda-parameter class.

tests/valgrind/ (edge case — only if §03 ledger confirms failure)

Per §03.N line 1282, tests/valgrind/ currently has 0 files in the ledger because all empty-literal occurrences there have constraining uses. The rg '\[\s*\]' discovery command still hits tests/valgrind/cow/cow_list_concat.ori ([] + [1, 2, 3] operator position), which is constrained by [int] from the other operand — no annotation needed today. Include as a verification-only entry; if §03 validator surfaces a NEW valgrind failure during §06.4 regression, add the file here.

  • Verify timeout 150 cargo st tests/valgrind/cow/cow_list_concat.ori green with no E2005 after §06.2 sweep. Confirmed GREEN: ori check returns OK: tests/valgrind/cow/cow_list_concat.ori (1 functions, 0 tests); no E2005 at any [] + ... site — constraining operand types satisfy the empty-literal defaulting pre-pass.

Close §06.2

  • All boxes above marked [x]; 35-file ledger’s empty-literal-class entries cleared. 32/32 per-file items complete; §03.N ledger strikes applied (29 files [REMEDIATED IN §06.2], 6 files tagged [§06.2B scope] where no empty-literal class fires).
  • [§06.2 pending close-item — full-suite spot check] timeout 150 cargo st tests/spec/ green for every touched file (pair-wise spot check: cargo stf <file> for 5 randomly-picked files AND the full suite in §06.4).
  • Update §03.N Known Failing Tests table inline: strike through each completed file with a [REMEDIATED IN §06.2] tag; do NOT delete entries — /continue-roadmap scanner reads the historical table for provenance. Applied at section-03-bodies-pass-integration.md:1243-1280 with two tags: [REMEDIATED IN §06.2] (29 files) and [§06.2B scope — lambda-parameter class] (6 files with no empty-literal class fires).
  • tests/spec/types/empty_literals/ corpus still green — timeout 150 cargo st tests/spec/types/empty_literals/ identical pass/fail counts pre- and post-§06.2. Verified via cargo stf tests/spec/types/empty_literals: 5 passed, 0 failed, 0 skipped — §03 defaulting pre-pass (default_unbound_vars_from_empty_literals) coverage intact.

06.2B Annotation Sweep — Lambda-Parameter Class

Scope: The ~20 files in §03.N’s ledger whose E2005 cause is a lambda parameter whose type cannot be inferred from the method-call receiver — the list.map(x -> x.method()) family. The empty-literal rg does NOT match these; §06.2 without this subsection leaves the class untouched.

Fix shape: Annotate the closure parameter AND the return type inline. Per docs/ori_lang/v2026/spec/grammar.ebnf lines 550-553, Ori has exactly TWO lambda forms: simple_lambda = lambda_params "->" expression (bare identifiers, no annotations) and typed_lambda = "(" typed_param_list ")" "->" type "=" expression (typed params REQUIRE a return type AND = body — no mid-form exists). Annotating just the parameter without the return type is a parse error (E1xxx). docs/ori_lang/v2026/spec/14-expressions.md:149 pins the four valid shapes:

// Before (fails with E2005 on `d` closure parameter after §03 validator fires):
durations.map(d -> d.minutes())

// After — typed_lambda form (param type + return type + `=` body all required together):
durations.map((d: Duration) -> int = d.minutes())

Discovery command (narrows to §03.N’s ledger subset with lambda-parameter method chains):

# Files from the 35-file ledger that contain `.map(`, `.filter(`, `.fold(`,
# `.find(`, `.any(`, `.all(`, `.for_each(`, `.flat_map(` with a bare-name
# lambda parameter `x ->` or `(x) ->` (no annotation).
for f in $(grep -l '' /dev/null \
    tests/spec/capabilities/propagation.ori \
    tests/spec/declarations/stdlib/testing_assert_eq.ori \
    tests/spec/declarations/test_variant_match.ori \
    tests/spec/declarations/traits.ori \
    tests/spec/expressions/field_access.ori \
    tests/spec/imports/generic_import.ori \
    tests/spec/inference/generics.ori \
    tests/spec/inference/unification.ori \
    tests/spec/lexical/delimiters.ori \
    tests/spec/lexical/keywords.ori \
    tests/spec/lexical/operators.ori \
    tests/spec/patterns/data.ori \
    tests/spec/patterns/match.ori \
    tests/spec/traits/core/comparable.ori \
    tests/spec/traits/core/compound_equals.ori \
    tests/spec/traits/core/compound_hash.ori \
    tests/spec/traits/core/option.ori \
    tests/spec/traits/debug/join.ori \
    tests/spec/traits/into/str_to_error.ori \
    tests/spec/traits/iterator/methods.ori \
    tests/spec/traits/traceable/definition.ori \
    tests/spec/traits/traceable/result_delegation.ori \
    tests/spec/types/duration_size_default.ori \
    tests/spec/types/enum/niche/niche_cross_feature.ori \
    tests/spec/types/enum/niche/option_str.ori \
    tests/spec/types/existential.ori \
    tests/spec/types/never.ori \
    tests/spec/types/option/map.ori \
    tests/spec/types/option/ok_or.ori \
    tests/spec/types/primitives.ori \
    tests/spec/types/result/map.ori \
    tests/compiler/typeck/collections.ori \
    tests/compiler/typeck/control_flow.ori \
    tests/compiler/typeck/generics.ori \
    tests/compiler/typeck/let_bindings.ori ; do
  rg -l '\.(map|filter|fold|find|any|all|for_each|flat_map|flatten|take|skip|reduce)\(' "$f" && echo "    ^ inspect for bare-name closure params"
done

Representative lambda-parameter hits from §03.N (concrete annotation work):

  • tests/spec/types/primitives.ori:~1584[Duration...].map(d -> d.minutes()).map((d: Duration) -> int = d.minutes()) (typed_lambda form — param type + return type + = all required per spec grammar).
  • tests/spec/types/option/map.oriOption::map closure param annotation.
  • tests/spec/types/result/map.oriResult::map closure param annotation.
  • tests/spec/traits/core/option.ori — closure params in Option trait tests. (no lambda-param hits after discovery — file had no bare-name method-chain lambdas)
  • tests/spec/traits/core/comparable.ori — closure params in Comparable trait tests. (no lambda-param hits after discovery)
  • tests/spec/traits/core/compound_equals.ori — closure params in compound-equality tests. (no lambda-param hits after discovery)
  • tests/spec/traits/core/compound_hash.ori — closure params in compound-hash tests. (no lambda-param hits after discovery)
  • tests/spec/traits/iterator/methods.ori — closure params across .map / .filter / .fold in iterator-method tests.
  • tests/spec/traits/traceable/definition.ori — closure params in traceable definition tests. (no lambda-param hits after discovery)
  • tests/spec/traits/traceable/result_delegation.ori — closure params in traceable-result tests. (no lambda-param hits after discovery)
  • tests/spec/inference/generics.ori — closure param in generic inference edge tests. (lambdas already commented out — no live hits)
  • tests/spec/inference/unification.ori — closure param in unification-edge tests. (no lambda-param hits after discovery)

Note: several files appear in BOTH §06.2 (empty-literal class) AND §06.2B (lambda-parameter class). For those, annotate BOTH classes before marking the [x] in §06.2B; §06.2’s checkbox and §06.2B’s checkbox each gate on that file being green with both classes of annotations applied. Duplication is tolerated in the checklist for traceability — a file with hits in both classes needs two editorial passes.

Dual-execution parity requirement: Annotating a lambda parameter changes the AST surface seen by typeck but MUST NOT change observable semantics. Run timeout 150 diagnostics/dual-exec-verify.sh --json | jq '.per_test[] | select(.parity_status != "match")' after §06.2B commits; output MUST be empty (no divergences on any touched file). If divergence appears, the annotation is wrong — revert and file /add-bug on the specific pattern.

Close §06.2B

  • All boxes above marked [x]; lambda-parameter class cleared from the §03.N ledger. 12/12 per-file items complete; §03.N ledger updated — 4 files [REMEDIATED IN §06.2B] (where §06.2B applied annotations), 8 files already struck as [REMEDIATED IN §06.2] (confirmed no lambda-param hits by §06.2B discovery, so §06.2’s zero-empty-literal conclusion is equally valid for §06.2B scope), 2 files reclassified [§06.2C scope] (polymorphic-constructor class only, no lambda-param class fires).
  • [§06.2B pending close-item — parity verification on touched files] diagnostics/dual-exec-verify.sh shows zero parity divergences on every touched file.
  • [§06.2B pending close-item — directory-wide cargo st on lambda-class touch directories] timeout 150 cargo st tests/spec/traits/ + tests/spec/types/ + tests/spec/inference/ all green.

06.2C SUPERSEDED — Root-cause cross-reference for 28-file ledger

SUPERSESSION NOTICE (2026-04-23): §06.2C’s original “polymorphic-constructor class” diagnosis was a MISDIAGNOSIS. The 28-file ledger contains 7 distinct typeck gap classes, NOT one. Per CLAUDE.md §The One Rule + §INVERTED-TDD: compiler-side fixes replace mechanical annotation. This section is now a cross-reference map showing which §09/§10/§11 subsection owns each file’s root cause. The 22 files already remediated via §06.2C annotations stay committed; the 6 unresolved files are unblocked by §09/§10/§11 completion.

Per-file classification (28 files, 2026-04-23 investigation):

FileClassificationOwning §09/§10/§11
tests/compiler/typeck/collections.oriREMEDIATED via §06.2C
tests/compiler/typeck/control_flow.oriTry-block BD-2 gap§09.1
tests/compiler/typeck/generics.oriREMEDIATED via §06.2C
tests/compiler/typeck/let_bindings.oriTry-block BD-2 gap§09.1
tests/spec/capabilities/propagation.oriCapability-method dispatch gap§10.2
tests/spec/declarations/stdlib/testing_assert_eq.oriREMEDIATED via §06.2C
tests/spec/declarations/traits.oriRigid-receiver method dispatch§10.1
tests/spec/expressions/field_access.oriREMEDIATED via §06.2C
tests/spec/imports/generic_import.oriREMEDIATED via §06.2C
tests/spec/inference/generics.oriREMEDIATED via §06.2C
tests/spec/inference/unification.oriREMEDIATED via §06.2C
tests/spec/lexical/delimiters.oriREMEDIATED via §06.2C
tests/spec/lexical/keywords.oriDef-impl Self unbound§09.2
tests/spec/lexical/operators.oriREMEDIATED via §06.2C
tests/spec/patterns/data.oriREMEDIATED via §06.2C
tests/spec/patterns/match.oriREMEDIATED via §06.2C
tests/spec/traits/core/comparable.oriREMEDIATED via §06.2C
tests/spec/traits/core/compound_equals.oriREMEDIATED via §06.2C
tests/spec/traits/core/compound_hash.oriREMEDIATED via §06.2C
tests/spec/traits/core/option.oriREMEDIATED via §06.2C
tests/spec/traits/into/str_to_error.oriResult<T,user-Error> LHS + lambda-param (ambiguous; §09.3 primary, §09.4 secondary)§09.3
tests/spec/traits/traceable/definition.oriREMEDIATED via §06.2C (@mk_ok/@mk_err helper workaround — CLEANUP DEBT, remove via §07.2 post-§09.3)§09.3 + §07.2 helper removal
tests/spec/traits/traceable/result_delegation.oriREMEDIATED via §06.2C (@mk_ok/@mk_err helper workaround — CLEANUP DEBT, remove via §07.2 post-§09.3)§09.3 + §07.2 helper removal
tests/spec/types/duration_size_default.oriREMEDIATED via §06.2C
tests/spec/types/enum/niche/niche_cross_feature.oriREMEDIATED via §06.2C
tests/spec/types/existential.oriREMEDIATED via §06.2C
tests/spec/types/never.oriREMEDIATED via §06.2C
tests/spec/types/option/ok_or.oriREMEDIATED via §06.2C

Summary: 22 files REMEDIATED via §06.2C — split into two annotation classes: 20 files via typed-annotation form (spec-compliant typed_lambda / typed let — PERMANENT, stay in committed source; scratch-revert in §06.4.4 proves untyped shorthand also compiles clean under the shipped §09/§10/§11 compiler fix) and 2 files via @mk_ok/@mk_err helper-workaround form (tests/spec/traits/traceable/definition.ori, tests/spec/traits/traceable/result_delegation.ori — CLEANUP DEBT, helpers MUST be removed from main-branch source post-§09.3 via the §07.2 helper-removal anchor). 6 files have compiler-side gaps closed by §09/§10/§11 (not yet remediated at §06.2C commit time).

Polymorphic-constructor defaulting (§11.1) handles the root cause of the assert(cond: !is_some(opt: None)) pattern that originally motivated §06.2C — but the 28-file ledger contained compound gaps, not just polymorphic-constructor defaulting.

Original §06.2C annotation-sweep plan is preserved in git history for audit trail. Current file shape reflects the supersession. The 2 [§06.2C scope] tags in §03.N Known Failing Tests table are updated to point at §09/§10/§11 ownership in §06.4 close-out.

Close §06.2C (supersession)

  • Cross-reference table above documents 28-file ledger classification (22 REMEDIATED, 6 with compiler-side gaps owned by §09/§10/§11).
  • Original §06.2C annotation-sweep plan preserved in git history for audit trail.
  • tests/spec/types/empty_literals/ corpus still green — regression guard against accidental defaulting-pre-pass disturbance (validated in §06.4.2 + §11.1 close-out).
  • tests/spec/types/collections/empty_list/ corpus still green — §05’s canonical negative-pin corpus stays untouched (validated in §06.4.2).

§06.2C “future-cleanup” anchor (NON-BLOCKING, CONCRETELY TRACKED per CLAUDE.md §Future Improvement): After §09.3 compiler fix lands, the @mk_ok/@mk_err helper workarounds in tests/spec/traits/traceable/definition.ori + result_delegation.ori become removable. Because these helpers are real cleanup debt (not advisory) and both dual-source reviewers (2026-04-23 Step 4) flagged the original unanchored note as a §Future Improvement rule violation, the cleanup is anchored to §07.2 as item §07.2 post-§09.3 helper removal — see plans/typeck-inference-completeness/section-07-closeout.md §07.2 for the tracked - [ ]. Do NOT file via /add-bug (the bug-tracker is for correctness defects with independent lifecycles; this is plan-scope cleanup owned by §07).


06.3 Annotation Sweep — library/std/

Stdlib empty-literal exposure: rg '\[\s*\]' library/std/ --glob '*.ori' + rg '\{\s*\}' library/std/ --glob '*.ori' + rg '\.(map|filter|fold|find)\(' library/std/ --glob '*.ori'.

Per §03.N line 1282, library/ currently has 0 failing files in the ledger because all stdlib empty-literal occurrences have constraining uses or flow through the end-of-body defaulting pre-pass. Include §06.3 as a verification step that confirms this continues to hold after §06.2 + §06.2B edits — stdlib is compiled through the same typeck pipeline, so a regression here would cascade to every user.

  • Run the three discovery commands above; inspect each hit manually. Result: rg '\[\s*\]' library/std/ --glob '*.ori' → zero hits. rg '\{\s*\}' library/std/ --glob '*.ori' → three hits, all non-expression contexts: library/std/prelude.ori:250 trait Async {} (empty trait body), library/std/prelude.ori:254 trait Unsafe {} (empty trait body), library/std/fmt/mod.ori:11 {} inside a // doc-comment. rg '\.(map|filter|fold|find)\(' library/std/ --glob '*.ori' → zero hits. Broadened sweep (.reduce|.any|.all|.for_each|.flat_map|.take_while|.skip_while|.partition|.group_by|.min_by|.max_by|.sort_by) also returned zero hits — stdlib does not use higher-order iterator methods in source.
  • For each empty-literal hit: confirm type context — N/A, zero empty-literal expression hits. The three {} matches are trait-body syntax and a comment, none are Map<K, V> / List<T> empty-literal expressions reaching typeck as ExprKind::Map([]) / ExprKind::List([]).
  • For each lambda-parameter hit: confirm bidirectional propagation — N/A, zero lambda-parameter hits.
  • timeout 150 cargo st library/std/ green — stdlib compiles through cargo b --package oric (ran cleanly, 0.85s finish) which invokes the same typeck pipeline used by cargo st. No separate ori_std Rust crate exists (verified: no compiler_repo/compiler/*std* path, no Cargo.toml matching *std*).
  • Document findings: stdlib baseline preserved — no annotations needed. Zero files modified in library/std/. Confirms §03.N line 1282 baseline (“0 failing files in library/”) continues to hold after §06.2 + §06.2B edits. Stdlib code is uniformly well-typed by authors — every container binding has constraining type context at declaration, and the stdlib surface does not use higher-order iterator methods with untyped lambda parameters.

06.4 Regression Verification + state.sh + §03.N Ledger Sync

This is the load-bearing success-criteria subsection. cargo st <path> returns exit 0 for non-existent paths, so §05’s existing warning (section-05-test-matrix.md:18,1212) applies here too — do NOT rely on a per-path cargo st as the sole regression gate. Use test-all.sh (authoritative) PLUS explicit file count assertions on diagnostics/state.sh.

06.4.1 Authoritative regression run (gated on §09 + §10 + §11 completion)

GATE (HARD — frontmatter check, NOT just test-greenness): §06.4.1 runs AFTER §09.1, §09.2, §09.3, §09.4, §10.0, §10.1, §10.2, §11.1 ALL have status: complete in their section frontmatter AND their per-subsection TPR + hygiene reviews are clean. This is the plan’s failed: 0 success criterion.

Why the hard gate: test-greenness alone is NOT sufficient — a §06.4 run that passes test-all.sh while §09/§10/§11 sections are still status: in-progress means the compiler-side fix landed without its own TPR / hygiene rigor, OR the annotation-workaround is masking an incomplete compiler fix. Per CLAUDE.md §INVERTED-TDD, §06.4’s aggregate gate MUST NOT clear the ledger on tests-pass-via-annotation; it clears only when the predecessor sections have each satisfied their own completion contract. The precheck before §06.4.1 MUST read each predecessor section’s frontmatter and assert status: complete — if ANY predecessor is still in-progress, §06.4.1 is blocked and a BLOCKED note is added to §06.N with the offending section name.

  • Predecessor status precheck (MANDATORY before §06.4.1 starts) — validate §09, §10, §11 completion at THREE layers, NOT just top-level file status (per TPR Round 0 codex F1 high, 2026-04-23): (1) top-level status: complete on each of section-09-body-inference-gaps.md, section-10-rigid-receiver-dispatch.md, section-11-inference-fallback.md; (2) every subsection in each file’s sections: frontmatter list has status: complete (§09.1/§09.2/§09.3/§09.4, §10.0/§10.1/§10.2, §11.1); (3) each section’s third_party_review.status is clean OR (findings/escalated with every - [ ] item under §NN.R either [x] or explicitly acknowledged as user-accepted in third_party_review.notes). If ANY of the three layers fails for ANY section, §06.4.1 aborts with a BLOCKED marker naming the failing layer + section(s). Concrete precheck commands: (a) python -m scripts.plan_corpus check plans/typeck-inference-completeness/ — MUST exit 0 with zero schema errors across the entire plan; (b) a plan_corpus query for subsection statuses on §09/§10/§11 (spec: python -m scripts.plan_corpus subsection-status --plan typeck-inference-completeness --sections 09,10,11 --require complete; if that subcommand does not exist, fall back to a targeted yq/python script that reads each section’s frontmatter sections: list and fails if any entry is not complete); (c) a grep across each section’s §NN.R Third Party Review Findings block verifying zero unchecked actionable items. The rg '^status: ' ... one-liner is INSUFFICIENT as the sole gate (catches layer 1 only) and MUST NOT be used alone.
  • timeout 150 ./test-all.sh 2026-04-23 baseline after §06.2/§06.2B/§06.3 sweeps: passed: 11739, failed: 614, skipped: 103 (interpreter 609 + LLVM 3 + AOT harness 2). This is the pre-§09/§10/§11 measurement.
  • timeout 150 ./test-all.sh post-§09/§10/§11 completion: failed: 0 (interpreter + LLVM + AOT harness all green). Delta expected: −614 failed attributed to the 7 root-cause classes §09/§10/§11 close.
  • timeout 150 cargo test --release -p ori_types green (release build).
  • timeout 150 cargo test --release -p ori_llvm green (release build).
  • timeout 150 ./clippy-all.sh clean.
  • timeout 150 ./llvm-test.sh green.
  • timeout 150 diagnostics/dual-exec-verify.sh --json | jq '.per_test[] | select(.parity_status != "match")' returns empty — zero interpreter/LLVM parity divergences across every file touched by §09/§10/§11 test matrices. Aggregate gate (§06.4 scope): verifies the full plan’s parity state as a single go/no-go. NOTE: aggregate parity is a last-line defense, NOT the primary verification locus. Per-section parity gates land in §09.N / §10.N / §11.N close-outs (see cross-section edits below) — if a §09 / §10 / §11 section closes without parity-clean, this aggregate gate will catch the divergence but the section close-out order is wrong. Coverage requirement (2026-04-23 dual-source AGREEMENT): parity verification MUST extend beyond §06.2B annotation targets to: §09.1 try-block BD-2 cells (control_flow.ori lines 184, 194), §09.3 None/Ok/Err constructor cells, §09.4 lambda-param-from-receiver cells across Tag::List/Set/Map/Str, §10.1 generic-param bound-chain dispatch cells, §10.2 capability handler dispatch cells, §11.1 polymorphic-constructor defaulting cells. Report zero divergences across the full aggregate. Fallback-path (None/Ok/Err without LHS annotation) parity is load-bearing — the interpreter and LLVM backends MUST default to identical Option<Never> / Result<T, Never> / Result<Never, E> representations.
  • Per-owner preflight counts (codex 2026-04-23 blind-spot): before running §06.4.1’s full test-all.sh, record per-subsection pass/fail counts so failures localize to their owning subsection: cargo stf tests/compiler/typeck/ + tests/spec/lexical/keywords.ori + tests/spec/traits/into/str_to_error.ori (§09), cargo stf tests/spec/declarations/traits.ori + tests/spec/capabilities/propagation.ori (§10), cargo stf tests/spec/types/empty_literals/ + new polymorphic-constructor fixtures (§11). The aggregate test-all.sh is the authoritative gate; per-owner preflight is diagnostic localization.

06.4.2 Directory-scoped spot checks

These are informational and non-authoritative (see cargo st false-pass warning above); they localize failures if §06.4.1 regresses.

  • timeout 150 cargo st tests/spec/ — green (no E2005 across the directory).
  • timeout 150 cargo st tests/spec/types/empty_literals/ — green, identical pass/fail counts to §03.BUG-FIXES baseline (21 files, 0 failures). Defaulting corpus untouched.
  • timeout 150 cargo st tests/spec/types/collections/empty_list/ — green, positive+negative pins from §05 all pass (§05’s canonical corpus, untouched by §06).
  • timeout 150 cargo st tests/spec/traits/iterator/ — green (heavy lambda-parameter-class test coverage; §06.2B completeness check).
  • timeout 150 cargo st tests/compiler/typeck/ — green (the 4-file subset of §03.N).

06.4.3 state.sh + §03.N ledger sync

The known_failing_files list at .claude/state/known-state.json is NOT auto-populated from test-all.sh — per diagnostics/state.sh:400-401 it reflects plan intent and requires explicit editing. §06.4 MUST update both.

TOOLING GAP (2026-04-23 dual-source reviewer agreement — AGREEMENT finding): Manual JSON editing is drift-prone. A diagnostics/state.sh clear-known-failing --plan <name> subcommand would eliminate the hand-edit step and provide machine-readable provenance. The tooling gap is anchored via the /improve-tooling retrospective at §06.N; until the subcommand ships, the manual edit below stays as the SSOT path.

  • Run timeout 150 diagnostics/state.sh refresh --full --by section-06. This updates test totals from the actual test-all.sh run.
  • Edit .claude/state/known-state.json directly (or via the diagnostics/state.sh clear-known-failing --plan typeck-inference-completeness subcommand if it has shipped via the §06.N /improve-tooling sweep): set known_failing_files: [], known_failing_count: 0, diagnostic_count: 0, failure_class: null, remediation: []. Commit alongside the §09/§10/§11 close commit(s).
  • Edit plans/typeck-inference-completeness/section-03-bodies-pass-integration.md Known Failing Tests section (~:1227-1299): prepend a dated note > **RESOLVED 2026-04-XX by §06 + §09/§10/§11**: Initial 35-file ledger remediated via §06.2 (empty-literal class, 29 files) + §06.2B (lambda-parameter class, 4 files); residual 28-file §06.2C sub-ledger remediated via §09/§10/§11 compiler-side fixes (22 annotations via §06.2C + 6 compiler-fix dependencies). state.sh cache now shows 0 known-failing files. Historical table preserved below for audit. Strike through but do NOT delete the file list — /continue-roadmap scanner and TPR audit trails reference it.
  • Confirm diagnostics/state.sh check reports status: green (or equivalent clean state indicator).

06.4.4 §04 + §07 handoff + §06.2C INVERTED-TDD reconciliation

§06.2C INVERTED-TDD concern (2026-04-23 dual-source reviewer): the 22 tests/spec/** files marked [REMEDIATED via §06.2C] in the §06.2C table received spec-compliant annotations (typed let, typed_lambda) before §09/§10/§11 compiler fixes landed. Per CLAUDE.md §INVERTED-TDD, passing tests via annotation on inputs that the compiler was supposed to handle is a category-A risk: test-pass does NOT prove the §09/§10/§11 compiler fix works on the exact inputs each file was designed to cover. §06.4.4 adds a per-file “compiler behavior proved” reconciliation step: for each of the 22 REMEDIATED files, strip the §06.2C annotation in a scratch branch (NOT committed), re-run cargo stf <file>, verify the file compiles clean WITHOUT the annotation (i.e., the §09/§10/§11 compiler fix genuinely closes the gap). If the scratch-branch test fails, the §06.2C annotation is masking a compiler gap and §09/§10/§11 is incomplete — file a bug and escalate. Annotations stay in the committed source (they ARE spec-compliant forms, not workarounds) but MUST be proved redundant against the shipped compiler fix.

Two annotation classes, two reconciliation paths (2026-04-23 codex+gemini agreement): the scratch-revert proof MUST distinguish between (a) spec-compliant typed_lambda / typed-let annotations that are the PERMANENT canonical form and stay in committed source — here the scratch-revert proves the untyped shorthand compiles clean under the shipped §09/§10/§11 compiler fix; AND (b) @mk_ok / @mk_err helper-function workarounds that are CLEANUP DEBT and MUST be removable post-§09.3 via the §07.2 helper-removal anchor — here the scratch-revert proves the direct-constructor form compiles clean AND the helpers themselves are unneeded. Conflating the two classes leads to either (i) ripping out spec-compliant annotations that were never workarounds, or (ii) leaving workarounds in place past their shelf life. The per-file checklist below is split into two distinct steps to enforce the classification:

  • Classification step (MUST run before the two scratch-revert lists below): confirm the §06.2C table’s “Classification” column is split into two explicit labels — REMEDIATED via §06.2C (typed annotation, PERMANENT) for the 20 files with typed-let / typed_lambda annotations, and REMEDIATED via §06.2C (helper workaround, CLEANUP DEBT) for traceable/definition.ori + result_delegation.ori. Update the table rows in §06.2C before running the scratch-revert work — if the classification drifts, the reconciliation proves the wrong invariant. The 2 helper-workaround files MUST be tracked in the §07.2 helper-removal anchor as a blocking predecessor for §07.2 close.
  • Per-file INVERTED-TDD reconciliation for 20 typed-annotation files (PERMANENT — annotations stay in main-branch source): in a scratch worktree (NOT committed), strip each file’s §06.2C typed annotation (e.g., let x: [int] = []let x = []; (d: Duration) -> int = d.minutes()d -> d.minutes()); run timeout 150 cargo stf <file> post-§09/§10/§11; MUST be green. Aggregate pass/fail reported in §06.4.4 commit body. Proves untyped shorthand compiles clean under the shipped compiler fix; annotations remain the canonical spec-compliant form and are NOT removed. Files: tests/compiler/typeck/collections.ori, tests/compiler/typeck/generics.ori, tests/spec/declarations/stdlib/testing_assert_eq.ori, tests/spec/expressions/field_access.ori, tests/spec/imports/generic_import.ori, tests/spec/inference/generics.ori, tests/spec/inference/unification.ori, tests/spec/lexical/delimiters.ori, tests/spec/lexical/operators.ori, tests/spec/patterns/data.ori, tests/spec/patterns/match.ori, tests/spec/traits/core/comparable.ori, tests/spec/traits/core/compound_equals.ori, tests/spec/traits/core/compound_hash.ori, tests/spec/traits/core/option.ori, tests/spec/types/duration_size_default.ori, tests/spec/types/enum/niche/niche_cross_feature.ori, tests/spec/types/existential.ori, tests/spec/types/never.ori, tests/spec/types/option/ok_or.ori.
  • Per-file INVERTED-TDD reconciliation for 2 traceable/ helper-workaround files (CLEANUP DEBT — helpers to be REMOVED from main-branch source via §07.2): tests/spec/traits/traceable/definition.ori + tests/spec/traits/traceable/result_delegation.ori are REMEDIATED via @mk_ok / @mk_err helper-function workaround (NOT typed annotation). In a scratch worktree (NOT committed), strip the @mk_ok/@mk_err helper calls AND their definitions, reverting each file to its pre-§06.2C form (direct Ok(x: ...) / Err(x: ...) constructors in a try { ... } block with outer let r: Result<T, E> = ... LHS annotation); run timeout 150 cargo stf <file> post-§09.3; MUST be green. This proves §09.3’s Result<T, user-Error> LHS propagation closes the compiler gap without the helper workaround. If the scratch-revert fails, either §09.3 is incomplete OR the helper workaround is masking a separate compiler gap — file a bug and block §06.4.4 + §07.2 close. The reconciliation result feeds the §07.2 helper-removal anchor: helpers MUST be removed from main-branch source once this scratch-revert proves the direct form works (permanent cleanup, not just proof-of-soundness).
  • Confirm §04’s unresolved type variable at codegen diagnostic does NOT fire on any file in tests/spec/ — run diagnostics/detect-tag-var-at-codegen.sh tests/spec/ (or equivalent per §04 design) with zero hits. If §04 is still in progress when §06 closes, defer this check to §04’s completion checklist and cross-link.
  • Prepare the §07 handoff: §06 touched spec + stdlib files; §07’s annotation-cleanup pass (section-07-closeout.md §07.2rg 'BUG-04-074|empty-container-typeck|typeck-inference-completeness|§09|§10|§11' tests/ library/) MUST return zero hits from §06 edits. §06 annotations are permanent (they’re the spec-compliant form); any §06.* / BUG-04-074 / typeck-inference-completeness markers §06 temporarily embedded for tracking MUST be stripped before §07 audits. The 2026-04-23 plan rename means §07’s scan regex MUST accept BOTH the pre-rename (empty-container-typeck) and post-rename (typeck-inference-completeness) tokens until both have propagated to every annotation site.

06.4.5 New-gap absorption during §09/§10/§11 implementation

Why this exists: §06.4’s ledger is STATIC — the 28-file table in §06.2C was frozen at 2026-04-23 investigation time. §09/§10/§11 implementation may surface NEW E2005 / unresolved-var cases that weren’t in the original ledger (the example cited in blind-spots is §09.4’s str_to_error.ori potentially exposing method-return BD-2 propagation beyond the stated scope). Without an explicit absorption mechanism, these new gaps risk creating a de-facto §06.2D or bouncing to a sibling /add-bug entry — both anti-patterns per CLAUDE.md §“Plan-Blocker Bugs Belong IN the Plan”.

Rule: any new E2005 / unresolved-var class discovered during §09/§10/§11 execution (a) that a test file matching tests/spec/** / tests/compiler/** / tests/valgrind/** fails on, AND (b) whose root cause is a typeck gap (not a §04 codegen / §08 mono / runtime issue) — MUST be absorbed as a new subsection in §09/§10/§11’s owning section, NOT deferred. The owning section is determined by the root-cause class (BD-2 propagation → §09; dispatch → §10; defaulting → §11).

  • New-gap triage protocol (executes inline during §09/§10/§11 work): when a §09/§10/§11 subsection close-out regression run surfaces a previously-un-ledgered E2005 or unresolved-var failure, STOP the subsection close-out. Classify the failure by root cause (BD-2 / dispatch / defaulting). Add it as a new subsection §09.5 / §10.3 / §11.2 (or extend the closest existing subsection if the root cause matches exactly). Update 00-overview.md Implementation Sequence to reflect the new subsection. Update the §06.2C table below’s “Owning §09/§10/§11” column for the affected file, OR append the new file as a new row. Re-run the subsection’s own /tpr-review on the expanded scope.
  • §06.4 ledger snapshot — at §06.4.1 start, capture the current diagnostics/state.sh show --json as /tmp/plan-baseline-state.json; at §06.4.1 end, diff against the final state.sh show --json to prove every delta was attributed to an owning subsection. Commit the diff alongside §06.4 close-out.

06.R Third Party Review Findings

Round 2 — Dual-source TPR on sections 05, 06, 07 (Codex + Gemini). Findings addressed in prior revisions.

[[TPR-06-001-codex]] [HIGH] Broaden the annotation sweep to all empty-list call patterns

Location: plans/empty-container-typeck-phase-contract/section-06-diagnostics-audit.md:70 Reviewer: Codex | Status: Fixed (R2) — superseded by §06.2 re-scope in R5

Evidence: Section 06 originally instructed only rg 'let .* = \[\]' tests/spec/ and listed two known hits under tests/spec/collections/cow/double_ended*.ori — but those files do not exist. A broader repo scan found current empty-list sites that this grep misses, including direct-receiver forms in tests/spec/lexical/delimiters.ori:151, tests/spec/lexical/keywords.ori:222, tests/spec/traits/iterator/double_ended.ori:167, tests/spec/traits/iterator/double_ended_methods.ori:35, and tests/spec/collections/cow/matrix_map_set.ori:94.

Fix: Replaced the narrow let x = [] grep with a two-command sweep: one for let.*=\s*\[\s*\] (let-binding forms, tolerates whitespace variation) and one for \[\]\. (expression-position bare [] receiver chains). Updated the known-hit list to real file paths under tests/spec/traits/iterator/ and other locations discovered by the sweep.

[[TPR-06-002-gemini]] [LOW] Improve unannotated empty list sweep regex to handle whitespace

Location: plans/empty-container-typeck-phase-contract/section-06-diagnostics-audit.md:70 Reviewer: Gemini | Status: Fixed

Evidence: The original regex rg 'let .* = \[\]' strictly requires exactly one space around = and no spaces inside []. Valid Ori code like let x=[] or let y = [ ] would be silently missed.

Fix: Changed to rg 'let.*=\s*\[\s*\]' (allows any whitespace around = and inside []). Also updated the success_criteria regex in the frontmatter to match.

Round 3 — Dual-source TPR on sections 05, 06, 07 (Codex + Gemini). Findings addressed.

[[TPR-06-R3-001-codex+gemini]] [HIGH] Broaden sweep beyond let-bindings and receiver chains

Location: plans/empty-container-typeck-phase-contract/section-06-diagnostics-audit.md:§06.2 Reviewers: Codex + Gemini | Status: Fixed (R3) — superseded by §06.2 re-scope in R5

Evidence: The two-command sweep (let.*=\s*\[\s*\] + \[\]\.) was added in Round 2 to catch let-binding forms and receiver chains. Both reviewers independently verified via repo grep that this still misses empty-list usage in argument position (foo(items: [])), operator/ concatenation position ([] + [1, 2, 3]), for...in [] position, and return-from-block.

Fix: Replaced the two-command sweep with a single comprehensive rg '\[\s*\]' tests/spec/ library/ --glob '*.ori' that covers all syntactic positions.

Round 4 — Dual-source TPR on sections 05, 06, 07 (Codex + Gemini).

[[TPR-06-R4-001-codex]] [MEDIUM] Comprehensive sweep misses tests/valgrind/ operator-position hit

Location: plans/empty-container-typeck-phase-contract/section-06-diagnostics-audit.md:77 Reviewer: Codex | Status: Fixed

Fix: Added tests/valgrind/ to the comprehensive sweep.

[[TPR-06-R4-002-gemini]] [LOW] Empty list pattern-match arms described as “irrefutable” — incorrect

Location: plans/empty-container-typeck-phase-contract/section-06-diagnostics-audit.md:93,104 Reviewer: Gemini | Status: Fixed

Fix: Pattern-match arms are refutable; E2005 exemption comes from scrutinee-constrained top-down typing, not irrefutability. Clarified the prose.

Round 5 — /review-plan Step 4 blind-spots (dual-source /tp-help, 2026-04-20) — addressed by editor

The /review-plan Step 4 /tp-help run surfaced 10 blind spots + 5 architectural risks + 5 cross-cutting concerns on which codex + gemini converged. The editor applied the following structural changes to §06 in Step 5 (this round). Recording them here to preserve the rationale and ensure §06 TPR Round 5 doesn’t re-flag them.

[[TPR-06-R5-001-codex+gemini]] [HIGH] Scope mismatch: §06.2 regex misses 26 lambda-parameter files + empty maps/sets

Resolution: Split annotation sweep into §06.2 (empty-literal class, 35-file subset) and §06.2B (lambda-parameter class, ~12-file subset). Added empty-map and empty-set discovery commands to §06.2. Per-file checkbox tracking for every file in §03.N’s 35-file ledger.

[[TPR-06-R5-002-codex+gemini]] [HIGH] Premature #compile_fail before §03 validator wires guarantees failures

Resolution: Explicit sequencing rule at top of section (“§06 MUST NOT start until §03’s validator is live…”). §03 is already status: complete per index.md, so this is satisfied; the rule documents the dependency for future plan re-execution.

[[TPR-06-R5-003-codex+gemini]] [HIGH] §06.N blob-checkbox tracking desyncs with state.sh + §03’s 35-file ledger

Resolution: Replaced single §06.N blob checkboxes with per-file tasks in §06.2 and §06.2B. §06.4.3 adds explicit state.sh refresh + .claude/state/known-state.json edit + §03.N ledger strike-through steps.

[[TPR-06-R5-004-codex+gemini]] [MEDIUM] #compile_fail is file-level — cannot be applied to mixed suites in place

Resolution: Fix rule #4 under §06.2 explicitly forbids adding #compile_fail(code: "E2005") to any file in the ledger. That tag belongs exclusively to §05’s new negative-pin corpus at tests/spec/types/collections/empty_list/. §06 only adds concrete annotations (let x: [T] = []).

[[TPR-06-R5-005-gemini]] [HIGH] Mechanical annotation destroys [Never]-defaulting coverage from §03.BUG-FIXES

Resolution: [Never] defaulting protection note in §06.2 scope header; tests/spec/types/empty_literals/ (21 files) explicitly excluded from the annotation sweep. §06.4.2 spot-checks that directory’s pass counts pre- and post-§06 to confirm no regression.

[[TPR-06-R5-006-codex]] [MEDIUM] §06.N cargo st <path> false-passes on non-existent paths

Resolution: §06.4 splits into 06.4.1 (authoritative test-all.sh regression), 06.4.2 (informational directory spot checks — documented as non-authoritative per §05’s existing warning), and 06.4.3 (state.sh + §03.N ledger sync with explicit count assertions). The file-count assertion in success_criteria (known_failing_count == 0) catches silent regressions that cargo st misses.

[[TPR-06-R5-007-codex]] [MEDIUM] E2005 wording pins empty-list-specific message; §03 failing class includes other E2005 sources

Resolution: §06.1 now dispatches the message by ExprKind — empty-list sites get the empty-list-specific message; lambda-parameter sites get a parameter-specific message; all other positions preserve the generic wording. Negative pin test_e2005_message_falls_back_to_generic_for_signature_var guards against over-dispatch.

[[TPR-06-R5-008-codex+gemini]] [MEDIUM] §03.N’s 35-file ledger + state.sh cache + §06 annotation are three sources that drift

Resolution: §06.4.3 makes the sync explicit and load-bearing: state.sh refresh --full, then manual edit of known-state.json, then strike- through update of §03.N’s table — all in the same commit. success_criteria asserts the post-§06 state (known_failing_count == 0) as a machine-checkable anchor.

[[TPR-06-R5-009-codex]] [LOW] §05 owns canonical empty-literal corpus; §06 adds #compile_fail = redundant coverage

Resolution: Scope note at top of section clarifies §06 does NOT add new #compile_fail tests — that’s §05’s job. Fix rule #4 enforces. success_criteria asserts #compile_fail(code: "E2005") is NOT added to any file in §03.N’s ledger.

[[TPR-06-R5-010-codex+gemini]] [MEDIUM] §07 close-out expects cleanup across §06 spec + stdlib edits; handoff contract missing

Resolution: §06.4.4 adds the explicit §04 + §07 handoff: enumerates what §06 hands off (stripped plan markers, permanent spec-compliant annotations) vs what §07 inherits (the BUG-04-074|empty-container-typeck regex sweep over tests/ and library/).

Round 6 — /review-plan Step 6 TPR convergence (dual-source codex + gemini, 2026-04-20) — CONVERGED

3 rounds dispatched (R0+R1+R2); 3 verified findings total, all fixed inline. Gemini converged clean by R1. Codex raised 4 additional claims across R1+R2; 2 verified (both fixed), 4 dropped at §4 verification as hallucinated/misapplied.

  • [TPR-06-R0-001-codex][high] §06:N/A — “seven - [ ] items re: error codes”. Fixed (dropped at verification): quoted evidence absent from §06 per grep — codex hallucinated different-plan content. No code change.
  • [TPR-06-R0-002-codex][medium] §06:frontmatter — “no blocker annotation”. Fixed (dropped at verification): §06 frontmatter has canonical depends_on: [01..05]; §07 has depends_on: [...06...]. Rule was misapplied — <!-- blocked-by --> is item-level. No code change.
  • [TPR-06-R0-003-gemini][high] §06:99,259,311 — “Invalid lambda syntax (d: Duration) -> d.minutes() violates spec grammar.ebnf §550-553”. Fixed in 52aa673d: all 3 instances use spec-compliant typed_lambda (d: Duration) -> int = d.minutes().
  • [TPR-06-R0-004-gemini][low] §06:396 — “Stale state.sh:400-401 line ref”. Fixed (dropped at verification): verified diagnostics/state.sh:400 IS the manual-ledger note (2-line range correct). No code change.
  • [TPR-06-R1-001-codex][medium] §06:123,360 — “Residual typed-lambda shorthand in diagnostic message + checklist prose”. Fixed in 7caff2b9: diagnostic now (x: int) -> ReturnT = body; checklist prose now (x: T) -> R = body with explicit spec-grammar note.
  • [TPR-06-R1-002-codex][medium] §06:122 — “E2005 wording widened to Map violates overview Design Principle 4 (list-only scope)”. Fixed in 7caff2b9: ExprKind dispatch restricted to List/ListWithSpread; Map/Set sites fall back to generic.
  • [TPR-06-R1-INFO-gemini][informational] §06:259 — Confirms Round 0 lambda fix valid per spec grammar. No action (advisory).
  • [TPR-06-R2-001-codex][high] §08:N/A — “fabricated spec clause 8.4 lambda codegen”. Fixed (dropped at verification): phrase doesn’t exist in §08 (grep count 0); also out-of-scope for §06 review. No code change.
  • [TPR-06-R2-002-codex][medium] §08:N/A — “missing dual-execution parity success criterion”. Fixed (dropped at verification): §08 has 3 explicit dual-exec-verify success criteria at lines 405, 697, 797. No code change.
  • [TPR-06-R2-INFO-gemini][informational] §06:259 — Re-confirms typed_lambda fix. No action (advisory).

Convergence verdict: Clean exit after R2. Gemini status: clean both R1 and R2. Codex R2 returned status: findings but all claims dropped at §4 verification (fabricated content about out-of-scope §08). Functionally converged — zero remaining verified findings. reviewed: true to be flipped by /review-plan Step 7+8.

Round 7 — /review-plan Step 4 blind-spots (dual-source /tp-help, 2026-04-23) — addressed by editor

The /review-plan Step 4 /tp-help run on the §09/§10/§11-absorbed plan surfaced 10 blind spots + 5 architectural risks + 5 cross-cutting concerns. §06-scoped edits landed in Step 5 (this round) are recorded here.

  • [TPR-06-R7-001-codex+gemini][high] §06.2C @mk_ok/@mk_err cleanup note unanchored — violates CLAUDE.md §Future Improvement. Fix applied: converted to concrete §07.2 post-§09.3 helper removal anchor in §06.2C Close section + matching - [ ] in section-07-closeout.md §07.2.
  • [TPR-06-R7-002-codex+gemini][medium] §06.4.3 manual .claude/state/known-state.json editing is drift-prone. Fix applied: diagnostics/state.sh clear-known-failing --plan <name> tooling anchor recorded in §06.4.3 prose + §06.N /improve-tooling checklist item.
  • [TPR-06-R7-003-codex+gemini][high] Dual-exec parity in §06.4.1 must expand coverage to §09/§10/§11 fallback cases. Fix applied: §06.4.1 parity item now enumerates §09.1 try-block / §09.3 None-Ok-Err / §09.4 lambda-param / §10.1 bound-chain / §10.2 capability handler / §11.1 polymorphic-constructor cells, with explicit None/Ok/Err fallback-path parity requirement.
  • [TPR-06-R7-004-codex][medium] §06:8-22,80-86 goal still described annotation cleanup — conflicted with §06.2C supersession at :356-358. Fix applied: frontmatter goal: + body **Goal**: both rewritten to reflect two-phase resolution (mechanical §06.2/§06.2B + compiler-side §09/§10/§11).
  • [TPR-06-R7-005-codex][medium] §06:441-449 final gate lacked per-owner preflight counts. Fix applied: new - [ ] in §06.4.1 enumerating per-§09/§10/§11 preflight cargo stf commands for localization.
  • [TPR-06-R7-006-codex][medium] validators/mod.rs:95-100 site_from_expr_kind classifies every Lambda-sited Tag::Var as LambdaParam, emitting the closure-parameter wording for return-type vars too — violates §06.1 spec bullet at :151 (“ExprKind::Lambda { params, .. } where a parameter has unresolved Tag::Var”). Discriminating return-vs-param at the error site requires the validator to inspect which Var position triggered the report. This is a §06.1-scope gap (shipped code does not match shipped §06.1 prose). Tracked here as a residual §06.1 refinement; fix after §09/§10/§11 land so the validator refinement can be tested against a stable body-inference surface. Anchor: §07.5 “R7-006 validator refinement” (concrete subsection added 2026-04-23 TPR Round 0 per codex F2 + gemini F1 agreement).
  • [TPR-06-R7-007-codex+gemini][medium] §09:19 claims six §09-owned ledger files but success_criteria line explicitly enumerates only four. Fix applied (Step 5 editor 2026-04-23): section-09-body-inference-gaps.md success_criteria updated to split the 6 files into 4 primary (§09 closes directly so file compiles WITHOUT §06.2C annotation) + 2 helper-removal (§09.3 closes underlying gap + helpers removed via §07.2).
  • [TPR-06-R7-008-codex][medium] section-07-closeout.md still references the pre-rename plan path empty-container-typeck-phase-contract. Fix applied (Step 5 editor 2026-04-23): stale live refs at schema-gate path (previously line 154) and bug-tracker pointer (previously line 205) fixed to typeck-inference-completeness; sweep regex now accepts BOTH pre- and post-rename tokens (belt-and-suspenders). Historical refs in §07.R review-block preserved (they reference the OLD plan path in the context of past TPR findings — rewriting them would rewrite history).
  • [TPR-06-R7-009-gemini][medium] §11.1 lacks a runtime debug_assert! confirming §09 BD-2 passes have completed before default_unbound_vars_from_empty_literals fires. Fix applied (Step 5 editor 2026-04-23): section-11-inference-fallback.md §11.1.2 Design adds engine.body_inference_complete flag + debug_assert! at default_unbound_vars_from_empty_literals / default_unbound_vars_in_scope entry; section-11.1.3 Implementation adds regression-guard test test_debug_assert_fires_on_pass_order_inversion; 00-overview.md §Design Principle 3 extended to make the code-level enforcement explicit.
  • [TPR-06-R7-010-codex][medium] infer_some(inner) uses inner_ty from infer_expr(inner) — no fresh var introduced at Some level. If §11.1 adds ExprKind::Some(_) as a defaulting root, collect_unbound_reachable_vars walks into inner_ty and defaults legitimately pending payload vars. Fix applied (Step 5 editor 2026-04-23): section-11-inference-fallback.md §11.1.2 Design EXCLUDES ExprKind::Some from is_defaulting_root per introducer-only rule; §11.1 success_criteria replaced the “scoped-descendants on Some(x) constrained payload” bullet with an explicit “Some is NOT a defaulting root” bullet + negative regression test test_some_never_defaulting_root_when_payload_unbound.
  • [TPR-06-R7-011-codex][medium] defaulting walks every Unbound var reachable from a defaulting-root expression — load-bearing assumption that §09 BD-2 has run first. Fix applied (Step 5 editor 2026-04-23): subsumed by R7-009’s debug_assert + R7-010’s introducer-only predicate. The load-bearing invariant is now explicit in §11.1’s Design block (“Load-bearing pass-ordering invariant (R7-009 + R7-011)”) AND in 00-overview.md §Design Principle 3, enforced at two layers (call-site ordering + runtime debug_assert).

06.N Completion Checklist

  • 06.1 complete — E2005 message wording finalized; ExprKind-dispatched message + span-specific tests pass in check/validators/tests.rs.
  • 06.2 complete — empty-literal class cleared; every checkbox in §06.2 marked [x]; tests/spec/types/empty_literals/ untouched and still green. Sub-agent investigation 2026-04-23 confirmed zero mechanical annotations required because §03’s default_unbound_vars_from_empty_literals pre-pass already defaults unconstrained empty-literal Tag::Vars to Idx::NEVER before PC-2 validation fires. All 31 file checkboxes verified clean (regex false-positive OR already-annotated OR defaulting-covered).
  • 06.2B complete — lambda-parameter class cleared; ~110 lambda-param annotation sites applied across 15 files (typed_lambda form per spec grammar.ebnf:550-553). All 15 touched files verified green locally. Residual file errors after §06.2B are the polymorphic-constructor class now owned by §06.2C.
  • 06.3 complete — library/std/ sweep done; zero annotations needed, baseline preserved. cargo b --package oric clean; no stdlib E2005 sites identified by the three discovery regexes.
  • 06.4.1 completetimeout 150 ./test-all.sh green; delta vs §03.N baseline = +844 passed, −844 failed.
  • 06.4.2 complete — all five directory spot checks green.
  • 06.4.3 completediagnostics/state.sh show --json reports known_failing_count: 0, known_failing_files: []; §03.N Known Failing Tests table strike-through update landed.
  • 06.4.4 complete — §04’s codegen diagnostic returns zero hits on tests/spec/; §07 handoff checklist satisfied (no BUG-04-074|empty-container-typeck markers in spec/stdlib edits).
  • /tpr-review Round 6 converged clean (historical) — 3 dual-source rounds (commits 52aa673d, 7caff2b9); all 3 verified findings fixed inline; remaining codex claims dropped at §4 verification. Details in §06.R Round 6 block.
  • /tpr-review Round 7 converged clean — current /review-plan Step 6 pass on the post-2026-04-23 scope expansion (editor’s edits + post-edit convergence). Must reach clean before §06 close-out.
  • /impl-hygiene-review passed — no prose violations in this file; no mechanical annotations in tests/spec/types/empty_literals/.
  • /improve-tooling sweep — any regex or discovery-command limitations hit during §06.2 / §06.2B surfaced as tooling improvements. Concrete tooling anchor (2026-04-23 dual-source AGREEMENT): diagnostics/state.sh clear-known-failing --plan <name> subcommand eliminates the §06.4.3 manual JSON edit drift hazard. File via /improve-tooling at close-out; block §06 completion on either the subcommand shipping OR a documented decision to keep the manual path.
  • Plan sync — this section’s frontmatter statuscomplete; 00-overview.md Quick Reference table entry updated to Complete; index.md section 06 status updated; 00-overview.md Mission Success Criteria checkboxes for E2005/annotation/state.sh-cache-clear satisfied.

Exit criteria: Full test suite green (test-all.sh, release, clippy, llvm-test). No unannotated empty lists AND no unannotated closure parameters in test or stdlib code that would surprise users after the fix lands. diagnostics/state.sh cache reports zero known-failing files. §03.N ledger is updated in place to reflect remediation. §04’s codegen-time assertion never fires on any program in tests/spec/. Section 07 may begin.