89%

Section 0: Full Parser Support

Goal: Complete parser support for entire Ori spec grammar (parsing only — evaluator in Section 23)

SPEC: spec/grammar.ebnf (authoritative), spec/06-source-code.md, spec/07-lexical-elements.md

Status: In Progress — Verified 2026-03-29. 3 parser bugs remain (all blocked), down from 24. 4181 spec tests pass, 0 fail. Gap analysis found 3 missing grammar productions (while_expr, labeled_block, capset_decl) and systemic absence of negative parser tests. See 0.8 for full checklist.


OVERVIEW

This section ensures the parser handles every syntactic construct in the Ori specification. It has no dependencies and can be worked on at any time. Other sections may overlap with this work — that’s expected and acceptable.

Why this matters: The formatter, LSP, and other tooling depend on complete parser support. Without it, valid Ori code may fail to parse, blocking downstream work.

Approach:

  1. Audit current parser against each grammar production
  2. Implement missing productions
  3. Add parser tests for each production
  4. Mark items complete as verified

0.1 Lexical Grammar (verified 2026-03-29)

SPEC: grammar.ebnf § LEXICAL GRAMMAR, spec/07-lexical-elements.md

INCOMPLETE MATRIX: Zero #compile_fail negative parser tests in tests/spec/lexical/. Every test suite must include negative tests per tests.md.

0.1.1 Comments

  • Audit: Line comments // ... — grammar.ebnf § comment [done] (2026-02-10)

    • Rust Tests: oric/tests/phases/parse/lexer.rs — 14 comment tests (classification, spans, detached warnings)
    • Ori Tests: tests/spec/lexical/comments.ori — 21 tests (verified 2026-03-29)
  • Audit: Doc comments with markers — grammar.ebnf § doc_comment [done] (2026-02-10)

    • // (description), // * (param), // ! (warning), // > (example)
    • Rust Tests: oric/tests/phases/parse/lexer.rs — doc comment type tests
    • Ori Tests: tests/spec/lexical/comments.ori — all marker types tested

0.1.2 Identifiers

  • Audit: Standard identifiers letter { letter | digit | "_" } — grammar.ebnf § identifier [done] (2026-02-10)
    • Rust Tests: oric/tests/phases/parse/lexer.rs — identifier tokenization
    • Ori Tests: tests/spec/lexical/identifiers.ori — 26 tests (verified 2026-03-29)

0.1.3 Keywords

  • Audit: Reserved keywords — grammar.ebnf § Keywords [done] (2026-02-10)

    • break, continue, def, do, else, extern, false, for, if, impl
    • in, let, loop, match, pub, self, Self, then, trait, true
    • type, unsafe, use, uses, void, where, with, yield
    • Rust Tests: oric/tests/phases/parse/lexer.rs — 45+ keyword recognition tests
    • Ori Tests: tests/spec/lexical/keywords.ori — 34 tests (verified 2026-03-29)
  • Audit: Context-sensitive keywords (patterns) — grammar.ebnf § Keywords [done] (2026-02-10)

    • cache, catch, for, match, nursery, parallel, recurse, run, spawn, timeout, try, with
    • Rust Tests: oric/tests/phases/parse/lexer.rs — soft keyword lookahead, contextual flag tests
    • Ori Tests: tests/spec/lexical/keywords.ori — context-sensitive usage verified
  • Audit: Context-sensitive keywords (stdlib methods) — spec/07-lexical-elements.md § Context-Sensitive [done] (2026-02-10)

    • collect, filter, find, fold, map, retry, validate
    • Note: These are stdlib iterator methods, not compiler patterns — listed in spec as context-sensitive
    • Rust Tests: oric/tests/phases/parse/lexer.rs — builtin_names_are_identifiers test
    • Ori Tests: tests/spec/lexical/keywords.orifold tested as identifier; stdlib methods are plain identifiers
  • Audit: Context-sensitive keywords (other) — grammar.ebnf § Keywords [done] (2026-02-10)

    • without (imports only), by (ranges only), max (fixed-capacity only)
    • int, float, str, byte (type conversion call position)
    • Rust Tests: oric/tests/phases/parse/lexer.rs — type keywords always resolved, soft keyword handling
    • Ori Tests: tests/spec/lexical/keywords.ori — type keywords and context-sensitive usage tested

0.1.4 Operators

  • Audit: Arithmetic operators — grammar.ebnf § arith_op [done] (2026-02-10)

    • +, -, *, /, %, divFixed: Added div to parser (was missing)
    • Rust Tests: implicit through tokenization
    • Ori Tests: tests/spec/lexical/operators.ori — 72 tests (verified 2026-03-29)
  • Audit: Comparison operators — grammar.ebnf § comp_op [done] (2026-02-10)

    • ==, !=, <, >, <=, >=
    • Rust Tests: implicit through tokenization
    • Ori Tests: tests/spec/lexical/operators.ori
  • Audit: Logic operators — grammar.ebnf § logic_op [done] (2026-02-10)

    • &&, ||, !
    • Rust Tests: implicit through tokenization
    • Ori Tests: tests/spec/lexical/operators.ori
  • Audit: Bitwise operators — grammar.ebnf § bit_op [done] (2026-02-10)

    • &, |, ^, ~, <<, >>
    • Rust Tests: implicit through tokenization
    • Ori Tests: tests/spec/lexical/operators.ori
  • Audit: Other operators — grammar.ebnf § other_op [done] (2026-02-10)

    • .., ..=, ??, ?, ->, => — Note: ?? parses but evaluator incomplete
    • Rust Tests: implicit through tokenization
    • Ori Tests: tests/spec/lexical/operators.ori

0.1.5 Delimiters

  • Audit: All delimiters — grammar.ebnf § delimiter [done] (2026-02-10)
    • (, ), [, ], {, }, ,, :, ., @, $
    • Rust Tests: implicit through parsing
    • Ori Tests: tests/spec/lexical/delimiters.ori — 57 tests (verified 2026-03-29)

0.1.6 Integer Literals

  • Audit: Decimal integers — grammar.ebnf § decimal_lit [done] (2026-02-10)

    • Basic: 42, with underscores: 1_000_000
    • Rust Tests: oric/tests/phases/parse/lexer.rs — decimal/hex/binary underscore tests
    • Ori Tests: tests/spec/lexical/int_literals.ori — 42 tests (verified 2026-03-29)
  • Audit: Hexadecimal integers — grammar.ebnf § hex_lit [done] (2026-02-10)

    • Basic: 0xFF, with underscores: 0x1A_2B_3C
    • Rust Tests: oric/tests/phases/parse/lexer.rs — hex underscore tests
    • Ori Tests: tests/spec/lexical/int_literals.ori — hex literals with case/underscore variants

0.1.7 Float Literals

  • Audit: Basic floats — grammar.ebnf § float_literal [done] (2026-02-10)
    • Simple: 3.14, with exponent: 2.5e-8, 1.0E+10
    • Rust Tests: oric/tests/phases/parse/lexer.rs — float/scientific notation tests
    • Ori Tests: tests/spec/lexical/float_literals.ori — 45 tests (verified 2026-03-29)

0.1.8 String Literals

  • Audit: Basic strings — grammar.ebnf § string_literal [done] (2026-02-10)

    • Simple: "hello", empty: ""
    • Rust Tests: oric/tests/phases/parse/lexer.rs — string escape tests
    • Ori Tests: tests/spec/lexical/string_literals.ori — 52 tests (verified 2026-03-29)
  • Audit: Escape sequences — grammar.ebnf § escape [done] (2026-02-10)

    • \\, \", \n, \t, \r, \0
    • Rust Tests: oric/tests/phases/parse/lexer.rs — escape parsing
    • Ori Tests: tests/spec/lexical/string_literals.ori — escapes tested in same file

0.1.9 Template Literals

  • Audit: Template strings — grammar.ebnf § template_literal [done] (2026-02-10)

    • Simple: `hello`, interpolation: `{name}`
    • Rust Tests: oric/tests/phases/parse/lexer.rs — 12 template tests (head/middle/tail tokens, interpolation)
    • Ori Tests: tests/spec/expressions/template_literals.ori — end-to-end template tests
  • Audit: Template escapes — grammar.ebnf § template_escape, template_brace [done] (2026-02-10)

    • Escapes: \`, \\, \n, \t, \r, \0
    • Brace escapes: {{, }}
    • Rust Tests: oric/tests/phases/parse/lexer.rs — template escape/brace tests
  • Audit: Format specifications — grammar.ebnf § format_spec [done] (2026-02-10)

    • Fill/align: {x:<10}, {x:>5}, {x:^8}
    • Sign: {x:+} (always sign), {x:-} (negative only), {x: } (space for positive)
    • Width/precision: {x:10}, {x:.2}, {x:10.2}
    • Format types: {x:b}, {x:x}, {x:X}, {x:o}, {x:e}, {x:E}, {x:f}, {x:%}
    • Rust Tests: oric/tests/phases/parse/lexer.rs — format spec parsing tests (:x, >10.2f)

0.1.10 Character Literals

  • Audit: Character literals — grammar.ebnf § char_literal [done] (2026-02-10)
    • Simple: 'a', escapes: '\n', '\t', '\'', '\\'
    • Rust Tests: oric/tests/phases/parse/lexer.rs — char literal parsing
    • Ori Tests: tests/spec/lexical/char_literals.ori — 59 tests (verified 2026-03-29)

0.1.11 Boolean Literals

  • Audit: Boolean literals — grammar.ebnf § bool_literal [done] (2026-02-10)
    • true, false
    • Rust Tests: implicit through keyword recognition
    • Ori Tests: tests/spec/lexical/bool_literals.ori — 51 tests (verified 2026-03-29)

0.1.12 Duration Literals

  • Audit: Duration literals — grammar.ebnf § duration_literal [done] (2026-02-10)
    • All units: 100ns, 50us, 10ms, 5s, 2m, 1h
    • Decimal syntax: 0.5s, 1.5m (compile-time sugar) — tested
    • Rust Tests: oric/tests/phases/parse/lexer.rs — 10+ duration tests (units, decimal, many digits)
    • Ori Tests: tests/spec/lexical/duration_literals.ori — 60 tests (verified 2026-03-29)

0.1.13 Size Literals

  • Audit: Size literals — grammar.ebnf § size_literal [done] (2026-02-10)
    • All units: 100b, 10kb, 5mb, 1gb, 500tb
    • Decimal syntax: 1.5kb, 2.5mb (compile-time sugar) — tested
    • Rust Tests: oric/tests/phases/parse/lexer.rs — 5+ size tests (units, decimal)
    • Ori Tests: tests/spec/lexical/size_literals.ori — 58 tests (verified 2026-03-29)

0.2 Source Structure (verified 2026-03-29)

SPEC: grammar.ebnf § SOURCE STRUCTURE, spec/06-source-code.md, spec/18-modules.md

0.2.1 Source File

  • Audit: Source file structure — grammar.ebnf § source_file [done] (2026-02-10)

    • [ file_attribute ] { import } { declaration } — imports + types + functions + tests all parse
    • Rust Tests: implicit through full-file parsing
    • Ori Tests: tests/spec/source/file_structure.ori — 4 tests (verified 2026-03-29)
  • Audit: File-level attributes — grammar.ebnf § file_attribute [done] (2026-02-13)

    • #!target(os: "linux"), #!cfg(debug) — parses correctly, stored in Module.file_attr
    • Rust Tests: oric/tests/phases/parse/file_attr.rs — 16 tests, ori_parse::grammar::attr — 5 tests
    • Ori Tests: tests/spec/source/file_attr_target.ori, file_attr_cfg.ori, file_attributes.ori

0.2.2 Imports

  • Audit: Import statements — grammar.ebnf § import [done] (2026-02-10)

    • Relative: use "./path" { items } — parses correctly
    • Module: use std.math { sqrt } — parses correctly
    • Alias: use std.net.http as http — parses correctly
    • Ori Tests: tests/spec/source/imports.ori — 2 tests (verified 2026-03-29)
  • Audit: Import items — grammar.ebnf § import_item [done] (2026-02-10)

    • Basic: { name }, aliased: { name as alias } — parses correctly
    • Private: { ::internal } — parses correctly (2026-02-13), constants: { $CONST } — parses correctly (parser + formatter, evaluator pending)
    • Without default impl: { Trait without def } — parses correctly (2026-02-13, trait resolution pending)
    • Rust Tests: oric/tests/phases/parse/imports.rs — 12 tests (all import_item forms)
    • Ori Tests: tests/spec/source/imports.ori, tests/spec/modules/use_imports.ori, tests/spec/modules/_test/use_constants.test.ori

0.2.3 Re-exports

  • Audit: Re-export statements — grammar.ebnf § reexport [done] (2026-02-10)
    • pub use path { items } — parses correctly (verified via ori parse)
    • Ori Tests: tests/spec/modules/reexporter.ori — 1 test

0.2.4 Extensions

  • Audit: Extension definitions — grammar.ebnf § extension_def [done] (2026-02-10)

    • extend Type { methods } — parses correctly (verified via ori parse)
    • extend Type where T: Bound { methods } — parses correctly (2026-02-13), including multiple bounds
    • Ori Tests: tests/spec/source/extensions.ori — 2 tests (verified 2026-03-29)
  • Audit: Extension imports — grammar.ebnf § extension_import [done] (2026-02-13)

    • extension std.iter.extensions { Iterator.count } — parses correctly (2026-02-13)
    • pub extension path { Type.method } — parses correctly (public re-export)
    • extension "./path" { Type.method } — parses correctly (relative paths)
    • Rust Tests: oric/tests/phases/parse/extensions.rs — 8 extension import tests
    • Formatter: round-trips correctly

0.2.5 FFI

  • Audit: Extern blocks — grammar.ebnf § extern_block [done] (2026-02-13)

    • C: extern "c" from "lib" { ... } — parses correctly (verified via ori parse)
    • JS: extern "js" { ... } — parses correctly
    • pub extern visibility — parses correctly
    • from "path" library clause — parses correctly
    • Empty extern blocks — parses correctly
    • Note: Extern blocks are now proper AST nodes (ExternBlock, ExternItem, ExternParam)
  • Audit: Extern items — grammar.ebnf § extern_item [done] (2026-02-13)

    • @_sin (x: float) -> float as "sin" — parses correctly (as alias)
    • @sin (x: float) -> float — parses correctly (no alias)
    • Mixed alias/no-alias items in same block — parses correctly
  • Audit: C variadics — grammar.ebnf § c_variadic [done] (2026-02-13)

    • @printf (fmt: CPtr, ...) -> c_int — parses correctly
    • (...) -> void — parses correctly (no named params)
  • Rust Tests: oric/tests/phases/parse/extern_def.rs — 20 tests (2026-02-13)

  • Formatter: round-trips correctly (2026-02-13)


0.3 Declarations (verified 2026-03-29)

SPEC: grammar.ebnf § DECLARATIONS, spec/10-declarations.md

0.3.1 Attributes

  • Audit: Item attributes — grammar.ebnf § attribute [done] (2026-02-10)

    • #derive(Eq, Clone) — parses correctly
    • #skip("reason"), #fail("expected"), #compile_fail("E1234") — parse correctly
    • #target(os: "linux"), #cfg(debug) — parses correctly [done] (2026-02-13)
    • #repr("c") — parses correctly [done] (2026-02-13)
    • Ori Tests: tests/spec/declarations/attributes.ori — 24+ tests
  • Audit: Attribute arguments — grammar.ebnf § attribute_arg [done] (2026-02-10)

    • Expression: #attr(42), named: #attr(key: value) — tested in attributes.ori
    • Array: #attr(["a", "b"]) — tested via #derive(Eq, Clone) syntax
    • Ori Tests: tests/spec/declarations/attributes.ori — covers argument forms

0.3.2 Functions

  • Audit: Function declarations — grammar.ebnf § function [done] (2026-02-10)

    • Basic: @name (x: int) -> int = expr — parses correctly
    • Public: pub @name — parses correctly
    • Rust Tests: oric/tests/phases/parse/function.rs — 8 tests for return type annotations
    • Ori Tests: extensive coverage across all test files (3068 tests use function syntax)
  • Audit: Function generics — grammar.ebnf § generics (partial) [done] (2026-02-10)

    • Type params: @f<T> (x: T) -> T — parses correctly (verified via ori parse)
    • Bounded: @f<T: Eq> (x: T) -> bool — parses correctly
    • Multiple bounds: @f<T: Eq + Clone> (x: T) -> T — parses correctly
    • Const params: @f<$N: int> () -> [int, max $N] — parses correctly [done] (2026-02-13)
    • Default params: @f<T = int> (x: T) -> T — parses correctly
    • Ori Tests: tests/spec/declarations/generics.ori — exists but tests commented out (type checker deps)
  • Audit: Clause parameters — grammar.ebnf § clause_params [done] (2026-02-13)

    • Pattern param: @fib (0: int) -> int = 1 — parses correctly (verified via ori parse)
    • Default value: @greet (name: str = "World") -> str — parses correctly (verified via ori parse)
    • Ori Tests: tests/spec/declarations/clause_params.ori — exists, commented out (blocked by type checker/evaluator)
  • Audit: Guard clauses — grammar.ebnf § guard_clause [done] (2026-02-13)

    • @f (n: int) -> int if n > 0 = n — parses correctly (verified via ori parse)
  • Audit: Uses clause — grammar.ebnf § uses_clause [done] (2026-02-10)

    • @fetch (url: str) -> str uses Http = ... — parses correctly (verified via ori parse)
    • Multiple: @process () -> void uses Http, FileSystem = ... — parses correctly
  • Audit: Where clause — grammar.ebnf § where_clause [done] (2026-02-10)

    • Type constraint: where T: Clone — parses correctly (verified via ori parse)
    • Multiple: where T: Clone, U: Default — parses correctly
    • Const constraint: where N > 0 — parses correctly [done] (2026-02-13)
    • Ori Tests: tests/spec/declarations/where_clause.ori — exists but tests commented out

0.3.3 Const Bound Expressions

  • Audit: Const bound expressions — grammar.ebnf § const_bound_expr [done] (2026-02-13)
    • Comparison: N > 0, N == M, N >= 1 — parses correctly
    • Logical: N > 0 && N < 100, A || B, !C — parses correctly
    • Grouped: (N > 0 && N < 10) || N == 100 — parses correctly
    • Rust Tests: ori_parse/src/grammar/item/generics.rs — 5 where clause tests

0.3.4 Type Definitions

  • Audit: Struct types — grammar.ebnf § struct_body [done] (2026-02-10)

    • type Point = { x: int, y: int } — parses correctly
    • Generic: type Box<T> = { value: T } — parses correctly
    • Ori Tests: tests/spec/declarations/struct_types.ori — 39 active tests (comprehensive)
  • Audit: Sum types — grammar.ebnf § sum_body [done] (2026-02-10)

    • type Option<T> = Some(value: T) | None — parses correctly
    • Unit variants: type Color = Red | Green | Blue — parses correctly
    • Ori Tests: tests/spec/declarations/sum_types.ori — 35+ active tests
  • Audit: Newtype aliases — grammar.ebnf § type_body (type reference) [done] (2026-02-10)

    • type UserId = int — parses correctly (verified via ori parse)
    • Ori Tests: tests/spec/types/newtypes.ori — tests in types/ directory

0.3.5 Traits

  • Audit: Trait definitions — grammar.ebnf § trait_def [done] (2026-02-10)

    • Basic: trait Printable { @to_str (self) -> str } — parses correctly
    • With inheritance: trait Comparable: Eq { ... } — parses correctly
    • With generics: trait Into<T> { @into (self) -> T } — parses correctly
    • Default type params: trait Add<Rhs = Self> { ... } — parses correctly
    • Ori Tests: tests/spec/declarations/traits.ori — 30+ active tests
  • Audit: Method signatures — grammar.ebnf § method_sig [done] (2026-02-10)

    • @method (self) -> T, @method (self, other: Self) -> bool — parse correctly
    • Ori Tests: tests/spec/declarations/traits.ori — method sigs tested within trait tests
  • Audit: Default methods — grammar.ebnf § default_method [done] (2026-02-10)

    • @method (self) -> T = expr — parses correctly
    • Ori Tests: tests/spec/declarations/traits.ori — default methods tested within trait tests
  • Audit: Associated types — grammar.ebnf § assoc_type [done] (2026-02-10)

    • Basic: type Item — parses correctly
    • Bounded: type Item: Eq — parses correctly
    • Default: type Output = Self — parses correctly
    • Ori Tests: tests/spec/traits/associated_types.ori — comprehensive tests
  • Audit: Variadic parameters — grammar.ebnf § variadic_param [done] (2026-02-13)

    • @sum (nums: ...int) -> int — parses correctly (verified via ori parse)

0.3.6 Implementations

  • Audit: Inherent impl — grammar.ebnf § inherent_impl [done] (2026-02-10)

    • impl Point { @distance (self) -> float = ... } — parses correctly
    • Generic: impl<T> Box<T> { ... } — parses correctly (verified via ori parse)
    • Ori Tests: tested across trait/struct test files
  • Audit: Trait impl — grammar.ebnf § trait_impl [done] (2026-02-10)

    • impl Point: Printable { ... } — parses correctly
    • Generic: impl<T: Printable> Box<T>: Printable { ... } — parses correctly
    • Ori Tests: tests/spec/declarations/traits.ori — trait impls tested
  • Audit: Default impl — grammar.ebnf § def_impl [done] (2026-02-10)

    • def impl Printable { @to_str (self) -> str = ... } — parses correctly (verified via ori parse)

0.3.7 Tests

  • Audit: Test declarations — grammar.ebnf § test [done] (2026-02-14)
    • Attached: @t tests @target () -> void = ... — parses correctly (used in 3068 tests)
    • Floating: @t tests _ () -> void = ... — parses correctly [done] (2026-02-14)
    • Multi-target: @t tests @a tests @b () -> void = ... — parses correctly [done] (2026-02-14)
    • Ori Tests: tests/spec/free_floating_test.ori — 3 tests (2 floating with tests _, 1 legacy test_ prefix)
    • Rust Tests: ori_parse::grammar::item::function::tests — 5 tests

0.3.8 Constants

  • Audit: Module-level constants — grammar.ebnf § constant_decl (partial) [done] (2026-02-10)
    • let $PI = 3.14159 — parses correctly (verified via ori parse)
    • Computed: let $X = 2 + 3 — parses correctly
    • Typed: let $MAX_SIZE: int = 1000 — parses correctly [done] (2026-02-14)
    • Ori Tests: tests/spec/declarations/constants.ori — exists but all commented out

0.3.9 Capset Declarations

NEEDS TESTS — grammar.ebnf defines capset_decl but no section item or spec tests exist.

  • Audit: Capset declarations — grammar.ebnf § capset_decl

    • Basic: capset Net = Http, Dns, Tls — needs verification and spec tests
    • NEEDS TESTS: tests/spec/declarations/capsets.ori — basic capset declaration and usage
  • /tpr-review passed — independent review found no critical or major issues (or all findings triaged)

  • /impl-hygiene-review passed — hygiene review clean. MUST run AFTER /tpr-review is clean.

  • Subsection close-out (0.3) — MANDATORY before starting the next subsection. Run /improve-tooling retrospectively on THIS subsection’s debugging journey (per .claude/skills/improve-tooling/SKILL.md “Per-Subsection Workflow”): which diagnostics/ scripts you ran, where you added dbg!/tracing calls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE /commit-push using a valid conventional-commit type (build(diagnostics): ... — surfaced by section-0.3 retrospectivebuild/test/chore/ci/docs are valid; tools(...) is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 0.3: no tooling gaps”. Update this subsection’s status in section frontmatter to complete.

  • /sync-claude section-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW.

  • Repo hygiene check — run diagnostics/repo-hygiene.sh --check and clean any detected temp files.


0.4 Types

SPEC: grammar.ebnf § TYPES, spec/08-types.md

0.4.1 Type Paths

  • Audit: Simple type paths — grammar.ebnf § type_path [done] (2026-02-10)

    • int, Point, std.math.Complex — parses correctly
    • Rust Tests: ori_ir/tests/ — 16 parsed_type tests (primitive, named, generic, nested, associated, function, list, map, tuple, unit)
  • Audit: Generic type arguments — grammar.ebnf § type_args [done] (2026-02-10)

    • Option<int>, Result<T, E>, Map<str, int> — parses correctly
    • With const: [int, max 10] — parses correctly [done] (2026-02-13)
    • Array<int, $N> — parses correctly [done] (2026-02-13)

0.4.2 Existential Types

  • Audit: impl Trait — grammar.ebnf § impl_trait_type
    • Basic: impl IteratorBROKEN: parser rejects impl in type position
    • Multi-trait: impl Iterator + Clone — blocked by above
    • With where: impl Iterator where Item == int — blocked by above

0.4.3 Compound Types

  • Audit: List types — grammar.ebnf § list_type [done] (2026-02-10)

    • Dynamic: [int], [Option<str>] — parses correctly
  • Audit: Fixed-capacity list types — grammar.ebnf § fixed_list_type [done] (2026-02-13)

    • [int, max 10], [T, max N] — parses correctly (verified via ori parse)
  • Audit: Map types — grammar.ebnf § map_type [done] (2026-02-10)

    • {str: int}, {K: V} — parses correctly
  • Audit: Tuple types — grammar.ebnf § tuple_type [done] (2026-02-10)

    • Unit: (), pairs: (int, str), nested: ((int, int), str) — parses correctly
  • Audit: Function types — grammar.ebnf § function_type [done] (2026-02-10)

    • () -> void, (int) -> int, (int, str) -> bool — parses correctly (verified via typed lambda)

0.4.4 Const Expressions in Types

  • Audit: Const expressions — grammar.ebnf § const_expr [done] (2026-02-13)
    • Literal: 10 in type argument position (e.g., Array<int, 10>) — parses correctly
    • Parameter: $N in type argument position — parses correctly
    • Arithmetic: $N + 1, $N * 2 in type argument position — parses correctly
    • Rust Tests: ori_parse/src/grammar/ty.rs — 4 const expression type arg tests

0.4.5 Trait Objects (verified 2026-03-29)

SPEC: spec/08-types.md § Trait Objects

  • Audit: Simple trait objects — spec/08-types.md § Trait Objects [done] (2026-02-10)

    • Trait name as type: @display (item: Printable) -> void — parses correctly (verified via ori parse)
    • In collections: [Printable], {str: Printable} — parses correctly [done] (2026-02-13)
    • Ori Tests: tests/spec/types/trait_objects.ori — tests exist
  • Audit: Bounded trait objects — spec/08-types.md § Bounded Trait Objects [done] (2026-02-14)

    • Multiple bounds: Printable + Hashable — parses correctly as TraitBounds variant [done] (2026-02-14)
    • As parameter type: @store (item: Printable + Hashable) -> void — parses correctly [done] (2026-02-14)
    • Grammar: trait_object_bounds already in grammar.ebnf; parser now implements it [done] (2026-02-14)
  • /tpr-review passed — independent review found no critical or major issues (or all findings triaged)

  • /impl-hygiene-review passed — hygiene review clean. MUST run AFTER /tpr-review is clean.

  • Subsection close-out (0.4) — MANDATORY before starting the next subsection. Run /improve-tooling retrospectively on THIS subsection’s debugging journey (per .claude/skills/improve-tooling/SKILL.md “Per-Subsection Workflow”): which diagnostics/ scripts you ran, where you added dbg!/tracing calls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE /commit-push using a valid conventional-commit type (build(diagnostics): ... — surfaced by section-0.4 retrospectivebuild/test/chore/ci/docs are valid; tools(...) is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 0.4: no tooling gaps”. Update this subsection’s status in section frontmatter to complete.

  • /sync-claude section-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW.

  • Repo hygiene check — run diagnostics/repo-hygiene.sh --check and clean any detected temp files.


0.5 Expressions (verified 2026-03-29)

SPEC: grammar.ebnf § EXPRESSIONS, spec/14-expressions.md

INCOMPLETE MATRIX: Zero #compile_fail negative parser tests in tests/spec/expressions/. Missing dedicated while and labeled block tests.

0.5.1 Primary Expressions

Note: Pattern expressions (run, try, match, parallel, nursery, channel, etc.) are valid primary expressions per grammar.ebnf § primary → pattern_expr. See section 0.6 for pattern-specific audit items.

  • Audit: Literals — grammar.ebnf § primary [done] (2026-02-10)

    • All literal types covered in 0.1 — all parse correctly
    • Ori Tests: tests/spec/lexical/ — 690+ tests across all literal types
  • Audit: Identifiers and self — grammar.ebnf § primary [done] (2026-02-10)

    • x, self, Self — parse correctly
    • Ori Tests: tests/spec/lexical/identifiers.ori — 26 tests
  • Audit: Grouped expressions — grammar.ebnf § primary [done] (2026-02-10)

    • (expr), nested: ((a + b) * c) — parse correctly (verified via ori parse)
  • Audit: Length placeholder — grammar.ebnf § primary [done] (2026-02-13)

    • list[# - 1] (last element) — parses correctly (verified via ori parse)

0.5.2 Unsafe Expression

  • Audit: Unsafe expressions — grammar.ebnf § unsafe_expr [done] (2026-02-10)
    • unsafe(expr) — parsed correctly (verified 2026-02-10; parenthesized form removed by unsafe-semantics-proposal 2026-02-20)
    • unsafe { expr } — block-only form (implemented 2026-02-21)

0.5.3 List Literals

  • Audit: List literals — grammar.ebnf § list_literal [done] (2026-02-10)
    • Empty: [], simple: [1, 2, 3] — parse correctly
    • With spread: [...a, 4, ...b] — parses correctly (verified via ori parse)

0.5.4 Map Literals

  • Audit: Map literals — grammar.ebnf § map_literal [done] (2026-02-10)
    • Empty: {}, simple: {"a": 1, "b": 2} — parse correctly
    • String keys: {"key": value} — parses correctly
    • Computed keys: {[expr]: value} — parses correctly (verified via ori parse)
    • With spread: {...base, extra: 1} — parses correctly (verified via ori parse)

0.5.5 Struct Literals

  • Audit: Struct literals — grammar.ebnf § struct_literal [done] (2026-02-10)
    • Basic: Point { x: 1, y: 2 } — parses correctly
    • Shorthand: Point { x, y } — parses correctly (verified via ori parse)
    • With spread: Point { ...base, x: 10 } — parses correctly (verified via ori parse)
    • Ori Tests: tests/spec/declarations/struct_types.ori — 39 active tests

0.5.6 Postfix Expressions

  • Audit: Field/method access — grammar.ebnf § postfix_op [done] (2026-02-10)

    • Field: point.x — parses correctly
    • Method: list.len() — parses correctly
    • Ori Tests: extensive coverage across all test files
  • Audit: Index access — grammar.ebnf § postfix_op [done] (2026-02-10)

    • list[0], map["key"] — parse correctly
    • list[# - 1] — parses correctly [done] (2026-02-13)
  • Audit: Function calls — grammar.ebnf § call_args [done] (2026-02-10)

    • Named: greet(name: "Alice") — parses correctly
    • Positional (lambda): list.map(x -> x * 2) — parses correctly
    • Spread: sum(...numbers) — parses correctly (verified via ori parse)
    • Ori Tests: tests/spec/declarations/named_arguments.ori — 149 lines
  • Audit: Error propagation — grammar.ebnf § postfix_op [done] (2026-02-10)

    • result? — parses correctly (verified via ori parse)
  • Audit: Type conversion — grammar.ebnf § postfix_op [done] (2026-02-10)

    • Infallible: 42 as float — parses correctly (verified via ori parse)
    • Fallible: "42" as? int — parses correctly (verified via ori parse)

0.5.7 Unary Expressions

  • Audit: Unary operators — grammar.ebnf § unary_expr [done] (2026-02-10)
    • Logical not: !condition — parses correctly
    • Negation: -number — parses correctly
    • Bitwise not: ~bits — parses correctly
    • Ori Tests: tests/spec/lexical/operators.ori — 72 tests including unary

0.5.8 Binary Expressions

  • Audit: Null coalesce — grammar.ebnf § coalesce_expr [done] (2026-02-10)

    • option ?? default — parses correctly (verified via ori parse)
  • Audit: Logical operators — grammar.ebnf § or_expr, and_expr [done] (2026-02-10)

    • a || b, a && b — parse correctly
    • Ori Tests: tests/spec/lexical/operators.ori, tests/spec/lexical/bool_literals.ori
  • Audit: Bitwise operators — grammar.ebnf § bit_or_expr, bit_xor_expr, bit_and_expr [done] (2026-02-10)

    • a | b, a ^ b, a & b — parse correctly
    • Ori Tests: tests/spec/lexical/operators.ori
  • Audit: Equality operators — grammar.ebnf § eq_expr [done] (2026-02-10)

    • a == b, a != b — parse correctly
    • Ori Tests: tests/spec/lexical/operators.ori
  • Audit: Comparison operators — grammar.ebnf § cmp_expr [done] (2026-02-10)

    • a < b, a > b, a <= b, a >= b — parse correctly
    • Ori Tests: tests/spec/lexical/operators.ori
  • Audit: Range expressions — grammar.ebnf § range_expr [done] (2026-02-10)

    • Exclusive: 0..10, inclusive: 0..=10 — parse correctly
    • With step: 0..10 by 2 — parses correctly
    • Ori Tests: tests/spec/lexical/operators.ori
  • Audit: Shift operators — grammar.ebnf § shift_expr [done] (2026-02-10)

    • a << n, a >> n — parse correctly
    • Ori Tests: tests/spec/lexical/operators.ori
  • Audit: Arithmetic operators — grammar.ebnf § add_expr, mul_expr [done] (2026-02-10)

    • a + b, a - b, a * b, a / b, a % b, a div b — parse correctly
    • Ori Tests: tests/spec/lexical/operators.ori

0.5.9 While Expression

NEEDS TESTS — grammar.ebnf defines while_expr but no section item or dedicated spec tests exist.

  • Audit: While expressions — grammar.ebnf § while_expr
    • Basic: while condition do body — needs verification and spec tests
    • Labeled: while:name condition do body — needs verification and spec tests
    • NEEDS TESTS: tests/spec/expressions/while.ori — basic, labeled, break, continue, nested

0.5.10 Labeled Blocks

NEEDS TESTS — grammar.ebnf defines labeled_block but no section item or spec tests exist.

  • Audit: Labeled blocks — grammar.ebnf § labeled_block
    • Basic: block:name { body } — needs verification and spec tests
    • With break: block:name { ... break:name value } — needs verification and spec tests
    • NEEDS TESTS: tests/spec/expressions/labeled_blocks.ori — basic, break with value, nested

0.5.11 Pipe Expression

Parsing works in practice (used in 16+ spec test files). Not documented in section.

  • Audit: Pipe expressions — grammar.ebnf § pipe_expr (verified 2026-03-29)
    • x |> f(a: v) — parses correctly (used in traits/debug/, traits/core/, etc.)
    • x |> .method() — parses correctly
    • x |> (a -> expr) — parses correctly

0.5.12 Compound Assignment

Tests exist and pass (compound_assignment.ori, 412 lines). Not documented in section.

  • Audit: Compound assignment — grammar.ebnf § compound_assignment (verified 2026-03-29)
    • x += y, x -= y, x *= y, etc. — parse correctly
    • Ori Tests: tests/spec/expressions/compound_assignment.ori — 412 lines, comprehensive

0.5.13 Argument Punning

Tests exist and pass. Not documented in section.

  • Audit: Argument punning — grammar.ebnf § argument_punning (verified 2026-03-29)
    • f(x:) = f(x: x) — parses correctly
    • Ori Tests: tests/spec/expressions/argument_punning.ori — tests present

0.5.14 With Expression (verified 2026-03-29)

  • Audit: Capability provision — grammar.ebnf § with_expr [done] (2026-02-10)
    • with x = value in expr — parses correctly (verified via ori parse)
    • Capability form: with Http = MockHttp in expr — parses correctly [done] (2026-02-13)

0.5.15 Let Binding

  • Audit: Let expressions — grammar.ebnf § let_expr [done] (2026-02-10)

    • Mutable: let x = 42 — parses correctly
    • Immutable: let $x = 42 — parses correctly
    • Typed: let x: int = 42 — parses correctly
    • Ori Tests: extensive coverage across all test files (3068 tests use let bindings)
  • Audit: Assignment — grammar.ebnf § assignment [done] (2026-02-10)

    • x = new_value — parses correctly

0.5.16 Conditional

  • Audit: If expressions — grammar.ebnf § if_expr [done] (2026-02-10)
    • Simple: if cond then a else b — parses correctly
    • Void: if cond then action — parses correctly
    • Chained: if c1 then a else if c2 then b else c — parses correctly (verified via ori parse)
    • Ori Tests: extensive coverage across test files

0.5.17 For Expression

  • Audit: For loops — grammar.ebnf § for_expr [done] (2026-02-10)
    • Do: for x in items do action — parses correctly
    • Yield: for x in items yield x * 2 — parses correctly (verified via ori parse)
    • Filter: for x in items if x > 0 yield x — parses correctly (verified via ori parse)
    • Labeled: for:outer x in items do ... — parses correctly [done] (2026-02-14)

0.5.18 Loop Expression

  • Audit: Loop expressions — grammar.ebnf § loop_expr [done] (2026-02-14)
    • Basic: loop { body } — parses correctly (verified via ori parse)
    • Labeled: loop:name { body } — parses correctly [done] (2026-02-14)

0.5.19 Labels

  • Audit: Loop labels — grammar.ebnf § label [done] (2026-02-14)
    • :name (no space around colon) — parses correctly (verified via labeled for/loop/break/continue)

0.5.20 Lambda

  • Audit: Simple lambdas — grammar.ebnf § simple_lambda [done] (2026-02-10)

    • Single param: x -> x + 1 — parses correctly
    • Multiple: (a, b) -> a + b — parses correctly
    • No params: () -> 42 — parses correctly
    • Ori Tests: extensive coverage (lambdas used throughout test suite)
  • Audit: Typed lambdas — grammar.ebnf § typed_lambda [done] (2026-02-10)

    • (x: int) -> int = x * 2 — parses correctly (verified via ori parse)

0.5.21 Control Flow

  • Audit: Break expression — grammar.ebnf § break_expr [done] (2026-02-14)

    • Simple: break — parses correctly
    • With value: break result — parses correctly (verified via loop test)
    • Labeled: break:outer, break:outer result — parses correctly [done] (2026-02-14)
  • Audit: Continue expression — grammar.ebnf § continue_expr [done] (2026-02-14)

    • Simple: continue — parses correctly (verified via ori parse)
    • With value: continue replacement — parses correctly [done] (2026-02-13)
    • Labeled: continue:outer — parses correctly [done] (2026-02-14)
  • /tpr-review passed — independent review found no critical or major issues (or all findings triaged)

  • /impl-hygiene-review passed — hygiene review clean. MUST run AFTER /tpr-review is clean.

  • Subsection close-out (0.5) — MANDATORY before starting the next subsection. Run /improve-tooling retrospectively on THIS subsection’s debugging journey (per .claude/skills/improve-tooling/SKILL.md “Per-Subsection Workflow”): which diagnostics/ scripts you ran, where you added dbg!/tracing calls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE /commit-push using a valid conventional-commit type (build(diagnostics): ... — surfaced by section-0.5 retrospectivebuild/test/chore/ci/docs are valid; tools(...) is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 0.5: no tooling gaps”. Update this subsection’s status in section frontmatter to complete.

  • /sync-claude section-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW.

  • Repo hygiene check — run diagnostics/repo-hygiene.sh --check and clean any detected temp files.


0.6 Patterns (verified 2026-03-29)

SPEC: grammar.ebnf § PATTERNS, spec/15-patterns.md

0.6.1 Sequential Patterns

  • Audit: Block expressions and function contracts — grammar.ebnf § block_expr [done] (2026-02-14)

    • Basic: { let x = a \n result } — parses correctly (verified via ori parse)
    • Pre-contract: pre(cond) on function declaration — parses correctly [done] (2026-02-14)
    • Post-contract: post(r -> cond) on function declaration — parses correctly [done] (2026-02-14)
    • Pre-contract with message: pre(cond | "msg") — parses correctly [done] (2026-02-14)
    • Post-contract with message: post(r -> cond | "msg") — parses correctly [done] (2026-02-14)
    • Multiple pre-contracts: pre(a) pre(b) — parses correctly [done] (2026-02-14)
    • Enforcement: pre/post contracts not yet enforced at runtime
  • Audit: Try pattern — grammar.ebnf § try_expr [done] (2026-02-13)

    • try { let x = f()? \n Ok(x) } — parses correctly (verified via ori parse)
  • Audit: Match pattern — grammar.ebnf § match_expr [done] (2026-02-10)

    • match expr { Some(x) -> x, None -> default } — parses correctly (verified via ori parse)
  • Audit: Guard syntax — grammar.ebnf § guard [done] (2026-02-14)

    • .match(...) syntax — verified (now superseded: guards use if syntax per match-arm-comma-separator-proposal)
  • Audit: For pattern — grammar.ebnf § for_pattern [done] (2026-02-10)

    • Basic form: for(over: items, match: x -> x, default: 0) — parses correctly (verified via ori parse)
  • Audit: Catch pattern — grammar.ebnf § catch_expr [done] (2026-02-10)

    • catch(expr: risky_operation) — parses correctly (verified via ori parse)
  • Audit: Nursery pattern — grammar.ebnf § nursery_expr [done] (2026-02-10)

    • nursery(body: n -> ..., on_error: CancelRemaining) — parses correctly (verified via ori parse)

0.6.2 Function Expression Patterns

  • Audit: Pattern arguments — grammar.ebnf § pattern_arg [done] (2026-02-10)

    • Named argument syntax: identifier ":" expression — parses correctly
    • All function_exp patterns use this form — verified across recurse/parallel/spawn/timeout/cache
    • Ori Tests: Named args verified through pattern tests
  • Audit: Recurse pattern — grammar.ebnf § function_exp [done] (2026-02-10)

    • recurse(condition: n -> n > 0, base: 1, step: n -> n - 1) — parses correctly (verified via ori parse)
    • With memo: recurse(..., memo: true) — parses correctly [done] (2026-02-13)
  • Audit: Parallel pattern — grammar.ebnf § function_exp [done] (2026-02-10)

    • parallel(tasks: [...], max_concurrent: 4) — parses correctly (verified via ori parse)
    • With timeout: parallel(tasks: [...], timeout: 10s) — parses correctly [done] (2026-02-13)
  • Audit: Spawn pattern — grammar.ebnf § function_exp [done] (2026-02-10)

    • spawn(tasks: [...], max_concurrent: 10) — parses correctly (verified via ori parse)
  • Audit: Timeout pattern — grammar.ebnf § function_exp [done] (2026-02-10)

    • timeout(op: expr, after: 5s) — parses correctly (verified via ori parse)
  • Audit: Cache pattern — grammar.ebnf § function_exp [done] (2026-02-10)

    • cache(key: k, op: 42, ttl: 1h) — parses correctly (verified via ori parse)
  • Audit: With pattern (RAII) — grammar.ebnf § function_exp [done] (2026-02-14)

    • with(resource: expr, body: f -> ...) — parses correctly with named args (verified via ori parse)
    • with(acquire: expr, action: f -> ..., release: f -> ...) — parses correctly [done] (2026-02-14). Spec uses action: not use: (because use is a reserved keyword)
    • Note: with keyword disambiguated correctly: with Ident = → capability provision, with( → RAII pattern

0.6.3 Type Conversion Patterns

  • Audit: Type conversion calls — grammar.ebnf § function_val [done] (2026-02-10)
    • int(x), float(x), str(x), byte(x) — all parse correctly (verified via ori parse)
    • Ori Tests: tests/spec/expressions/type_conversion.ori — if exists; verified parsing via temp files

0.6.4 Channel Constructors

  • Audit: Channel creation — grammar.ebnf § channel_expr [done] (2026-02-14)
    • channel<int>(buffer: 10) — FIXED [done] (2026-02-14): Added FunctionExpKind::Channel variants + parse_channel_expr with generic type args
    • channel_in<T>(buffer: 5), channel_out<T>(buffer: 5) — FIXED [done] (2026-02-14)
    • channel_all<T>(buffer: 5) — FIXED [done] (2026-02-14)
    • channel(buffer: 10) — still works (no generics)

0.6.5 Match Patterns

  • Audit: Literal patterns — grammar.ebnf § literal_pattern [done] (2026-02-10)

    • Int: 42, -1 — parses correctly in match arms
    • String: "hello" — parses correctly in match arms
    • Bool: true, false — parses correctly in match arms
    • Char: 'a' — parses and evaluates correctly [done] (2026-02-14)
    • Verified: match 42 { 42 -> 1, _ -> 0 } parses correctly (via ori parse)
  • Audit: Identifier pattern — grammar.ebnf § identifier_pattern [done] (2026-02-10)

    • x (binds value) — parses correctly (verified via ori parse)
  • Audit: Wildcard pattern — grammar.ebnf § wildcard_pattern [done] (2026-02-10)

    • _ — parses correctly in match arms (verified via ori parse)
  • Audit: Variant patterns — grammar.ebnf § variant_pattern [done] (2026-02-10)

    • Red, Green, Blue — unit variants parse correctly in match arms (verified via ori parse)
    • Some(x), Ok(value), Err(e) — parses correctly with named-field sum types [done] (2026-02-13)
  • Audit: Struct patterns — grammar.ebnf § struct_pattern (partial) [done] (2026-02-10)

    • { x, y } — parses correctly in match arms (verified via ori parse)
    • { x: px, y: py } — parses correctly [done] (2026-02-13)
    • With rest: { x, .. } — parses and evaluates correctly [done] (2026-02-14)
  • Audit: Tuple patterns — grammar.ebnf § tuple_pattern [done] (2026-02-10)

    • (a, b), (x, y, z) — parse correctly in match arms (verified via ori parse)
  • Audit: List patterns — grammar.ebnf § list_pattern [done] (2026-02-10)

    • [a, b, c] — parses correctly in match arms (verified via ori parse)
    • [head, ..tail] — parses correctly (verified via ori parse)
    • Rest only: [..], [..rest] — parses correctly [done] (2026-02-13)
  • Audit: Range patterns — grammar.ebnf § range_pattern [done] (2026-02-10)

    • 1..10 — parses correctly in match arms (verified via ori parse)
    • 'a'..='z' — char range patterns parse and evaluate correctly [done] (2026-02-14)
  • Audit: Or patterns — grammar.ebnf § or_pattern [done] (2026-02-10)

    • 1 | 2 — parses correctly in match arms (verified via ori parse)
    • Some(1) | Some(2) — variant or-patterns parse correctly [done] (2026-02-13)
  • Audit: At patterns — grammar.ebnf § at_pattern [done] (2026-02-10)

    • x @ 42 — parses correctly in match arms (verified via ori parse)
    • list @ [_, ..] — parses correctly [done] (2026-02-13)

0.6.6 Binding Patterns

  • Audit: Identifier bindings — grammar.ebnf § binding_pattern [done] (2026-02-14)

    • Mutable: let x = 42 — parses correctly (verified via ori parse)
    • Immutable: let $x = 42 in function body — parses and evaluates correctly [done] (2026-02-14)
    • Wildcard: _ — parses correctly (verified in for loops and match arms)
  • Audit: Struct destructure — grammar.ebnf § binding_pattern [done] (2026-02-14)

    • let { x, y } = Point { ... } — parses correctly (verified via ori parse)
    • let { x: px, y: py } = ... — parses correctly [done] (2026-02-13)
    • Immutable: let { $x, $y } = ... — parses and evaluates correctly [done] (2026-02-14)
  • Audit: Tuple destructure — grammar.ebnf § binding_pattern [done] (2026-02-14)

    • let (a, b) = (1, 2) — parses correctly (verified via ori parse)
    • let ($a, $b) = ... — parses and evaluates correctly [done] (2026-02-14)
  • Audit: List destructure — grammar.ebnf § binding_pattern [done] (2026-02-14)

    • let [head, ..tail] = [1, 2, 3] — parses correctly (verified via ori parse)
    • let [$first, $second, ..rest] = ... — parses and evaluates correctly [done] (2026-02-14)
  • /tpr-review passed — independent review found no critical or major issues (or all findings triaged)

  • /impl-hygiene-review passed — hygiene review clean. MUST run AFTER /tpr-review is clean.

  • Subsection close-out (0.6) — MANDATORY before starting the next subsection. Run /improve-tooling retrospectively on THIS subsection’s debugging journey (per .claude/skills/improve-tooling/SKILL.md “Per-Subsection Workflow”): which diagnostics/ scripts you ran, where you added dbg!/tracing calls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE /commit-push using a valid conventional-commit type (build(diagnostics): ... — surfaced by section-0.6 retrospectivebuild/test/chore/ci/docs are valid; tools(...) is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 0.6: no tooling gaps”. Update this subsection’s status in section frontmatter to complete.

  • /sync-claude section-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW.

  • Repo hygiene check — run diagnostics/repo-hygiene.sh --check and clean any detected temp files.


0.7 Constant Expressions (verified 2026-03-29)

SPEC: grammar.ebnf § CONSTANT EXPRESSIONS, spec/12-constants.md, spec/24-constant-expressions.md

  • Audit: Literal const expressions — grammar.ebnf § const_expr [done] (2026-02-10)

    • let $A = 42, let $B = true, let $C = "hello" — all parse correctly (verified via ori parse)
  • Audit: Arithmetic const expressions — grammar.ebnf § const_expr [done] (2026-02-14)

    • let $D = $A + 1, let $E = $A * 2 — parses correctly (verified via ori parse)
    • Fix: Replaced parse_literal_expr() with parse_expr() in constant initializer parsing
  • Audit: Comparison const expressions — grammar.ebnf § const_expr [done] (2026-02-14)

    • let $F = $A > 0 — parses correctly (verified via ori parse)
  • Audit: Logical const expressions — grammar.ebnf § const_expr [done] (2026-02-14)

    • let $G = $A && $B — parses correctly (verified via ori parse)
  • Audit: Grouped const expressions — grammar.ebnf § const_expr [done] (2026-02-14)

    • let $H = ($A + 1) * 2 — parses correctly (verified via ori parse)

0.8 Section Completion Checklist (verified 2026-03-29)

STATUS: In Progress — Re-verified 2026-03-29. 8/10 checklist items complete, 2 blocked. Remaining: 0.4 audit (blocked-by:19, only impl Trait), 0.6 audit (blocked-by:23, only runtime enforcement). All unblocked parser work is complete. 4181 Ori tests pass (confirmed), 42 skipped.

INCOMPLETE MATRIX: Grammar gap analysis found 3 major missing productions (while_expr, labeled_block, capset_decl) and systemic absence of negative parser tests.

  • All lexical grammar items audited and tested (0.1) [done] (2026-02-10) (verified 2026-03-29)
  • All source structure items audited and tested (0.2) [done] (2026-02-13) (verified 2026-03-29) — file attributes, extern as, C variadics all work now
  • All declaration items audited and tested (0.3) — capset_decl (0.3.9) missing
  • All type items audited and tested (0.4) — 30/34 complete; only impl Trait remains (0.4.2, 4 items)
  • All expression items audited and tested (0.5) — while_expr (0.5.9) and labeled_block (0.5.10) missing
  • All pattern items audited and tested (0.6) — 93/94 complete; only runtime contract enforcement remains (0.6.1, 1 item)
  • All constant expression items audited and tested (0.7) [done] (2026-02-14) (verified 2026-03-29)
  • Run cargo t -p ori_parse — all parser tests pass [done] (2026-02-14) (verified 2026-03-29)
  • Run cargo t -p ori_lexer — all lexer tests pass (277 passed) [done] (2026-02-14) (verified 2026-03-29)
  • Run cargo st tests/ — 4181 passed, 0 failed, 42 skipped [done] (verified 2026-03-29)
  • /tpr-review passed — independent Codex review found no critical or major issues (or all findings triaged)
  • /impl-hygiene-review passed — implementation hygiene review clean (phase boundaries, SSOT, algorithmic DRY, naming). MUST run AFTER /tpr-review is clean.
  • /improve-tooling retrospective completed — MANDATORY at section close, after both reviews are clean. Reflect on the section’s debugging journey (which diagnostics/ scripts you ran, which command sequences you repeated, where you added ad-hoc dbg!/tracing calls, where output was hard to interpret) and identify any tool/log/diagnostic improvement that would have made this section materially easier OR that would help the next section touching this area. Implement every accepted improvement NOW (zero deferral) and commit each via SEPARATE /commit-push. The retrospective is mandatory even when nothing felt painful — that is exactly when blind spots accumulate. See .claude/skills/improve-tooling/SKILL.md “Retrospective Mode” for the full protocol.
  • NEEDS TESTS: Negative parser tests — #compile_fail tests verifying invalid syntax is rejected with correct error codes (E0xxx/E1xxx)
    • Invalid syntax rejection in tests/spec/lexical/ (currently 0 #compile_fail tests)
    • Invalid syntax rejection in tests/spec/expressions/ (currently 0 #compile_fail tests)
    • Error recovery continues past first error
  • NEEDS TESTS: while expression spec tests — tests/spec/expressions/while.ori (basic, labeled, break, continue, nested)
  • NEEDS TESTS: Labeled block spec tests — tests/spec/expressions/labeled_blocks.ori (block:name { ... break:name value })
  • NEEDS TESTS: Capset declaration spec tests — tests/spec/declarations/capsets.ori (capset Net = Http, Dns, Tls)

Exit Criteria: Every grammar production in grammar.ebnf has verified parser support with tests.

Remaining Parser Bugs (verified 2026-02-13):

  • Const functions ($name (params)) — rejected
  • Computed constants (let $D = $A + 1) — FIXED [done] (2026-02-14)
  • impl Trait in type position — rejected
  • Associated type constraints (where I.Item == int) — == rejected
  • Floating tests (tests _) — FIXED [done] (2026-02-14)
  • Typed constants (let $X: int) — FIXED [done] (2026-02-14)
  • Channel generic syntax (channel<int>) — FIXED [done] (2026-02-14)
  • Struct rest pattern ({ x, .. }) — FIXED [done] (2026-02-14)
  • .match() method syntax — FIXED [done] (2026-02-14) — desugars expr.match { arms } to match expr { arms } at parser level
  • with() RAII pattern (acquire:/action:/release:) — FIXED [done] (2026-02-14) — was doc error: spec uses action: not use: (use is reserved keyword)
  • Function-level contracts (pre()/post()) — FIXED [done] (2026-02-14)
  • Immutable binding in function body (let $x = 42) — FIXED [done] (2026-02-14)
  • Labeled continue (continue:outer) — FIXED [done] (2026-02-14)
  • Char patterns in match ('a', 'a'..='z') — FIXED [done] (2026-02-14)

Fixed since 2026-02-10 (23 items): File attributes, extern as alias, C variadics, pattern params, guard clauses, default params, variadic params, #repr/#target/#cfg attributes, fixed-capacity lists, length placeholder, try ? inside try { }, const generic type args (Array<int, $N>), const expressions in types, const bounds in where clauses (where N > 0), labeled continue (continue:outer), function-level contracts (pre()/post()), computed constants (let $D = $A + 1), struct rest pattern ({ x, .. }), immutable bindings in function bodies (let $x, let ($a, $b), let { $x }, let [$h, ..]), with() RAII pattern (acquire:/action:/release: — was doc error, spec uses action: not use:), .match() method syntax (expr.match { arms } desugars to match expr { arms })

  • /tpr-review passed — independent review found no critical or major issues (or all findings triaged)
  • /impl-hygiene-review passed — hygiene review clean. MUST run AFTER /tpr-review is clean.
  • Subsection close-out (0.8) — MANDATORY before starting the next subsection. Run /improve-tooling retrospectively on THIS subsection’s debugging journey (per .claude/skills/improve-tooling/SKILL.md “Per-Subsection Workflow”): which diagnostics/ scripts you ran, where you added dbg!/tracing calls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE /commit-push using a valid conventional-commit type (build(diagnostics): ... — surfaced by section-0.8 retrospectivebuild/test/chore/ci/docs are valid; tools(...) is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 0.8: no tooling gaps”. Update this subsection’s status in section frontmatter to complete.
  • /sync-claude section-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW.
  • Repo hygiene check — run diagnostics/repo-hygiene.sh --check and clean any detected temp files.

0.9 Parser Bugs (from Comprehensive Tests) (verified 2026-03-29)

STATUS: Re-verified 2026-03-29. Many items previously marked “STILL BROKEN” now parse correctly. 19+ fixed, 3 remaining blocked.

POLICY: Skipping tests is NOT acceptable. Every test must pass. If a feature is tested, it must work. Fix the code, not the tests.

This section documents parser-only bugs discovered by the comprehensive test suite. Evaluator/type checker bugs are tracked in Section 23: Full Evaluator Support.

0.9.1 Parser/Syntax Bugs — STILL BROKEN (verified 2026-02-13)

These features fail at the parse phase — the parser does not recognize the syntax.

  • Implement: Const generics parser support [done] (2026-02-13)

    • Parser: $N: int in generic parameters — was already working
    • Syntax: Array<int, $N> — const expressions in type arguments (NEW)
    • Syntax: [int, max $N] — const expressions in fixed-list capacity (NEW)
    • Syntax: where N > 0 — const bounds in where clauses (NEW)
  • Implement: Associated type constraints in where clauses

    • Syntax: where I.Item == intBROKEN: parser expects :, finds ==
  • Implement: Const functions

    • Syntax: $add (a: int, b: int) = a + bBROKEN: parser error
  • Implement: Computed constants [done] (2026-02-14)

    • Syntax: let $D = $A + 1 — parses correctly (constant initializer now uses general expression parser)
  • Implement: impl Trait in type position

    • Syntax: @f () -> impl IteratorBROKEN: parser rejects impl in type
  • Implement: Channel generic syntax [done] (2026-02-14)

    • Syntax: channel<int>(buffer: 10) — FIXED: detect channel identifiers in parse_primary, parse_channel_expr with generic type args
  • Implement: Struct rest pattern in match [done] (2026-02-14)

    • Syntax: { x, .. } — parses and evaluates correctly [done] (2026-02-14)
  • Implement: .match() method syntax [done] (2026-02-14)

    • Syntax: 42.match { ... } — method-style match desugars to match 42 { ... } at parse level [done] (2026-02-14)
  • Implement: Immutable bindings in function bodies [done] (2026-02-14)

    • Syntax: let $x = 42 inside function — parses and evaluates correctly [done] (2026-02-14)
    • Syntax: let ($a, $b) = ... — tuple destructuring with $ [done] (2026-02-14)
    • Syntax: let { $x, $y } = ... — struct destructuring with $ [done] (2026-02-14)
    • Syntax: let [$first, ..rest] = ... — list destructuring with $ [done] (2026-02-14)
  • Implement: Floating tests with _ target [done] (2026-02-14)

    • Syntax: @t tests _ () -> void = ... — parses correctly [done] (2026-02-14)
  • Implement: Typed constants [done] (2026-02-14)

    • Syntax: let $MAX_SIZE: int = 1000 — parses correctly [done] (2026-02-14)
  • Implement: Function-level contracts (pre()/post()) [done] (2026-02-14)

    • Syntax: pre(cond) on function declaration — parses correctly [done] (2026-02-14)
    • Syntax: post(r -> cond) on function declaration — parses correctly [done] (2026-02-14)
    • Syntax: pre(c | "msg") post(r -> c | "msg") — parses correctly [done] (2026-02-14)
    • Enforcement: Runtime contract execution tracked in Section 23
  • Implement: with(acquire:, action:, release:) RAII pattern [done] (2026-02-14)

    • Syntax: with(acquire: expr, action: f -> ..., release: f -> ...) — parses correctly. Spec uses action: not use: (use is reserved keyword)
  • Implement: Labeled continue [done] (2026-02-14)

    • Syntax: continue:outer — parses correctly [done] (2026-02-14)
  • Implement: Char patterns in match [done] (2026-02-14)

    • Syntax: 'a' in match arm — parses and evaluates correctly
    • Syntax: 'a'..='z' range — parses and evaluates correctly

0.9.2 Previously Fixed Bugs — VERIFIED WORKING

These features were previously reported as broken but now parse correctly.

  • Fixed: Guard clauses — @f (n: int) -> int if n > 0 = n [done] (2026-02-13)

  • Fixed: Pattern params — @fib (0: int) -> int = 1 [done] (2026-02-13)

  • Fixed: Default params — @greet (name: str = "World") -> str [done] (2026-02-13)

  • Fixed: Variadic parameters — @sum (nums: ...int) [done] (2026-02-13)

  • Fixed: #repr attribute — #repr("c") [done] (2026-02-13)

  • Fixed: #target attribute — #target(os: "linux") [done] (2026-02-13)

  • Fixed: #cfg attribute — #cfg(debug) [done] (2026-02-13)

  • Fixed: Fixed-capacity list type — [int, max 10] [done] (2026-02-13)

  • Fixed: File-level attributes — #!target(os: "linux") [done] (2026-02-13)

  • Fixed: Extern as alias — @_sin (x: float) -> float as "sin" [done] (2026-02-13)

  • Fixed: C variadics — @printf (fmt: CPtr, ...) -> c_int [done] (2026-02-13)

  • Fixed: Try ? inside try — try { let x = f()? \n Ok(x) } [done] (2026-02-13)

  • Fixed: Length placeholder — list[# - 1] [done] (2026-02-13)

  • Fixed: Spread in function calls — sum(...list) [done] (2026-02-10)

  • Fixed: timeout as identifier — let timeout = 5 [done] (2026-02-10)

  • Fixed: List spread syntax — [...result, i] [done] (2026-02-10)

  • Fixed: Map spread syntax — {...base, "c": 3} [done] (2026-02-10)

  • Fixed: Tuple destructuring in for loops — for (k, v) in m do ... — parser dispatch via is_named_arg_at(2) (commit 0aae9265, verified 2026-02-24)

  • Fixed: Multiple derives — #derive(Eq, Clone, Debug) [done] (2026-02-10)

  • Fixed: as/as? type conversion — 42 as float, "42" as? int [done] (2026-02-10)

  • Fixed: Wildcard pattern in for loops — for _ in 0..n do ... [done] (2026-02-10)

  • Fixed: Context-sensitive pattern keywords — let timeout = 5, let cache = 10 [done] (2026-02-10)

  • /tpr-review passed — independent review found no critical or major issues (or all findings triaged)

  • /impl-hygiene-review passed — hygiene review clean. MUST run AFTER /tpr-review is clean.

  • Subsection close-out (0.9) — MANDATORY before starting the next subsection. Run /improve-tooling retrospectively on THIS subsection’s debugging journey (per .claude/skills/improve-tooling/SKILL.md “Per-Subsection Workflow”): which diagnostics/ scripts you ran, where you added dbg!/tracing calls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE /commit-push using a valid conventional-commit type (build(diagnostics): ... — surfaced by section-0.9 retrospectivebuild/test/chore/ci/docs are valid; tools(...) is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 0.9: no tooling gaps”. Update this subsection’s status in section frontmatter to complete.

  • /sync-claude section-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW.

  • Repo hygiene check — run diagnostics/repo-hygiene.sh --check and clean any detected temp files.


NOTE: Type checker and evaluator bugs have been moved to Section 23: Full Evaluator Support.


Completion Summary

Full Audit Completed: 2026-02-10

Systematic ori parse verification of every grammar production against actual parser behavior.

Previously Fixed (verified working):

  1. div operator in match_multiplicative_op()
  2. Spread in function calls (sum(...list))
  3. Context-sensitive keywords (timeout, parallel, cache as identifiers)
  4. List spread ([...a, ...b]), map spread ({...base, key: val})
  5. Tuple destructure in for (for (k, v) in m)
  6. Multiple derives (#derive(Eq, Clone, Debug))
  7. as/as? type conversion operators
  8. Wildcard in for loops (for _ in range)

Verified Parser Bugs — 24 items originally, 19+ fixed, 3 remain (blocked): (verified 2026-03-29)

  1. Guard clauses (if before =) — parser rejects FIXED [done]
  2. List/pattern params (@fib (0: int)) — parser rejects FIXED [done]
  3. Const generics ($ in generics) — parser rejects FIXED [done] (2026-02-13)
  4. Variadic params (...int) — parser rejects FIXED [done]
  5. #repr/#target/#cfg attributes — unknown attribute error
  6. Associated type constraints (where I.Item == int) — == rejected
  7. Const functions ($name (params)) — parser error
  8. Computed constants (let $D = $A + 1) — FIXED [done] (2026-02-14)
  9. Fixed-capacity lists ([T, max N]) — comma rejected in type
  10. impl Trait in type position — parser rejects
  11. Channel generics (channel<int>) — FIXED [done] (2026-02-14)
  12. Struct rest pattern ({ x, .. }) — .. rejected
  13. .match() method syntax — keyword conflict
  14. with() RAII pattern (acquire:/use:/release:) — named arg rejection
  15. File attributes (#!target(...)) — ! rejected
  16. Extern as alias — rejected
  17. C variadics (... in params) — rejected
  18. Floating tests (tests _) — FIXED [done] (2026-02-14)
  19. Typed constants (let $X: int = 1000) — FIXED [done] (2026-02-14)
  20. Try ? inside try() — rejected
  21. Function-level contracts (pre()/post()) — FIXED [done] (2026-02-14)
  22. Length placeholder (#) — attribute marker conflict
  23. Immutable binding in function body (let $x = 42) — FIXED [done] (2026-02-14)
  24. .match() guard method syntax — RESOLVED: guards now use if syntax (match-arm-comma-separator-proposal)

Known Limitations (Parser works, but semantics incomplete — tracked in Section 23):

  • ?? operator: Parses but evaluator support incomplete
  • Primitive trait methods: Parse but evaluator doesn’t resolve
  • Map indexing semantics: Parses but returns wrong type

Notes

  • This section intentionally overlaps with other roadmap sections
  • Other sections add semantics; this section ensures syntax parses
  • Work can proceed in any order within this section
  • Parser tests should verify both success and error cases
  • Error messages should include spans for IDE integration

Grammar Inconsistencies Identified

The following grammar inconsistencies were identified during the audit and require resolution:

1. Extension Generics (grammar.ebnf § extension_def) — RESOLVED

Resolution: Updated grammar.ebnf to support generics and any type in extensions:

extension_def = "extend" [ generics ] type [ where_clause ] "{" { method } "}" .

This allows:

extend<T: Clone> [T] { ... }           // Angle bracket generics
extend [T] where T: Clone { ... }       // List type with where clause
extend Iterator where Self.Item: Add { ... }

2. Bounded Trait Objects (grammar.ebnf § type) — RESOLVED

Resolution: Added trait_object_bounds production to grammar.ebnf:

type = type_path [ type_args ]
     | trait_object_bounds            /* Printable + Hashable */
     | list_type | fixed_list_type | map_type | tuple_type | function_type
     | impl_trait_type .

trait_object_bounds = type_path "+" type_path { "+" type_path } .

Resolution Status: All grammar inconsistencies resolved.


0.10 Block Expression Syntax (PRIORITY) (verified 2026-03-29)

Proposal: proposals/approved/block-expression-syntax.md Migration script: scripts/migrate_block_syntax.py

This section blocks all other roadmap work. Every feature built on run()/match()/try() syntax creates migration debt. Complete this before continuing.

Overview

Replace parenthesized function_seq syntax with curly-brace block expressions. Remove run() entirely. Move contracts to function-level pre()/post() declarations.

OldNew
run(a, b, c){ a \n b \n c }
match(expr, P -> e)match expr { P -> e }
try(a, b)try { a \n b }
loop(run(a, b))loop { a \n b }
unsafe(run(a, b))unsafe { a \n b }
run(pre_check: c, body, post_check: r -> c)pre(c) post(r -> c) on function decl

Implementation

Phase 1: Parser — Block Expressions

  • Implement: Newline-as-separator tokenization inside { } blocks — N/A: semicolons-only design decision (2026-02-20)
  • Implement: Block expression parsing ({ block_body }) — semicolons as separators (2026-02-20)
    • Rust Tests: ori_parse/src/tests/parser.rstest_parse_block_expr
    • Ori Tests: tests/spec/expressions/block_scope.ori
  • Implement: Optional semicolon after }-ending expression statements — for...do { }, while...do { }, loop { }, if...then...else { }, match { } no longer require trailing ; when used as statements. Approved proposal: optional-semicolon-after-block-expressions-proposal.md. Grammar updated (grammar.ebnf block_ending_expression production). Parser change in blocks.rs: after parsing an expression, if last token is }, consume ; if present but don’t require it.
    • Rust Tests: ori_parse/src/tests/parser.rstest_optional_semicolon_after_block_expression
    • Ori Tests: tests/spec/expressions/ — block expressions without trailing ;
  • Implement: Block vs map vs struct disambiguation (2-token lookahead) (2026-02-20)
    • Rust Tests: ori_parse/src/tests/parser.rs — block/map disambiguation
    • Ori Tests: tests/spec/expressions/block_scope.ori
  • Implement: Balanced delimiter continuation rules — N/A: only needed for newline separators (2026-02-20)

Phase 2: Parser — Construct Migration

  • Implement: match expr { arms } syntax (scrutinee before block) (2026-02-20)
    • Rust Tests: ori_parse/src/tests/parser.rs — match block syntax
    • Ori Tests: All spec tests migrated to new syntax
  • Implement: try { block_body } syntax (2026-02-20)
    • Ori Tests: All spec tests migrated to new syntax
  • Implement: loop { block_body } syntax (drop parens) (2026-02-20)
    • Ori Tests: All spec tests migrated to new syntax
  • Implement: unsafe { block_body } syntax (block-only form) (2026-02-21)
    • Rust Tests: Parser unit tests for block syntax + rejection of paren form
    • Ori Tests: tests/spec/capabilities/unsafe_block.ori — 6 test cases
  • Implement: for...do { block_body } and for...yield { block_body } (automatic — blocks are expressions) (2026-02-20)
  • Implement: Remove old run()/match()/try() paren forms from parser (2026-02-20)
    • Rust Tests: Old syntax produces helpful error messages
    • Ori Tests: All AOT and spec tests migrated

Phase 3: Parser — Function-Level Contracts

  • Implement: pre(condition) parsing between return type and = (2026-02-21)
    • Rust Tests: ori_parse/src/grammar/item/function/tests.rs — pre contract parsing (4 tests)
    • Ori Tests: tests/spec/declarations/contracts/pre_basic.ori
  • Implement: post(r -> condition) parsing between return type and = (2026-02-21)
    • Rust Tests: ori_parse/src/grammar/item/function/tests.rs — post contract parsing (4 tests)
    • Ori Tests: tests/spec/declarations/contracts/post_basic.ori
  • Implement: Multiple pre()/post() declarations (2026-02-21)
    • Ori Tests: tests/spec/declarations/contracts/multiple_contracts.ori
  • Implement: Message syntax pre(condition | "message") (2026-02-21)
    • Ori Tests: Tests included in pre_basic.ori and post_basic.ori (message variants)
  • Implement: IR changes — PreContract/PostContract structs + pre_contracts/post_contracts fields on Function (2026-02-21)

Phase 4: Migration

  • Run: scripts/migrate_block_syntax.py on all documentation (.md files) (2026-02-20)
  • Manual: Migrate pre_check:/post_check: references to function-level pre()/post() (2026-02-21) — README examples, parser context comment, design doc
  • Run: scripts/migrate_block_syntax.py on all .ori test files (2026-02-20)
  • Update: grammar.ebnf with new block/match/try rules (2026-02-20)
  • Update: .claude/rules/ori-syntax.md with new syntax (2026-02-20)
  • Update: Spec files with new syntax (2026-02-20)
  • Verify: ./test-all.sh passes with new syntax (10,219 tests passing) (2026-02-20)

Phase 5: Formatter

  • Implement: Blank-line-before-result enforcement (2026-02-21)
    • Block and try-block: emit blank line before result when 2+ statements precede it
    • Spec rule: 16-formatting.md:74-85
  • Implement: Match trailing comma on every arm (2026-02-21)
    • Always emit comma after every arm including last (spec: 16-formatting.md:786)
  • Update: Golden tests updated to match new formatting (19 files) (2026-02-21)
  • Implement: Contract formatting (pre/post between signature and =)
    • IR unblocked: Function now has pre_contracts/post_contracts fields (2026-02-21)
    • Still blocked: formatter needs contract emit logic (depends on 15D contract enforcement design)
  • Fix: Formatter double-emits $ for immutable local bindings (2026-02-21)
    • emit_stmt() emits let $ AND emit_binding_pattern() emits $ → produces let $$x
    • Root cause: $ prefix emitted in two independent locations (stacked.rs:211, patterns.rs:135-137)
    • Parser is correct (strips $, sets Immutable); formatter had the bug
    • Fix: Removed $ from emit_stmt in all 3 renderers (stacked, inline, broken); emit_binding_pattern is sole owner

Phase 6: Dead Code Cleanup — FunctionSeq::Run Removal

Completed as part of Block Unification plan (plans/block_unify/), commit 01c43e21. Removed FunctionSeq::Run, SeqBinding, CheckExpr, CheckRange and all downstream consumers across 37 files in 9 crates. FunctionSeq reduced from 4 → 3 variants (Try, Match, ForPattern).

  • Remove: FunctionSeq::Run variant from ori_ir/src/ast/patterns/seq/mod.rs (2026-02-20)

  • Remove: Formatter dead paths (2026-02-20):

    • ori_fmt/src/formatter/stacked.rsemit_function_seq() Run arm + emit_run_with_checks()
    • ori_fmt/src/rules/run_rule.rs — entire module (RunRule, RunContext, is_run())
    • ori_fmt/src/width/mod.rsFunctionSeq::Run arm in width calculation
  • Remove: Type checker dead paths: ori_types/src/infer/expr/sequences.rs, ori_types/src/infer/expr/mod.rs (2026-02-20)

  • Remove: Canon lowering dead paths: ori_canon/src/lower/sequences.rs (2026-02-20)

  • Remove: Incremental copier dead paths: ori_parse/src/incremental/copier.rs (2026-02-20)

  • Remove: Visitor dead paths: ori_ir/src/visitor.rs (2026-02-20)

  • Remove: Test references: ori_fmt/src/width/tests.rs, ori_ir/src/ast/patterns/seq/tests.rs, ori_types/src/infer/expr/tests.rs (2026-02-20)

  • Verify: ./test-all.sh passes after removal (10,215+ tests passing) (2026-02-20)

  • /tpr-review passed — independent review found no critical or major issues (or all findings triaged)

  • /impl-hygiene-review passed — hygiene review clean. MUST run AFTER /tpr-review is clean.

  • Subsection close-out (0.10) — MANDATORY before starting the next subsection. Run /improve-tooling retrospectively on THIS subsection’s debugging journey (per .claude/skills/improve-tooling/SKILL.md “Per-Subsection Workflow”): which diagnostics/ scripts you ran, where you added dbg!/tracing calls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE /commit-push using a valid conventional-commit type (build(diagnostics): ... — surfaced by section-0.10 retrospectivebuild/test/chore/ci/docs are valid; tools(...) is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 0.10: no tooling gaps”. Update this subsection’s status in section frontmatter to complete.

  • /sync-claude section-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW.

  • Repo hygiene check — run diagnostics/repo-hygiene.sh --check and clean any detected temp files.


Verification Log (2026-03-29)

Verified by: Claude Opus 4.6 (1M context) verification agent Test execution: 4181 spec tests pass, 0 fail, 42 skipped. 277 lexer unit tests pass. 267 oric parse tests pass.

Hygiene audit:

  • File sizes: All parser source files under 500-line limit. Largest: collections.rs (449), postfix.rs (442).
  • TODOs/FIXMEs: Zero in ori_parse/src/ and ori_lexer/src/.
  • Plan annotations: Zero stale plan annotations in parser source.
  • Phase bleeding: No type checking or evaluation logic in parser code.
  • Dead code: No commented-out code in parser source.
  • Sibling test pattern: Proper sibling test files (ty/tests.rs, function/tests.rs, generics/tests.rs, attr/tests.rs, impl_def/tests.rs, config/tests.rs).
  • Commented-out test files: 4 files (constants.ori, generics.ori, clause_params.ori, where_clause.ori) — all correctly documented as evaluator/typeck blockers.

Findings summary:

  • 4 major findings: 3 missing grammar productions (while_expr, labeled_block, capset_decl), systemic absence of negative parser tests
  • 4 minor findings: pipe_expr/compound_assignment/argument_punning not documented (tests exist and pass), test count claims corrected
  • 5 tracked/known: impl Trait (blocked-by:19), const functions (blocked-by:18), associated type constraints (blocked-by:3), contract formatting (blocked-by:15D), TPR review outstanding