60%

Intelligence Reconnaissance

Queries run 2026-04-23 (Phase 2 Pass 3 + 2.6B consultation):

  • scripts/intel-query.sh --human file-symbols "body_finalize" --repo ori — inventory the existing defaulting pre-pass. Result: default_unbound_vars_from_empty_literals + default_unbound_vars_in_scope + helpers is_empty_collection_literal + collect_unbound_reachable_vars all live in body_finalize/mod.rs (267 lines). 4 call sites in check/bodies/{functions,impls}.rs.
  • scripts/intel-query.sh --human similar "never_type_fallback" --repo rust --limit 10 — surface Rust’s complete fallback algorithm (rustc_hir_typeck/src/fallback.rs:22-400). Uses coercion-graph DFS from diverging roots.
  • scripts/intel-query.sh --human callers "infer_none" --repo ori — single call site from infer_expr in mod.rs. Same for infer_ok/infer_err/infer_some.
  • Prior /tp-help consultation (2026-04-23 round 1) and /tpr-review Phase 2.6B confirm: Ori’s simple predicate-extension approach is sufficient; coercion-graph port is unwarranted complexity given Ori’s invariance and lack of subtyping.

Results summary (≤500 chars) [ori]: is_empty_collection_literal matches 4 ExprKind variants — List, ListWithSpread, Map, MapWithSpread. collect_unbound_reachable_vars walks type structure via Pool::visit_children, collecting VarState::Unbound vars not in the exempt set (from FunctionSig.scheme_var_ids). Substitution via substitute_in_pool covers expr_types + param_types + return_type in one pass; defense-in-depth via direct VarState::Link { target: Idx::NEVER } assignment. §11.1 extends the predicate to 3 additional ExprKind variants: None, Ok, Err (Some INTENTIONALLY EXCLUDED per R7-010 introducer-only rule — see §11.1.3 Design for the infer_some vs infer_none/infer_ok/infer_err asymmetry rationale). The collector’s existing behavior (walks Option<Var> / Result<T, Var> / Result<Var, E> and collects Var children) MUST be restricted to the introducer slot for Ok/Err per R7-010 (cured by §11.1.3 STAGE 3: DefaultingClassification::IntroducerSlot(path) + collector walk only the introducer slot — Var_err for Ok / Var_ok for Err — NOT the full Result<inner_ty, Var> tree, which would default unrelated payload generics and silently mask legitimate E2005). The entry predicate extension is necessary but not sufficient.


Section 11: Inference Fallback for Unconstrained Bottom-Instantiable Roots

Goal: Close the last root-cause class of the §06.2C 28-file ledger — unconstrained None/Ok(x)/Err(x) leaking Tag::Var to PC-2 validation (Some(x) is INTENTIONALLY EXCLUDED — owned by §09.3 BD-2 propagation; cascades only through inner defaulting roots per R7-010). Extends the existing empty-literal defaulting pre-pass with constructor root predicates. Ships silent fallback per Rust 2024 Edition direction (both reviewers 2.6B: NO lint).

Depends on: §03 (the existing defaulting pre-pass §11.1 extends), §09 (MUST complete first — landing §11.1 before §09 would mask §09 BD-2 failures with fallback, per both reviewers 2.6B).

Sequencing rule: §11.1 MUST run AFTER §09.1 + §09.2 + §09.3 + §09.4 + §10.0 + §10.1 + §10.2 all complete. The pipeline ordering in check/bodies/{functions,impls}.rs (inference → default_unbound_vars_from_empty_literalsnormalize_body_generalized_to_bound_varvalidate_body_types) ensures that any vars §09 BD-2 would have pinned are already pinned before §11.1’s defaulting pass runs. Landing §11.1 first without §09 in place would silently default vars that BD-2 should have constrained — inverting correctness.


11.1 Polymorphic-constructor defaulting — extend predicate

Goal: Extend is_empty_collection_literal at body_finalize/mod.rs:225-233 to also match ExprKind::None, ExprKind::Ok(inner), ExprKind::Err(inner). Rename to is_defaulting_root for accuracy. ExprKind::Some(inner) is EXCLUDED from the defaulting-root predicate per TPR Round 7 R7-010 (codex finding, editor-confirmed via infer/expr/constructors.rs:40-49 source inspection: infer_some uses inner_ty = infer_expr(inner) — NOT fresh_var() — so Some never introduces a root-level unbound payload var; the only Tag::Var reachable from a Some(x) expression is whatever inner itself introduces, which is owned by its own defaulting-root classification, not by Some). Adding Some to the root predicate would cause collect_unbound_reachable_vars to walk into inner_ty and aggressively default payload vars that §09.3’s check_some BD-2 gate was supposed to pin — inverting correctness. No changes to collect_unbound_reachable_vars — the existing tree-walking behavior works correctly for Option<Var> / Result<T, Var> / Result<Var, E> shapes produced by None / Ok(x) / Err(x).

Scoped-descendants invariant (Codex 2.6B + R7-010 refinement): defaulting-root classification is introducer-only — a constructor is a defaulting root ONLY if it introduces a fresh var at the constructor level that no other call site will constrain. Per constructors.rs:10-55:

  • infer_noneOption<fresh_var> — fresh var INTRODUCED at None, defaulting-root. ✓
  • infer_ok(inner)Result<inner_ty, fresh_var> — err-slot fresh var INTRODUCED at Ok(x), defaulting-root. ✓
  • infer_err(inner)Result<fresh_var, inner_ty> — ok-slot fresh var INTRODUCED at Err(e), defaulting-root. ✓
  • infer_some(inner)Option<inner_ty> — NO fresh var introduced at Some level; inner_ty comes from infer_expr(inner). NOT a defaulting root. For Some([]), the List([]) inner expression IS a defaulting root (its own classification); the cascade happens through the inner’s classification, not through Some’s. Tests test_naked_some_with_empty_list_cascades_defaulting verify the cascade works via inner classification.

Load-bearing pass-ordering invariant (R7-009 + R7-011): §11.1 defaulting assumes §09 BD-2 propagation has run and every var §09 would have pinned is already VarState::Link (not VarState::Unbound) at defaulting time. This invariant is enforced at two layers:

  1. Code-location orderingcheck/bodies/{functions,impls}.rs call default_unbound_vars_from_empty_literals AFTER InferEngine body inference (which includes §09.1/§09.3/§09.4’s check_expr BD-2 gates) and BEFORE validate_body_types. See call sites: compiler/ori_types/src/check/bodies/functions.rs:134,256 + impls.rs:203,347.
  2. Runtime debug-assertbody_finalize/mod.rs adds a debug_assert! at the entry of default_unbound_vars_from_empty_literals / default_unbound_vars_in_scope confirming that any expression ExprId marked for defaulting has had its body-inference pass complete. Shape (concept-only assertion text, NO plan-path / rule-file pointer per impl-hygiene.md §Comments — External pointers — spec only C-B11): debug_assert!(engine.body_inference_complete, "body_inference_complete invariant violated — defaulting called before body inference finished");. body_inference_complete is a new bool field on InferEngine (alongside existing self_type / capability / loop_break_stack scoped fields per typeck.md §EN-1 table), initialized false at InferEngine creation (per-body ephemeral lifecycle per check/bodies/functions.rs:106-110 create_engine_with_env; NO save-restore in scope helpers — the engine is created INSIDE the with_function_scope / with_impl_scope closure with no prior state to save), set to true at end of body inference at exactly one site per body-check call path (after the top-level check_expr on the body root returns), checked here. Turns pass-order inversion from silent masking bug into panic in debug builds.

Why the debug_assert is load-bearing: prose-only ordering notes in a plan file are invisible to a future refactor. If someone moves the defaulting call site earlier in the pipeline (e.g., attempts to run it inside check_expr for perf), the silent masking manifests as green tests + wrong semantics (vars that BD-2 should have pinned get defaulted to Never). The debug_assert surfaces the inversion at the exact point of violation, with a pointer to this overview rule.

11.1.1 Discovery + root cause verification

  • Re-read compiler_repo/compiler/ori_types/src/infer/body_finalize/mod.rs:42-267 — confirm the current flow: iterate expr_types, gate on is_empty_collection_literal, walk via collect_unbound_reachable_vars, substitute via substitute_in_pool, link vars in pool.
  • Confirm is_empty_collection_literal at lines 225-233 matches only 4 ExprKind variants: List(range) if empty, ListWithSpread(range) if empty, Map(range) if empty, MapWithSpread(range) if empty.
  • Confirm infer_none/infer_ok/infer_err/infer_some at infer/expr/constructors.rs:10-55 allocate fresh_var() for unconstrained slots: infer_noneOption<fresh_var>; infer_okResult<inner_ty, fresh_var>; infer_errResult<fresh_var, inner_ty>; infer_someOption<inner_ty> (inner_ty comes from infer_expr(inner), NOT fresh).
  • Verify collect_unbound_reachable_vars at lines 241-267 correctly walks Option<Var> via Pool::visit_childrenOption is a single-child tag; visit_children yields the inner.
  • Verify the scoped-descendants invariant: test that Some(x) with constrained x does NOT default any var. Example: let y: int = 42; let z = Some(y);z: Option<int>; no Tag::Var to default.
  • Write TDD matrix BEFORE implementation:
    • Positive test_naked_none_defaults_to_option_neverlet x = None; x compiles clean; x: Option<Never>.
    • Positive test_naked_ok_with_payload_defaults_err_to_neverlet r = Ok(42); r compiles clean; r: Result<int, Never>.
    • Positive test_naked_err_with_payload_defaults_ok_to_neverlet r = Err(\"boom\"); r compiles clean; r: Result<Never, str>.
    • Positive test_naked_some_with_empty_list_cascades_defaultinglet o = Some([]) defaults outer Some’s wrap + inner List<Never>.
    • Scoped-descendants test_some_with_constrained_payload_does_not_default_unrelated_vars — fixture where Some(x) has x constrained elsewhere; Some is not a defaulting root because its payload var is Link, not Unbound.
    • Negative test_non_constructor_root_does_not_default — random unbound Tag::Var from a different expression (not reachable from a defaulting root) continues to fire E2005.
    • Interaction with §09 test_ok_under_check_result_does_not_default_because_bd2_pinnedlet r: Result<int, str> = Ok(42) has §09.3 BD-2 propagation pin the err var to str; §11.1 finds no Unbound var to default. Regression guard for §09/§11 ordering.
    • Regression guard test_empty_literals_corpus_unchanged — run tests/spec/types/empty_literals/ pre/post §11.1; identical pass/fail counts (21 files, 0 failures each).

11.1.2 Design

Fix shape:

  1. Rename is_empty_collection_literalis_defaulting_root (or similar; name choice TBD but should NOT imply “empty” since Ok(x)/Err(x) may have non-empty payloads).
  2. Extend the match at lines 225-233 — Some is INTENTIONALLY OMITTED per R7-010 introducer-only rule above:
    fn is_defaulting_root(arena: &ExprArena, kind: &ExprKind) -> bool {
        match kind {
            ExprKind::List(range) => arena.get_expr_list(*range).is_empty(),
            ExprKind::ListWithSpread(range) => arena.get_list_elements(*range).is_empty(),
            ExprKind::Map(range) => arena.get_map_entries(*range).is_empty(),
            ExprKind::MapWithSpread(range) => arena.get_map_elements(*range).is_empty(),
            // §11.1 additions — constructors that INTRODUCE a fresh var at the
            // constructor level (per introducer-only rule, R7-010 codex):
            ExprKind::None => true,   // Option<fresh_var> introduced by infer_none
            ExprKind::Ok(_) => true,  // Result<inner_ty, fresh_var> — err slot introduced by infer_ok
            ExprKind::Err(_) => true, // Result<fresh_var, inner_ty> — ok slot introduced by infer_err
            // ExprKind::Some INTENTIONALLY OMITTED — infer_some uses inner_ty
            // from infer_expr(inner), not fresh_var; no root-level var is
            // introduced at Some, so adding it here would default payload vars
            // that §09.3's check_some BD-2 gate should have pinned.
            _ => false,
        }
    }
  3. Introducer-only walk for Ok/Err — REQUIRED (cures TPR Round 7 gemini F1 Critical, payload-contamination): collect_unbound_reachable_vars MUST walk ONLY the introducer slot for Ok(inner) / Err(inner), NOT the full Result<inner_ty, Var_err> / Result<Var_ok, inner_ty> tree. Today Pool::visit_children recurses into inner_ty and would default any unbound payload Tag::Var (e.g., a generic T from foo<T>() inside Ok(foo<T>())) to Idx::NEVER, silently masking the legitimate E2005 the validator should fire on the unconstrained payload generic. The introducer-only invariant from R7-010 (“Some excluded because no fresh var introduced at Some level”) REQUIRES symmetric treatment on the Ok/Err side — the err-slot fresh var for Ok / ok-slot fresh var for Err is the introducer; payload vars (whatever inner_ty produces) belong to the inner expression’s own defaulting-root classification. Cure: extend the predicate to return a DefaultingSlot enum naming WHICH slot is the introducer (Some=None, None=Inner, Ok=ErrSlot, Err=OkSlot, List=Elem, Map=Entry, ListWithSpread=Elem, MapWithSpread=Entry), then have the collector walk ONLY that slot’s Idx vs the full type tree. Test test_ok_with_unbound_payload_generic_does_not_default_payload (STAGE 4h above) is the regression guard.
  4. NO changes to substitute_in_pool or the defense-in-depth VarState::Link { target: Idx::NEVER } assignment — existing logic handles the additional vars.
  5. Add body_inference_complete: bool field to InferEngine — MANDATORY (cures TPR Round 7 codex F1 + opencode F1 + gemini F3 convergent Critical AND BS-11-002 design pivot from save-restore to per-body-path single-assignment; cures §11.R-R3-004 SSOT concern via single-lifecycle-home discipline; engine.body_inference_complete is NOT optional cosmetic guard). Field lives on InferEngine per typeck.md §EN-1 alongside scoped state (current_function, current_impl_self, loop_break_stack). Lifecycle (DESIGN-PIVOTED from save-restore per BS-11-002 code anchor compiler/ori_types/src/check/bodies/functions.rs:106-110): InferEngine is created INSIDE the with_function_scope / with_impl_scope closure via create_engine_with_env — engine state is per-body ephemeral; the scope helpers do NOT own the engine, so SG-1 / SG-2 save-restore pattern does NOT apply to engine fields. Cure: initialize body_inference_complete: false at InferEngine::new (engine constructor; default value at struct level); set to true at EXACTLY ONE site per body-check call path (top-level body-check functions in check/bodies/{functions,impls}.rs), AFTER top-level check_expr on body root returns AND BEFORE default_unbound_vars_from_empty_literals is called. Four assignment sites total, matching the four body-check entry points (see §11.1.3 STAGE 2 checklist). default_unbound_vars_from_empty_literals AND default_unbound_vars_in_scope open with debug_assert!(self.body_inference_complete, "body_inference_complete invariant violated — defaulting called before body inference finished"). The assertion text is concept-only — NO plan-path / rule-file reference per impl-hygiene.md §Comments — External pointers — spec only C-B11. SSOT verification: grep -rn "body_inference_complete = true" compiler/ori_types/src/ returns EXACTLY four matches all under check/bodies/{functions,impls}.rs — any additional site is a §11.R-R3-004 SSOT violation.
  6. Rename is_empty_collection_literalis_defaulting_root (cures TPR Round 7 opencode F3 Minor). Function at body_finalize/mod.rs:243 still carries the misleading name even though it now matches non-empty constructor variants (Ok(x) / Err(x) carry payloads). One call site within body_finalize/mod.rs:92; verified via scripts/intel-query.sh callers is_empty_collection_literal --repo ori — zero external callers. Rename is mechanical, single commit, lands alongside STAGE 2 invariant work.

Why this simple extension is sufficient (both reviewers 2.6B):

  • Ori has no subtyping (only Never <: T). Rust’s coercion-graph DFS exists to distinguish coercion edges from unification edges — Ori’s unification-only model collapses that distinction.
  • Ori runs defaulting AFTER body-exit inference (including §09 BD-2 propagations). Any var constrained by propagation is no longer Unbound at defaulting time.
  • The existing exempt set (FunctionSig.scheme_var_ids) handles the “legitimately polymorphic” case — top-level generic function parameters are exempt from defaulting.

Ordering constraint reinforcement: check/bodies/{functions,impls}.rs call the defaulting pass AFTER InferEngine body inference and BEFORE validate_body_types. §09 extensions live inside inference (in check_expr). So §09 BD-2 propagations pin vars BEFORE §11.1’s defaulting walks. Inverting this order (defaulting before §09) would break correctness — land §11.1 ONLY after all §09 subsections are complete.

11.1.3 Implementation

Provisional marker (cures BS-11-003 predecessor-ordering gate): STAGE 2 through STAGE 5 land BEFORE §09.6 / §09.7 / §10.1 / §10.2 are status: complete + reviewed: true. Per pass-ordering invariant (Design Principle §11.1 Load-bearing pass-ordering invariant R7-009 + R7-011), §11.1 defaulting assumes §09 BD-2 propagation has pinned every var §09 would constrain. Until predecessor §09.6 / §09.7 / §10.1 / §10.2 complete + their /tpr-review lands clean, ALL of §11.1’s STAGE 2-5 work is PROVISIONAL: any predicate cell that later turns out to mask a §09 BD-2 failure (legitimate var pinned to Never that should have been pinned to a concrete type) MUST be reverted at predecessor close. Recovery path if a predecessor surfaces a mask: §11.1.4 close-out re-runs STAGE 4 TDD matrix + STAGE 5 spec sweep after each predecessor flips complete + reviewed: true; any divergence in the matrix vs the provisional-landing baseline (scripts/state.sh test-snapshot at commit of STAGE 5 close) is a §11.R regression and MUST be cured before §11.N gate evaluates. Frontmatter subsection_depends_on: {"11.N": ["09.6", "09.7", "10.1", "10.2"]} enforces the close-gate; this paragraph documents the work-product-provisional discipline that holds before close.

STAGE 1 — Mechanical rename (single commit; cures opencode F3 Minor):

  • Rename is_empty_collection_literalis_defaulting_root at compiler/ori_types/src/infer/body_finalize/mod.rs:243.
  • Update single call site at compiler/ori_types/src/infer/body_finalize/mod.rs:92.
  • Verify zero external callers via scripts/intel-query.sh callers is_empty_collection_literal --repo ori (post-rename, both old + new names) — old returns 0, new returns 1 (internal call site only).
  • Commit: refactor(ori_types): rename is_empty_collection_literal -> is_defaulting_root.

STAGE 2 — body_inference_complete invariant (single commit; cures convergent Critical: codex F1 + opencode F1 + gemini F3 AND BS-11-002 design pivot AND §11.R-R3-004 SSOT centralization):

  • Add body_inference_complete: bool field to InferEngine in compiler/ori_types/src/infer/mod.rs:83 (alongside loop_break_stack and capability scoped state per typeck.md §EN-1). Initialize false in InferEngine::new (engine constructor; default value at struct-level construction — no save-restore needed because engine is per-body ephemeral per compiler/ori_types/src/check/bodies/functions.rs:106-110 create_engine_with_env call).
  • DO NOT add save-restore to with_function_scope / with_impl_scope. The scope helpers do not own InferEngine lifecycle (engine is created INSIDE the closure they pass, lives only for one body); SG-1 / SG-2 save-restore pattern in typeck.md applies to ModuleChecker fields, NOT to ephemeral-engine fields. Cures BS-11-002 (with_function_scope save-restore is structurally unimplementable for engine fields) AND §11.R-R3-004 (SSOT centralization in body-check paths, not split across scope helpers).
  • Set engine.body_inference_complete = true at end of body inference in EACH of the four top-level body-check call paths (after check_expr on body root returns, BEFORE default_unbound_vars_from_empty_literals is called). EXACTLY one assignment per path; four assignments total (SSOT verification step below):
    • check_function at compiler/ori_types/src/check/bodies/functions.rs (Pass 2 per typeck.md §CK-1).
    • check_test at compiler/ori_types/src/check/bodies/functions.rs (Pass 3).
    • check_impl_method at compiler/ori_types/src/check/bodies/impls.rs:215 (Pass 4).
    • check_def_impl_method at compiler/ori_types/src/check/bodies/impls.rs:468 (Pass 5).
  • Add debug_assert!(self.body_inference_complete, "body_inference_complete invariant violated — defaulting called before body inference finished") at line 1 of default_unbound_vars_from_empty_literals (compiler/ori_types/src/infer/body_finalize/mod.rs:42).
  • Add same debug_assert! at line 1 of default_unbound_vars_in_scope (compiler/ori_types/src/infer/body_finalize/mod.rs:76).
  • Verify assertion text is concept-only — NO plans/... / bug-tracker/... / .claude/... / §... / Round N / rule-file references per impl-hygiene.md §Comments — External pointers — spec only C-B11 (PUBLIC_LEAK:wrapper-path-reference Critical at review). Allowed: spec citation (Spec: Clause N.M), open-bug ref (BUG-XX-NNN).
  • SSOT verification: grep -rn "body_inference_complete = true" compiler/ori_types/src/ returns EXACTLY four matches all under check/bodies/{functions,impls}.rs. Any additional site (e.g., inside with_function_scope, inside with_impl_scope, inside an infer/* module) is a §11.R-R3-004 SSOT violation — cure by removing the extra site and confirming the lifecycle stays single-homed in body-check paths.
  • Commit: feat(ori_types): body_inference_complete invariant guards defaulting pass order.

STAGE 3 — Ok/Err introducer-only walk (single commit; cures gemini F1 Critical, payload-contamination):

  • Extend predicate return value from bool to DefaultingClassification enum in body_finalize/mod.rs. Variants: NotARoot, EmptyLiteralRoot, IntroducerSlot(slot_path: Vec<u32>). Slot path indices for the four polymorphic-constructor variants:
    • ExprKind::None — slot path [0] (Option’s single child = the introduced var)
    • ExprKind::Ok(_) — slot path [1] (Result’s err slot, index 1 — the introduced var)
    • ExprKind::Err(_) — slot path [0] (Result’s ok slot, index 0 — the introduced var)
    • Empty-literal variants (List/Map/ListWithSpread/MapWithSpread) — slot path [0] (List/Set child) or [0, 1] (Map K, V — full type tree since walking entries is the existing established behavior).
  • Update default_unbound_vars_in_scope (body_finalize/mod.rs:76) match-arm: on IntroducerSlot(path), walk ONLY the slot at the given projection of the expression’s type, NOT the full type tree. On EmptyLiteralRoot, retain existing full-tree walk.
  • Verify scoped-descendants behavior preserved: cascading defaulting through Some([]) STILL works because the inner [] expression’s own classification independently fires EmptyLiteralRoot against its [Var_elem] type (no Some-level introducer needed).
  • Commit: fix(ori_types): introducer-only defaulting walk for Ok/Err payload isolation.

STAGE 4 — TDD matrix (single commit; cures opencode F2 Major phantom-deliverable):

  • Create compiler/ori_types/src/infer/body_finalize/tests.rs (file does not exist today; compiler.md §Testing “tests in sibling tests.rs files” — sibling to mod.rs).
  • Add #[cfg(test)] mod tests; declaration in compiler/ori_types/src/infer/body_finalize/mod.rs.
  • Implement matrix cells (one #[test] per cell):
    • test_naked_none_defaults_to_option_neverNone with no annotation → Option<Never>.
    • test_let_x_eq_none_types_as_option_neverlet x = None; xx: Option<Never>.
    • test_let_r_eq_ok_42_types_as_result_int_neverOk(42)Result<int, Never>.
    • test_let_r_eq_err_boom_types_as_result_never_strErr("boom")Result<Never, str>.
    • test_some_never_defaulting_root_when_payload_unbound (negative — Some(x) NOT a root; is_defaulting_root(Some) returns NotARoot).
    • test_naked_some_with_empty_list_cascades_defaulting (positive — Some([]) defaults inner via inner’s own root classification).
    • test_debug_assert_fires_on_pass_order_inversion — invoke pre-pass with body_inference_complete=false; verify panic in debug build with the expected concept-only message.
    • test_ok_with_unbound_payload_generic_does_not_default_payload (STAGE 3 regression guard — Ok(foo<T>()) with unbound T in inner-call’s return; payload Var_payload survives + fires E2005, NOT silently defaulted).
  • Run timeout 150 cargo test -p ori_types body_finalize — all pass.
  • Commit: test(ori_types): body_finalize defaulting matrix.

STAGE 5 — Spec test + regression guards (cures BS-11-005 by adding Ok/Err spec coverage symmetric with None):

  • Add Ori spec test none_defaults_to_option_never.ori at compiler_repo/tests/spec/types/empty_literals/ for assert(cond: !is_some(opt: None)) — verify compiles + runs green. Requires use std.testing { assert } per ori-syntax.md §Prelude.
  • Add Ori spec test ok_defaults_err_to_never.ori at compiler_repo/tests/spec/types/empty_literals/ covering let r = Ok(42); assert(cond: is_ok(result: r)) — exercises the AOT-boundary user-facing deliverable for unannotated Ok(x) defaulting to Result<int, Never> (cures BS-11-005 single-reviewer gap: Rust unit tests alone do not catch AOT pipeline regressions on this user-facing path).
  • Add Ori spec test err_defaults_ok_to_never.ori at compiler_repo/tests/spec/types/empty_literals/ covering let r = Err("boom"); assert(cond: is_err(result: r)) — symmetric AOT-boundary regression guard for Result<Never, str>.
  • Run timeout 150 cargo stf tests/spec/types/empty_literals — identical pre/post pass/fail counts on the legacy 21 files (regression guard) PLUS 3 new files green (the three added above).
  • Matrix verification (whole test sweep — verify each cell hits expected outcome):
    • Constructors: None, Some(x), Ok(x), Err(x).
    • Payloads: literal, constrained var, unconstrained var, empty-literal, nested constructor.
    • Outer contexts: no annotation (defaulting applies), LHS type annotation (§09.3 BD-2 pins vars; no defaulting), function argument (parameter type pins), function return (return type pins).
  • Verify timeout 150 cargo st tests/ green (no spec-test regression).
  • Verify debug + release parity on the new matrix cells.
  • Verify timeout 150 ./test-all.sh — final regression run validating failed: 0 target for typeck-scope tests. AOT-scope tests transitively blocked by BUG-04-090 (frontmatter comment per §11.R-R1-002); treat AOT failures as cures_failures: BUG-04-090 (NOT §11 regression).

11.1.4 Close §11.1

  • All §11.1.3 STAGE 1–5 checkboxes marked [x].
  • Predecessor revalidation gate (cures BS-11-003): for each of §09.6 / §09.7 / §10.1 / §10.2 as they flip complete + reviewed: true, re-run STAGE 4 TDD matrix (timeout 150 cargo test -p ori_types body_finalize) AND STAGE 5 spec sweep (timeout 150 cargo stf tests/spec/types/empty_literals); compare against the provisional-landing baseline snapshot captured at STAGE 5 close commit. Any matrix-cell delta where a baseline-passing cell now fails (predecessor pinned a var §11.1 had defaulted to Never) is a §11.R regression — file and cure before §11.N evaluates.
  • timeout 150 diagnostics/dual-exec-verify.sh on §11-touched files — zero divergences.
  • tests/spec/types/empty_literals/ corpus identical pre/post §11.1 — regression guard.
  • /tpr-review on §11.1 diff → clean across codex + gemini + opencode.
  • /impl-hygiene-review on §11.1 diff → clean.
  • /improve-tooling retrospective — any defaulting-pre-pass generalization lessons.
  • /sync-claude retrospective — update typeck.md §PC-2 “End-of-body defaulting pre-pass” description to note the extension AND the body_inference_complete invariant.
  • Frontmatter 11.1 status: complete.

11.R Third Party Review Findings

Round 7 findings (TPR Round 7 + 2026-05-15 /review-plan editor cross-reviewer synthesis). All cures absorbed inline as STAGE-numbered - [ ] items in §11.1.3 above per feedback_inline_fix_over_filing_more_bugs — every cure has concrete anchor.

  • §11.R-R3-003 — STRUCTURE:exit-reason-handler-dead cures_failures_on_blocked_bug (codex R3 F2, Major, CURED inline by BS-11-004) — §11.N autopilot routing block invented exit reason cures_failures_on_blocked_bug not in canonical /tpr-review exit_reason enum per tpr-review/SKILL.md §1.7 + scripts/plan_corpus/exit_reasons.py CANONICAL_EXIT_REASONS. Also invented blocked_on_predecessor and subsection_pending / section_close_pending cells outside the canonical set. CURE applied: rewrote §11.N routing table to use ONLY canonical exit_reasons (subsection_pending, finding_outstanding, cap_reached_max_rounds, predecessor_incomplete, section_complete); BUG-04-090 transitive blocker now represented via cures_failures: [{"test_id", "kind": "aot", "until_section": "BUG-04-090"}] payload field per feedback_plan_cures_failures_linkage.md, NOT via a section-local exit_reason invention. ANCHOR: §11.N “Autopilot Routing” table rewrite (post-edit).
  • §11.R-R3-004 — PLAN_COHERENCE_DRIFT: body_inference_complete flag lifecycle (codex R3 F3 + BS-11-002, High, CURED inline) — Original STAGE 2 design prescribed save-restore in BOTH with_function_scope + with_impl_scope (split lifecycle across two scope helpers, SSOT violation per impl-hygiene.md §SSOT). BS-11-002 (gemini + opencode) added the structural blocker: InferEngine is created INSIDE the with_function_scope closure via create_engine_with_env at compiler/ori_types/src/check/bodies/functions.rs:106-110; the scope helpers do not own engine lifecycle, so SG-1 / SG-2 save-restore on engine fields is structurally unimplementable. CURE applied: rewrote §11.1.2 Design item 5 + §11.1.3 STAGE 2 to (a) initialize body_inference_complete: false at InferEngine::new (engine constructor, struct-level default), (b) set true at exactly four sites — one per body-check call path (check_function, check_test, check_impl_method, check_def_impl_method), (c) explicitly forbid save-restore in with_function_scope / with_impl_scope, (d) SSOT verification via grep -rn "body_inference_complete = true" returning exactly four matches under check/bodies/. ANCHOR: §11.1.2 Design item 5 + §11.1.3 STAGE 2 (post-edit) + RESUME POINTER STAGE 2 (post-edit).
  • §11.R-BS-11-001 — Mission-fit drift on Some defaulting semantics (codex Step 4 blind-spot, Medium, CURED inline) — Umbrella 00-overview.md:132 + index :217 enumerated None/Ok/Err/Some as defaulting roots, contradicting target’s R7-010 “Some INTENTIONALLY EXCLUDED” semantics + actual code (body_finalize/mod.rs:249 matches None | Ok(_) | Err(_) only; infer_some at infer/expr/constructors.rs:48 uses infer_expr(inner) not fresh_var). CURE applied: reworded 00-overview.md:132 + :190 + :310 + index.md:217 to enumerate None/Ok/Err as defaulting roots with explicit Some-cascade-via-inner note. Negative/cascade Some checks already in target success_criteria + STAGE 4 matrix (lines 85, 300-301) per R7-010. ANCHOR: 00-overview.md + index.md (post-edit cohesion edits).
  • §11.R-BS-11-002 — body_inference_complete STAGE 2 save-restore design structurally unimplementable (gemini + opencode Step 4 blind-spot, High, CURED inline by §11.R-R3-004 design pivot) — See §11.R-R3-004 above; cure absorbed into same rewrite (engine is ephemeral inside scope-closure, so save-restore in scope helpers cannot apply to engine fields). ANCHOR: §11.1.2 Design item 5 + §11.1.3 STAGE 2 (post-edit).
  • §11.R-BS-11-003 — Predecessor ordering invariant stated but not gated (codex Step 4 blind-spot, Medium, CURED inline) — §11 prose declared “§11.1 MUST run AFTER all §09 BD-2 propagations” but frontmatter only gated §11.N close on predecessors; STAGE 2-5 could land while §09.6 / §09.7 / §10.1 / §10.2 were not-started / in-progress. CURE applied: added “Provisional marker” paragraph at top of §11.1.3 documenting the work-product-provisional discipline + added “Predecessor revalidation gate” checkbox in §11.1.4 close-out (re-runs STAGE 4 + STAGE 5 baselines after each predecessor flips complete + reviewed; any masked-pin regression files as §11.R). ANCHOR: §11.1.3 Provisional marker paragraph + §11.1.4 revalidation gate (post-edit).
  • §11.R-BS-11-005 — Test-coverage gap on Ok/Err spec integration (gemini Step 4 blind-spot, Medium, CURED inline) — STAGE 5 covered None via Ori spec test only; unannotated Ok(x) / Err(x) defaulting verified by Rust unit tests alone, leaving AOT-pipeline regression risk on the user-facing deliverable. CURE applied: added two Ori spec tests to STAGE 5 (ok_defaults_err_to_never.ori, err_defaults_ok_to_never.ori under compiler_repo/tests/spec/types/empty_literals/); updated corresponding success_criteria entries (lines 83-84 post-edit) to cite both Rust unit tests AND new Ori spec tests. ANCHOR: §11.1.3 STAGE 5 new checkboxes + success_criteria Ok/Err entries (post-edit).
  • §11.R-BS-11-006 — §11.1 status hides partial code deployment (opencode Step 4 blind-spot, Low, CURED inline) — Sections frontmatter declared §11.1 status: not-started while commit a20bc41b1 had already landed the predicate match-extension under §09.1’s BD-2 gate; cold /continue-roadmap session reading not-started would risk re-implementing shipped work. CURE applied: flipped status: not-started → partially-started in sections array + replaced anchor comment with explicit PARTIALLY-DEPLOYED: commit a20bc41b1 marker + cross-reference to §11.1.3 STAGE N OPEN checkboxes as machine-readable resume pointers. ANCHOR: sections array §11.1 entry (post-edit).
  • R7-codex-F1 (Critical, cured by §11.1.3 STAGE 2)body_inference_complete invariant declared in Design Principle 3 + §11.1.2 plan-body but ZERO production-code instances on InferEngine struct. grep body_inference_complete compiler/ori_types/src/ returned 0 hits at audit time (2026-05-15). Defaulting code at body_finalize/mod.rs:42 + :76 has no debug_assert guards. CURE: §11.1.3 STAGE 2 wires the field with per-body-path single-assignment (NO save-restore — engine is ephemeral per body), the flag-flip site per body-check call path, and the two debug_asserts. ANCHOR: §11.1.3 STAGE 2 checkboxes.
  • R7-codex-F1-sub (Critical, cured by §11.1.3 STAGE 2 + §11.1.2) — original draft assertion text embedded plan-section reference (See plans/typeck-inference-completeness/00-overview.md §Design Principle 3.) inside the runtime debug_assert panic string. Violates impl-hygiene.md §Comments — External pointers — spec only C-B11 + CLAUDE.md §Public Repo Never Leaks Private-Repo Identifiers. CURE: §11.1.2 + §11.1.3 STAGE 2 specify concept-only assertion text. ANCHOR: §11.1.2 Design Principle 3 paragraph 2; §11.1.3 STAGE 2 “Verify assertion text is concept-only”.
  • R7-codex-F2 (Critical, cured by subsection_depends_on: frontmatter) — original §11 depends_on: ["03", "09", "10"] was full-section, but §09.6/§09.7 not started + §10.1/§10.2 in-progress; predicate code already landed (a20bc41b1) under §09.1’s BD-2 pattern. CURE: subsection_depends_on: {"11.N": ["09.6", "09.7", "10.1", "10.2"]} declares that the §11.N CLOSE gate is the one blocked on §09 / §10 completion — the §11.1 predicate work itself is not. ANCHOR: frontmatter subsection_depends_on block.
  • R7-codex-F3 (Major, cured by §11.N below) — §11 lacks exit_reason / next_action mapping per /continue-roadmap autopilot consumption (§09 §760-774 template). CURE: §11.N Autopilot Routing block below mirrors §09’s template. ANCHOR: §11.N “Autopilot Routing” subsection.
  • R7-gemini-F1 (Critical, cured by §11.1.3 STAGE 3) — payload-contamination in Ok/Err defaulting: existing collect_unbound_reachable_vars calls Pool::visit_children on the full type tree, so let r = Ok(foo<T>()) with unbound T in foo’s payload defaults T to Never, silently suppressing the legitimate E2005 on the unconstrained payload generic. Violates introducer-only invariant R7-010 declared symmetrically across all polymorphic-constructor variants. CURE: §11.1.3 STAGE 3 introduces DefaultingClassification::IntroducerSlot(path) + restricts collector walk to the introducer slot. ANCHOR: §11.1.3 STAGE 3 checkboxes + STAGE 4h regression test.
  • R7-opencode-F1 (Critical, convergent with codex F1, cured by §11.1.3 STAGE 2) — same body_inference_complete missing-implementation finding from a second reviewer (independent verification). ANCHOR: §11.1.3 STAGE 2.
  • R7-opencode-F2 (Major, cured by §11.1.3 STAGE 4) — phantom deliverable: seven success_criteria items cite compiler/ori_types/src/infer/body_finalize/tests.rs which DOES NOT EXIST (ls compiler_repo/compiler/ori_types/src/infer/body_finalize/ returns only mod.rs). Tests cannot be authored against a phantom file path; either create the file OR update SCs to integration-level coverage. CURE: §11.1.3 STAGE 4 creates the sibling tests file per compiler.md §Testing convention (“tests in sibling tests.rs files”). ANCHOR: §11.1.3 STAGE 4 checkboxes.
  • R7-opencode-F3 (Minor, cured by §11.1.3 STAGE 1) — Design §11.1.2 item 1 mandates is_empty_collection_literalis_defaulting_root rename, but function at body_finalize/mod.rs:243 still carries the old (misleading) name. CURE: §11.1.3 STAGE 1 performs the mechanical rename. ANCHOR: §11.1.3 STAGE 1 checkboxes.
  • R7-gemini-F3 (Critical, convergent with codex F1 + opencode F1, cured by §11.1.3 STAGE 2) — third reviewer surfacing same body_inference_complete missing-implementation finding. ANCHOR: §11.1.3 STAGE 2.
  • §11.R-R1-001 — SCHEMA_DRIFT: blocked_by: not in PlanSectionSchema (codex R1 + adjudicator-verified, Critical, CURED inline) — Editor pass added blocked_by: bug-tracker/plans/BUG-04-090/ to §11 frontmatter; python -m scripts.plan_corpus check rejects with “unknown field blocked_by” per scripts/plan_corpus/schema.py PlanSectionSchema allowed-field list (depends_on / blocks_section_close / inserts_after / inserts_before only). CURE applied: BUG-04-090 transitive-blocker note moved from blocked_by: field to inline YAML comment in frontmatter; AOT-vs-typeck close-gate distinction lives in §11.R-R1-002 below. ANCHOR: frontmatter line 105-114 (post-edit).
  • §11.R-R1-002 — §11.N close-gate AOT-vs-typeck scope distinction (codex R1 + adjudicator-verified, Major) — BUG-04-090 (open AOT codegen UAF) transitive blocker on shared ./test-all.sh gate cited at §11.N “full ./test-all.sh regression run” (line 347). §11.N gate evaluator MUST distinguish typeck-scope failures from AOT-scope failures and treat AOT-scope failures as cures_failures: BUG-04-090, NOT §11 regression. ANCHOR: §11.N “full ./test-all.sh regression run” close-gate to be re-worded — current text says “AOT-scope failures attributed to BUG-04-090 per blocked_by: frontmatter, NOT to §11”; update to “per cures_failures mapping” since blocked_by: removed.
  • §11.R-R1-003 — PUBLIC_LEAK cluster: ~30 wrapper-private rule/plan refs across ori_types/src/ (gemini R1 F1-F4 + opencode R1 F1+F4+F5 convergent + adjudicator-expanded systemic, Critical SYSTEMIC) — Adjudicator grep across compiler/ori_types/src/ enumerated 30+ rustdoc + inline-comment sites carrying wrapper-private references to .claude/rules/*.md files (impl-hygiene.md, typeck.md, types.md sections) AND plan-section paths (§08.3b.1, §10.1, §11.1, §09.3 etc.). Reviewers cited 6 sites (body_finalize/mod.rs:178/230/234/239, infer/mod.rs:438/631, monomorphization.rs:90); ALL 6 CURED inline R1. Remaining ~24 sites (validators/mod.rs:60/106/112/117/122/125/129/132/137/160/164/233/235/245/248/256, pool/descriptor.rs:307-309, pool/substitute/mod.rs:321, pool/accessors/resolution.rs:132, pool/re_intern/mod.rs:501, registry/burden_dedup.rs:20+44, pool/mod.rs:83, output/mod.rs:396, infer/expr/sequences.rs:60, infer/expr/calls/impl_lookup.rs:93-94, check/registration/traits.rs:62, check/registration/impls.rs:407, check/bodies/functions.rs:28, check/validators/partial_move.rs:80+142, check/well_known/mod.rs:253, check/validators/tests.rs:876+883+904) constitute SYSTEMIC public-OSS leak per CLAUDE.md §Public Repo Never Leaks Private-Repo Identifiers. ANCHOR: crate-wide scrub pass on ori_types/src/ — strip every .claude/rules/*.md §... rule-file ref + every §NN.M plan-section ref from rustdoc + inline comments; preserve concept-vocabulary per impl-hygiene.md §Preserved vocabulary (PC-N / CN-N / RG-N / SC-N / VF-N AIMS labels OK; rule-file paths + plan-section refs BANNED).
  • §11.R-R1-004 — PLAN_COHERENCE_DRIFT: §04 status drift in index.md (opencode R1 F2, Major, CURED inline)index.md:75 claimed §04 “Complete 2026-04-22” but section-04-codegen-assertions.md frontmatter carries status: in-progress (Partial per 00-overview Quick Reference: cross-scope blockers on aims-burden-tracking §06). CURE applied: index.md:75 updated to “In Progress (Partial — production code shipped 2026-04-22; cross-scope blockers on aims-burden-tracking §06 prevent §04.N close-gate per 00-overview.md Quick Reference)”. ANCHOR: index.md line 75 (post-edit).
  • §11.R-R1-005 — PLAN_COHERENCE_DRIFT: §11 frontmatter in-review vs overview “In Progress” (opencode R1 F3, Minor) — section frontmatter status: in-review while overview/index prose says “In Progress”. Per state-discipline.md §4: in-review + reviewed: false is the EXPECTED mid-pipeline shape during /review-plan dispatch; the atomic-flip at /tpr-review terminal exit flips in-review → in-progress. ANCHOR: no edit needed — atomic-flip discipline resolves at this round’s exit; informational finding documenting the convention.
  • §11.R-R2-001 — Stale HISTORY entry references removed blocked_by: field (codex R2 F1, Medium, CURED inline) — HISTORY 2026-05-15 entry referenced BUG-04-090 recorded in blocked_by: after R1 cure removed the field. CURE applied: amended HISTORY entry to “tracked as inline YAML comment in §11 frontmatter (per §11.R-R1-001 cure removing the schema-rejected blocked_by: field)”. ANCHOR: section-11:380 HISTORY entry (post-edit).
  • §11.R-R2-002 — Temporal-state mixing in index.md browse-view (opencode R2 F1+F2, Major+Minor, CURED inline) — index.md:218-219 mixed pre-rename name is_empty_collection_literal (lines 225-233) with post-rename target is_defaulting_root; line range stale (actual :243-:252). CURE applied: index.md:218 updated to single-name with line range :243-252; rename anchor cited via §11.1.3 STAGE 1. ANCHOR: index.md:218 (post-edit).
  • §11.R-R2-003 — Phantom-path SC at section-11:81 needs PENDING prefix (opencode R2 F3, Major, CURED inline) — Success_criterion at :81 cites body_finalize/tests.rs without [PENDING] gating. CURE applied: prefixed [PENDING — gated on §11.1.3 STAGE 4] + appended “(file to be created by STAGE 4)”. ANCHOR: section-11:81 (post-edit).
  • §11.R-R2-004 — STAGE 1 rename anchor :242 vs actual :243 (opencode R2 F4, Minor, CURED inline) — One-line drift in STAGE 1 rename anchor. CURE applied: replace_all body_finalize/mod.rs:242:243 across §11 body. ANCHOR: section-11 multi-site (post-edit).
  • §11.R-R3-001 — PUBLIC_LEAK cluster: 3 more wrapper-private refs in infer/mod.rs rustdoc (gemini R3 F1-F3, Critical, CURED inline) — Plan-phase references at infer/mod.rs:143 (“Phase B-Residual-2 (a)”), :151 (“Phase B-Residual-2 (c)”), :182 (“§C.2”) in rustdoc comments. CURE applied: stripped all three phase/section references; kept architectural rationale. ANCHOR: infer/mod.rs:143/151/182 (post-edit). Cross-ref: §11.R-R1-003 systemic-leak finding still owns the ~24 remaining crate-wide leak sites; this cure adds 3 cleared to that count.
  • §11.R-R3-002 — STRUCTURE:work-order-violation (codex R3 F1, Critical) — §11 frontmatter declares subsection_depends_on: {"11.N": ["09.6", "09.7", "10.1", "10.2"]} but predicate code already landed under §09.1 BD-2 gate (commit a20bc41b1) AND §09.6/§09.7 not started + §10.1/§10.2 in-progress; close-gate routing through §09.6+§09.7+§10.1+§10.2 may need re-validation. ANCHOR: §11.N close-gate cannot complete until subsection_depends_on predecessors satisfy status: complete + reviewed: true per impl-hygiene.md §STRUCTURE:work-order-violation. Cross-scope dependency: §09.6/§09.7 are NEW subsections added by §09 editor; §10.1/§10.2 are in-progress with §10.R-014 work-order finding pending §04 close. Resolution path: §11.N close gates on §09 + §10 sections reaching complete + reviewed; informational tracking until predecessors close.
  • §11 close-out /tpr-review — fresh round on full §11 diff (post-STAGE-1-through-5) across codex + gemini + opencode → clean.
  • §11 close-out /impl-hygiene-review — post-TPR hygiene pass.

11.N Completion Checklist + Autopilot Routing

Completion Checklist

  • 11.1 complete — all STAGE 1–5 cures landed; assert(cond: !is_some(opt: None)) green; empty_literals/ corpus regression-guard clean.
  • All §11.R Round 7 findings flipped [x] (R7-codex-F1, R7-codex-F1-sub, R7-codex-F2, R7-codex-F3, R7-gemini-F1, R7-opencode-F1, R7-opencode-F2, R7-opencode-F3, R7-gemini-F3).
  • All §11.R-R1-001..§11.R-R1-005 findings flipped [x] (SCHEMA_DRIFT cured + AOT-vs-typeck close-gate distinction documented + PUBLIC_LEAK systemic cure landed + §04 index.md aligned + §11 in-review→in-progress atomic-flip).
  • All §11.R-R2-001..§11.R-R2-004 findings flipped [x] (stale HISTORY blocked_by-ref cured + index temporal-state mixing cured + phantom-path SC PENDING-prefixed + STAGE 1 anchor :242→:243 corrected).
  • All §11.R-R3-001..§11.R-R3-004 findings flipped [x] (3 more PUBLIC_LEAK refs cured + work-order subsection_depends_on tracking + exit_reason-handler-dead cured + body_inference_complete flag-lifecycle SSOT centralization via per-body-path single-assignment design).
  • All §11.R-BS-11-001..§11.R-BS-11-006 findings flipped [x] (Step 4 blind-spots: mission-fit Some semantics + STAGE 2 save-restore design pivot + predecessor provisional-revalidation gate + Ok/Err spec test coverage + §11.1 partially-started status visibility — all cured inline by this round).
  • §11 aggregate /tpr-review → clean.
  • §11 aggregate /impl-hygiene-review → clean.
  • §11 full ./test-all.sh regression runfailed: 0 confirmed for typeck-scope tests (AOT-scope failures attributed to BUG-04-090 transitive blocker per §11.R-R1-002 — frontmatter comment + cures_failures mapping, NOT to §11).
  • Plan sync — §11 frontmatter status: complete; 00-overview.md Quick Reference updates; index.md section 11 status updated.

Exit criteria: STAGE 1–5 complete; TPR + hygiene clean; ./test-all.sh reports failed: 0 typeck-scope; tests/spec/types/empty_literals/ regression-guard clean; subsection_depends_on: {"11.N": ["09.6", "09.7", "10.1", "10.2"]} predecessors all status: complete. §06.4 regression verification runs against this state. §07 close-out may begin.

Autopilot Routing (next_action mapping for /continue-roadmap)

Mirrors section-09-body-inference-gaps.md §09.N template per routing.md §5 Ordering Primitives — Schema v2 + orchestration-rules.json:skill_exit_reasons.

Exit reasons drawn ONLY from canonical closed set per scripts/plan_corpus/exit_reasons.py CANONICAL_EXIT_REASONS + .claude/skills/tpr-review/SKILL.md §1.7 per BS-11-004 cure (cures §11.R-R3-003 dead-handler cures_failures_on_blocked_bug AND drops dead blocked_on_predecessor invention). BUG-04-090 transitive blocker is represented via cures_failures payload field per feedback_plan_cures_failures_linkage.md, NOT via a section-local exit-reason invention.

§11 conditionexit_reasonnext_action
§11.1.3 STAGE 1 (rename) not startedsubsection_pendingcontinue §11.1.3 STAGE 1 (mechanical rename)
§11.1.3 STAGE 2 (body_inference_complete) not startedsubsection_pendingcontinue §11.1.3 STAGE 2 (cures Critical convergent R7-codex-F1 + R7-opencode-F1 + R7-gemini-F3 AND BS-11-002 + §11.R-R3-004)
§11.1.3 STAGE 3 (introducer-only walk) not startedsubsection_pendingcontinue §11.1.3 STAGE 3 (cures Critical R7-gemini-F1 payload-contamination)
§11.1.3 STAGE 4 (TDD matrix) not startedsubsection_pendingcontinue §11.1.3 STAGE 4 (cures Major R7-opencode-F2 phantom-deliverable)
§11.1.3 STAGE 5 (spec test + regression sweep) not startedsubsection_pendingcontinue §11.1.3 STAGE 5
§11.1.4 close not donesubsection_pendingcontinue §11.1.4 (dual-exec-verify + TPR + hygiene gates)
§11.R findings unflipped (Round 7 or later)finding_outstandingflip §11.R checkboxes as STAGEs land; final fresh TPR round at close
§11 close-out /tpr-review returns findingsfinding_outstandingabsorb findings into §11.R as - [ ] items; re-dispatch /tpr-review
§11 close-out /tpr-review hits round capcap_reached_max_roundsrecord third_party_review.status: cap_reached_with_substantive + open findings; orchestrator decides retry vs accept
§11.N close not done AND subsection_depends_on predecessors completesubsection_pendingrun §11.N close gates
§11.N close not done AND subsection_depends_on predecessors incompletepredecessor_incompleteroute to first incomplete predecessor in §09.6 / §09.7 / §10.1 / §10.2 (canonical reason per exit_reasons.py:73)
§11 frontmatter status: complete AND reviewed: truesection_completeadvance to §06.4 (regression verification gate)
./test-all.sh AOT failures attributable to BUG-04-090finding_outstandingsection frontmatter MUST declare cures_failures: [{"test_id": "<aot-test>", "file": "<path>", "until_section": "BUG-04-090", "kind": "aot"}] (frontmatter linkage field per feedback_plan_cures_failures_linkage.md, NOT a runtime payload); state.sh refresh joins this linkage with test results to downgrade attributed failures from regression-halt to warn-and-proceed; §11 close gate evaluates ONLY typeck-scope failures

Note on §11.2 (dropped): The original proposal included a §11.2 fallback-visibility lint (mirror of Rust’s NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE lint). Both 2026-04-23 /tp-help reviewers recommended DROPPING §11.2 — Ori has no ()-to-! migration to warn about (start-at-Never design), and Rust 2024 Edition direction is silent fallback. Silent fallback is the correct UX: assert(cond: !is_some(opt: None)) should just compile, not emit a confusing warning. If ergonomic concerns surface post-§11.1 deployment, §11.2 can be filed as a separate future proposal.

HISTORY

  • 2026-05-15 — /review-plan Step 5 editor Round 8 blind-spot cures: Step 4 surfaced 6 blind spots (codex/gemini/opencode synthesis); BS-11-004 convergent across all 3 reviewers (autopilot-routing exit_reason inventions wedge orchestrator) + BS-11-002 convergent across 2 (gemini + opencode: save-restore on engine fields structurally unimplementable per code anchor check/bodies/functions.rs:106-110 create_engine_with_env ephemeral-engine pattern); single-reviewer BS-11-001 (codex: mission-fit drift on Some defaulting between umbrella/index and target+code), BS-11-003 (codex: predecessor ordering invariant stated but not gated), BS-11-005 (gemini: AOT-boundary Ok/Err spec coverage gap), BS-11-006 (opencode: §11.1 not-started status hides partial-deployment commit a20bc41b1). All 6 cured inline: §11.N autopilot routing table rewritten to canonical exit_reasons.py enum + cures_failures payload for BUG-04-090; STAGE 2 design pivoted from save-restore to per-body-path single-assignment (cures §11.R-R3-004 SSOT concern in same edit); umbrella + index Some-cascade language clarified; §11.1.3 provisional-marker paragraph + §11.1.4 predecessor-revalidation gate added; STAGE 5 gained two Ori spec tests for Ok/Err; §11.1 status flipped not-started → partially-started with explicit a20bc41b1 marker. Cohesion edits: 00-overview.md (3 sites), index.md (1 site), section-06-diagnostics-audit.md body Status line auto-fix to match frontmatter in-progress. Editor: claude-opus-4-7 per feedback_review_plan_editor_must_do_mission_fit + feedback_sonnet_coding_ban.
  • 2026-05-15 — /review-plan Editor Round 7 cure absorption: TPR Round 7 surfaced convergent body_inference_complete missing-implementation Critical from codex F1 + opencode F1 + gemini F3 (declared in plan §Design Principle 3 + §11.1.2 but zero production code instances); convergent assertion-text plan-leak in debug_assert string (impl-hygiene.md C-B11 violation); convergent introducer-only walk gap on Ok/Err payload (gemini F1 Critical — payload contamination silently masks legitimate E2005); phantom body_finalize/tests.rs deliverable (opencode F2); omitted rename of is_empty_collection_literal -> is_defaulting_root (opencode F3); missing autopilot exit_reason routing (codex F3); subsection-level depends_on drift (codex F2 — section-level depends_on too coarse). All cures absorbed inline as §11.1.3 STAGE 1-5 + §11.R Round 7 findings + §11.N autopilot routing block + subsection_depends_on frontmatter. BUG-04-090 (open AOT codegen UAF, surfaced via intel-query) tracked as inline YAML comment in §11 frontmatter (per §11.R-R1-001 cure removing the schema-rejected blocked_by: field) — close-gate evaluator distinguishes typeck-scope from AOT-scope test failures per feedback_plan_cures_failures_linkage. Editor: claude-opus-4-7 per feedback_review_plan_editor_must_do_mission_fit.
  • 2026-05-17 — Stale review_pipeline: marker cleared by /continue-roadmap orchestrator: marker carried stage: verify-done, next_step: 7, updated: ?. Per /review-plan SKILL.md §Step 1a stale-marker rule (reviewed: false + marker present → STALE by definition), marker invalid; prior diagnosis preserved here for traceability. Cure rooted in scripts/plan_orchestrator/markers.py:clear_stale_marker_if_unreviewed.