Section 06: Protocol Builtin Verification Matrix
RESET (2026-04-11): All work in this section was produced by an autopilot session with inadequate planning and TPR oversight. Implementation code may exist in the codebase (commits from the autopilot session) but the design, test coverage, and verification cannot be trusted as valid. This section must be re-done from scratch with proper planning, review (
/review-plan), and verification (/tpr-review+/impl-hygiene-review). The existing code should be audited during re-implementation — it may be partially reusable but must not be assumed correct.
Status: In Progress (close-out: TPR + hygiene + tooling sweep pending)
Goal: Verify that ProtocolBuiltin ownership values are correctly defined (ori_ir) and consumed (ori_arc — borrow inference and AIMS contract seeding), with end-to-end validation through AOT leak checks (ori_llvm). Note: try_emit_protocol() in ori_llvm dispatches on from_name() and type information — it does NOT read arg_ownership(). The ownership consumers are purely in ori_arc; LLVM correctness is validated end-to-end via AOT tests, not by direct ownership-table consumption.
Protocol builtins (compiler/ori_ir/src/builtin_constants/protocol/mod.rs) are compiler-internal functions emitted by ARC lowering that carry per-argument ownership semantics. The critical failure mode is not that ProtocolBuiltin::Index.arg_ownership() returns the wrong constant (that is a tautology test) — it is that the consumers of these values (seed_builtin_contracts, annotate_arg_ownership, promote_callee_args) fail to use them correctly, producing wrong MemoryContracts or wrong ArgOwnership annotations. Note: try_emit_protocol in ori_llvm dispatches on ProtocolBuiltin::from_name() and type information — it does NOT read arg_ownership(). The ownership consumers are purely in ori_arc; LLVM is verified end-to-end via AOT tests. The __index RC leak was caused by exactly this class of bug — the ownership constant was correct, but the consumer fell through to the “unknown callee -> all Owned” default.
Success Criteria:
- Audit confirms existing
protocol/tests.rs(93 lines, 10 tests) already pins all ownership values — no new IR-level pin tests needed - New
ori_arcconsumer tests verify thatseed_builtin_contractsproduces correctMemoryContractparams for each protocol builtin (access, consumption, cardinality=Once fields — all three dimensions pinned) - New
ori_arcconsumer tests verify thatannotate_arg_ownershipproduces correctArgOwnershipvectors when called with protocol builtin callees - New
ori_arcconsumer tests verify thatpromote_callee_argscorrectly promotes/borrows params at protocol builtin call sites - AOT programs pass
ORI_CHECK_LEAKS=1across type x pattern matrix:[str],[int],{str: int},{int: str}x full iteration, break, yield, nested. Note:Set<int>blocked by BUG-04-065 (crashes);Set<str>verified via existing tests - At least one negative pin demonstrates that wrong ownership (e.g., IterDrop=Borrowed) produces a double-free or leak
- Exhaustiveness guard:
ProtocolBuiltin::ALL.len() == 5assertion prevents silent additions -
IterDropdoc comment fixed: “borrowed (freed internally)” -> “owned (consumed by cleanup)”
Context: The ProtocolBuiltin enum has 5 variants. The ownership matrix is small and fixed:
| Variant | Arg 0 | Arg 1 | Intercepted | Consumers |
|---|---|---|---|---|
Index | Borrowed | Borrowed | Yes | seed_builtin_contracts, annotate_arg_ownership, promote_callee_args |
Iter | Borrowed | — | No | seed_builtin_contracts, borrowing_builtin_names |
IterNext | Owned | Borrowed | Yes | seed_builtin_contracts, annotate_arg_ownership, promote_callee_args |
IterDrop | Owned | — | No | seed_builtin_contracts, annotate_arg_ownership, promote_callee_args |
CollectSet | Owned | — | Yes | seed_builtin_contracts, annotate_arg_ownership, promote_callee_args |
Existing test coverage (ALREADY DONE — do NOT rewrite):
compiler/ori_ir/src/builtin_constants/protocol/tests.rs(93 lines, 10 tests): pinsarg_count(),arg_ownership()per variant,is_intercepted(),from_name()round-trip, exhaustiveness overALLcompiler/ori_arc/src/aims/builtins/tests.rs(151 lines, 7 tests): verifiesseed_builtin_contractspopulates entries for all protocol builtinscompiler/ori_arc/src/borrow/builtins/tests.rs(376 lines, 18 tests): verifiesborrowing_builtin_namesincludes all-borrowed protocols,protocol_builtins_borrowing_syncchecks synccompiler/ori_llvm/tests/aot/iterator_drop.rs: exercisesIterDropownership via enum/struct/tuple iterator scope exitcompiler/ori_llvm/tests/aot/iter_rc_matrix.rs(88 tests): 6 types x 8 patterns x 2 loop variants — exercisesIter,IterNext,IterDropthrough full AOT pipelinecompiler/ori_llvm/tests/aot/sets.rs: exercisesCollectSetvia set constructioncompiler/ori_llvm/tests/aot/fat_ptr_iter/method_collect.rs: exercisescollect()path including__collect_set
What is MISSING (the actual work for this section):
- ori_arc consumer-level tests — existing tests verify constants and set membership, but do NOT verify that
seed_builtin_contractsproduces correctMemoryContractfield values (access class, consumption, cardinality), thatannotate_arg_ownershipproduces correctArgOwnershipvectors for protocol callees, or thatpromote_callee_argscorrectly promotes/borrows at protocol call sites - Negative pins — no test verifies that wrong ownership produces observable failure
- Map/Set type coverage in AOT —
iter_rc_matrix.rscoversstr,[int],Option<str>, closures, structs, maps but Set coverage is limited;__indexon maps is not explicitly tested for RC balance - ORI_AUDIT_CODEGEN=1 wiring — the AOT harness sets
ORI_CHECK_LEAKS=1but does NOT setORI_AUDIT_CODEGEN=1; codegen audit is not exercised in protocol tests
Reference implementations:
- Rust
tests/codegen/intrinsics/— pins codegen patterns for compiler intrinsics. - Swift ARC tests — positive + negative RC pairing per protocol.
Depends on: Section 01 (blocking codegen audit behavior needed for RC balance verification under ORI_AUDIT_CODEGEN=1).
06.1 Existing Test Audit & Gap-Fill
File(s): compiler/ori_ir/src/builtin_constants/protocol/tests.rs, compiler/ori_ir/src/builtin_constants/protocol/mod.rs
Audit the existing 10 tests in protocol/tests.rs and confirm they pin all ownership values. Fix the stale IterDrop doc comment in the source. The existing tests are comprehensive for IR-level pinning — this subsection is an audit, not a rewrite.
-
Audit existing tests — read
compiler/ori_ir/src/builtin_constants/protocol/tests.rsand verify the following are covered (check, do NOT rewrite):pin_arg_counts— all 5 variants’ arg counts pinnedall_variants_covered—ALL.len() == 5,from_nameround-trip, ownership len == arg countfrom_name_returns_none_for_unknown— negative: unknown names returnNoneindex_ownership_is_all_borrowed— both args Borrowediter_next_ownership_is_owned_borrowed— arg 0 Owned, arg 1 Borrowediter_ownership_is_borrowed— single arg Borrowediter_drop_ownership_is_owned— single arg Owned (with doc comment explaining the Borrowed→Owned history)collect_set_ownership_is_owned— single arg Ownedis_intercepted_matches_dispatch—Iter/IterDropnot intercepted, others interceptedis_intercepted_exhaustive— all variants have defined interception status- Result: All 10 tests confirmed — no gaps for IR-level ownership pinning (2026-04-12)
-
Fix stale
IterDropdoc comment incompiler/ori_ir/src/builtin_constants/protocol/mod.rsline 25: change"Iterator cleanup. Iterator state borrowed (freed internally)."to"Iterator cleanup. Iterator handle owned (consumed by cleanup)."— the ownership was changed from Borrowed to Owned (TPR-07-008) but the doc comment was not updated. This is a DRIFT finding. (Fixed 2026-04-12) -
Subsection close-out (06.1) — MANDATORY before starting 06.2:
- All tasks above are
[x]and the subsection’s behavior is verified - Update this subsection’s
statusin section frontmatter tocomplete
- All tasks above are
06.2 ori_arc Consumer Verification
File(s): compiler/ori_arc/src/aims/builtins/tests.rs, compiler/ori_arc/src/borrow/builtins/tests.rs, compiler/ori_arc/src/rc_insert/tests.rs
The critical failure mode is not the constants — it is the consumers. Test that seed_builtin_contracts, annotate_arg_ownership, and promote_callee_args produce correct output from the ProtocolBuiltin ownership values. This is where the __index RC leak actually occurred: the constant was correct but the consumer fell through to the wrong default.
Key consumers in ori_arc:
seed_builtin_contracts()(compiler/ori_arc/src/aims/builtins/mod.rs:77-79) — convertsProtocolArgOwnershiptoParamContractviaprotocol_contract(), inserting into the signature mapannotate_arg_ownership()(compiler/ori_arc/src/rc_insert/annotate.rs:78-91) — looks up protocol builtins inBuiltinOwnershipSets.protocoland maps toArgOwnership::Owned/Borrowedpromote_callee_args()(compiler/ori_arc/src/borrow/update.rs) — promotes parameters to Owned based on callee argument ownership; protocol builtins are consulted viaBuiltinOwnershipSets
-
Add consumer-level tests to
compiler/ori_arc/src/aims/builtins/tests.rs— verify thatseed_builtin_contractsproducesMemoryContractwith correct field values (not just “entry exists”). Added 5 per-builtin tests + found dispatch order bug inannotate_arg_ownership(2026-04-12):/// Verify seed_builtin_contracts produces correct MemoryContract /// fields for each protocol builtin — not just that an entry exists. /// Test naming: <subject>_<scenario>_<expected> per impl-hygiene.md. #[test] fn protocol_contract_index_has_two_borrowed_params() { let (interner, builtins) = setup(); let mut sigs = FxHashMap::default(); seed_builtin_contracts(&mut sigs, &builtins, &interner); let index_name = interner.intern("__index"); let contract = &sigs[&index_name]; assert_eq!(contract.params.len(), 2); assert_eq!(contract.params[0].access, AccessClass::Borrowed); assert_eq!(contract.params[0].consumption, Consumption::Dead); assert_eq!(contract.params[0].cardinality, Cardinality::Once); assert_eq!(contract.params[1].access, AccessClass::Borrowed); assert_eq!(contract.params[1].consumption, Consumption::Dead); assert_eq!(contract.params[1].cardinality, Cardinality::Once); } #[test] fn protocol_contract_iter_drop_has_owned_linear_param() { let (interner, builtins) = setup(); let mut sigs = FxHashMap::default(); seed_builtin_contracts(&mut sigs, &builtins, &interner); let name = interner.intern("ori_iter_drop"); let contract = &sigs[&name]; assert_eq!(contract.params.len(), 1); assert_eq!(contract.params[0].access, AccessClass::Owned); assert_eq!(contract.params[0].consumption, Consumption::Linear); assert_eq!(contract.params[0].cardinality, Cardinality::Once); } #[test] fn protocol_contract_iter_next_owned_then_borrowed() { let (interner, builtins) = setup(); let mut sigs = FxHashMap::default(); seed_builtin_contracts(&mut sigs, &builtins, &interner); let name = interner.intern("__iter_next"); let contract = &sigs[&name]; assert_eq!(contract.params.len(), 2); assert_eq!(contract.params[0].access, AccessClass::Owned); assert_eq!(contract.params[0].consumption, Consumption::Linear); assert_eq!(contract.params[0].cardinality, Cardinality::Once); assert_eq!(contract.params[1].access, AccessClass::Borrowed); assert_eq!(contract.params[1].consumption, Consumption::Dead); assert_eq!(contract.params[1].cardinality, Cardinality::Once); } #[test] fn protocol_contract_collect_set_owned_linear() { let (interner, builtins) = setup(); let mut sigs = FxHashMap::default(); seed_builtin_contracts(&mut sigs, &builtins, &interner); let name = interner.intern("__collect_set"); let contract = &sigs[&name]; assert_eq!(contract.params.len(), 1); assert_eq!(contract.params[0].access, AccessClass::Owned); assert_eq!(contract.params[0].consumption, Consumption::Linear); assert_eq!(contract.params[0].cardinality, Cardinality::Once); } #[test] fn protocol_contract_iter_borrowed_param() { let (interner, builtins) = setup(); let mut sigs = FxHashMap::default(); seed_builtin_contracts(&mut sigs, &builtins, &interner); let name = interner.intern("iter"); let contract = &sigs[&name]; assert_eq!(contract.params.len(), 1); assert_eq!(contract.params[0].access, AccessClass::Borrowed); assert_eq!(contract.params[0].consumption, Consumption::Dead); assert_eq!(contract.params[0].cardinality, Cardinality::Once); } -
Add
BuiltinOwnershipSetsintegration test tocompiler/ori_arc/src/borrow/builtins/tests.rs— verify thatBuiltinOwnershipSets::new()correctly populates theprotocolmap with the right ownership arrays (2026-04-12):/// Verify BuiltinOwnershipSets.protocol maps each protocol builtin /// name to its correct per-arg ownership array. This is the data /// that annotate_arg_ownership() consumes at call sites. #[test] fn ownership_sets_protocol_map_matches_all_builtins() { let interner = StringInterner::default(); let sets = BuiltinOwnershipSets::new(&interner); for &pb in ProtocolBuiltin::ALL { let name = interner.intern(pb.name()); let ownership = sets.protocol.get(&name) .unwrap_or_else(|| panic!("protocol {:?} missing from BuiltinOwnershipSets.protocol", pb)); assert_eq!(*ownership, pb.arg_ownership(), "BuiltinOwnershipSets.protocol[{:?}] doesn't match ProtocolBuiltin.arg_ownership()", pb); } assert_eq!(sets.protocol.len(), ProtocolBuiltin::ALL.len(), "BuiltinOwnershipSets.protocol has extra entries beyond ProtocolBuiltin::ALL"); } -
Add
annotate_arg_ownershipconsumer test tocompiler/ori_arc/src/rc_insert/tests.rs— this is the consumer directly responsible for the original__indexbug. Verify that whenannotate_arg_ownershipencounters a protocol builtin callee, it produces the correctArgOwnershipvector. Found and fixed dispatch order bug:ori_iter_dropwas incorrectly matched by theori_prefix check (external C runtime → all-Borrowed) before reaching the protocol builtin check. Fix: moved protocol check to first position in the cascade (2026-04-12):__indexcall →[Borrowed, Borrowed]✓__iter_nextcall →[Owned, Borrowed]✓ori_iter_dropcall →[Owned]✓ (FIXED: was[Borrowed]before dispatch reorder)__collect_setcall →[Owned]✓itercall →[Borrowed]✓
-
Add
promote_callee_argsconsumer test tocompiler/ori_arc/src/borrow/tests.rs— verify that borrow inference correctly promotes/borrows parameters at protocol builtin call sites (2026-04-12):- For
__index(both Borrowed): neither arg is promoted to Owned ✓ - For
ori_iter_drop(Owned): arg IS promoted ✓
- For
-
Add negative pin (forbid-old-behavior) — a negative pin must forbid the broken behavior that existed before the fix. For protocol builtins, the historic bug was
IterDrophavingBorrowedownership (causing double-free). The negative pin asserts the old behavior does NOT exist (2026-04-12):/// Negative pin: IterDrop must NOT have Borrowed access. /// Before the fix (TPR-07-008), IterDrop was Borrowed, causing /// a double-free on iterator cleanup. This test forbids the /// old behavior — if someone reverts the ownership change, /// this test fails immediately. #[test] fn protocol_contract_iter_drop_forbids_borrowed() { let (interner, builtins) = setup(); let mut sigs = FxHashMap::default(); seed_builtin_contracts(&mut sigs, &builtins, &interner); let name = interner.intern("ori_iter_drop"); let contract = &sigs[&name]; assert_ne!(contract.params[0].access, AccessClass::Borrowed, "IterDrop MUST NOT be Borrowed — Borrowed ownership causes \ a second scope-exit RcDec (double-free). See TPR-07-008."); } /// Negative pin: Index must NOT have Owned access on arg 0. /// The __index bug was caused by the "unknown callee -> all Owned" /// fallthrough. This forbids that regression. #[test] fn protocol_contract_index_forbids_owned_receiver() { let (interner, builtins) = setup(); let mut sigs = FxHashMap::default(); seed_builtin_contracts(&mut sigs, &builtins, &interner); let name = interner.intern("__index"); let contract = &sigs[&name]; assert_ne!(contract.params[0].access, AccessClass::Owned, "Index receiver MUST NOT be Owned — Owned receiver causes \ the collection to be consumed on index lookup. See __index RC leak."); } -
Add consistency pin (supplemental, not negative) — verify that for every protocol builtin, the
seed_builtin_contractsoutput matchesarg_ownership(). This is a positive regression guard, not a negative pin (2026-04-12):/// Consistency pin: contracts match arg_ownership() for all protocol builtins. #[test] fn protocol_contract_access_consistent_with_arg_ownership() { let (interner, builtins) = setup(); let mut sigs = FxHashMap::default(); seed_builtin_contracts(&mut sigs, &builtins, &interner); for &pb in ProtocolBuiltin::ALL { let name = interner.intern(pb.name()); let contract = &sigs[&name]; for (i, arg_own) in pb.arg_ownership().iter().enumerate() { let expected = match arg_own { ProtocolArgOwnership::Borrowed => AccessClass::Borrowed, ProtocolArgOwnership::Owned => AccessClass::Owned, }; assert_eq!(contract.params[i].access, expected, "{:?} arg {i}: contract {:?} != expected {:?}", pb, contract.params[i].access, expected); } } } -
TPR checkpoint —
/tpr-reviewcovering 06.1–06.2 implementation work (2026-04-12). Clean on iteration 2. Iteration 1: convergent GAP fixed (missing __iter_next mixed-ownership test). Iteration 2: codex clean (16 files, ran all tests), gemini naming finding rejected after verification (matches established crate convention). -
Subsection close-out (06.2) — MANDATORY before starting 06.3:
- All tasks above are
[x]and the subsection’s behavior is verified - Update this subsection’s
statusin section frontmatter tocomplete
- All tasks above are
06.3 AOT End-to-End Type x Pattern Matrix
File(s): Existing AOT test files (extend where gaps found), compiler/ori_llvm/tests/aot/util/aot.rs
Verify RC balance through the full LLVM codegen pipeline for programs exercising each protocol builtin. All existing AOT tests already enable ORI_CHECK_LEAKS=1 (wired in compile_and_run_capture). The work here is to identify gaps in the existing type x pattern matrix and fill them — NOT to create a new protocol_builtins.rs test file that duplicates existing coverage.
Existing coverage audit (DO FIRST — check these files for gaps):
iter_rc_matrix.rs(88 tests):str,[int],Option<str>, closure, struct, map x full/break/yield/two-call/nested/guard/unwind/continue — exercisesIter,IterNext,IterDropiterator_drop.rs: enum-tagged-ptr iterator, struct field, tuple element, bare unused iter — exercisesIterDropspecificallysets.rs: set length, contains, insert, remove, union, intersection, difference, for_each — exercisesCollectSetfat_ptr_iter/method_collect.rs:.iter().collect()for[str]andSet<str>— exercisesCollectSetcow_map_set.rs: map/set COW operationsfor_loops.rs: basic for-loop patterns- Other
fat_ptr_iter/submodules:control_flow.rs,map_set.rs,nested_list.rs, etc.
Known gaps to fill:
-
Map indexing RC balance gap-fill (2026-04-12) — added
test_coll_map_index_int_str({int: str} reversed types, exercises value-type RC) andtest_coll_map_index_in_loop(map indexing inside for-loop, exercises __index + Iter/IterNext interaction). Both pass with ORI_CHECK_LEAKS=1. -
Set iteration type coverage (2026-04-12) — Evaluated:
Set<int>iteration crashes in AOT (SIGSEGV, BUG-04-065).Set<str>iteration works (existing sets.rs tests pass). E7 fixtures kept as list-collect regression guards (without: Set<int>annotation). Matrix header updated to document the blocker. The original exclusion comment (“not yet implemented”) was inaccurate — it’s a codegen crash, not a missing implementation. -
CollectSetwith non-trivial element types (2026-04-12) — addedtest_iter_collect_nested_list([[int]] → collect exercises elem_inc_fn for [int]) andtest_iter_collect_map_elements([{str: int}] → collect exercises elem_inc_fn for {str: int}). Both pass. Note: nested_list test avoidsOption<[int]>.unwrap()due to BUG-04-061 (AOT monomorphization gap). -
AOT regression guard (2026-04-12) — all 2,161 AOT tests pass (0 failed, 22 ignored) with
ORI_CHECK_LEAKS=1. Positive regression guard confirmed. -
ORI_AUDIT_CODEGEN=1 in harness (2026-04-12) — evaluated: 38/2161 tests fail with
ORI_AUDIT_CODEGEN=1, all concentrated in unwind/panic/catch paths (cli::test_main_args_, error_handling::test_catch_, fat_ptr_iter::unwind::*). Decision: NOT adding globally — filed as BUG-04-062. Once unwind RC audit is fixed, harness can enable it. -
Debug AND release (2026-04-12) — both debug (
cargo test -p ori_llvm: 2161 pass/0 fail) and release (cargo test -p ori_llvm --release: 2161 pass/0 fail) builds pass. No FastISel divergence on protocol-exercising tests. -
Subsection close-out (06.3) — MANDATORY before starting 06.4:
- All tasks above are
[x]and the subsection’s behavior is verified - Update this subsection’s
statusin section frontmatter tocomplete - Run
/improve-toolingretrospectively on THIS subsection — Retrospective 06.3: TheORI_AUDIT_CODEGEN=1evaluation exposed 38 unwind-path RC failures (filed as BUG-04-062) — this surfaced a real issue class. Theunwrap()monomorphization gap was caught by a test exercising complex generic types (filed as BUG-04-061). No diagnostic scripts needed; targetedcargo testwith specific filters was sufficient. No tooling gaps — the AOT harness’sORI_CHECK_LEAKS=1integration provided immediate, actionable feedback (exit code 2 = leak). - Repo hygiene check — run
diagnostics/repo-hygiene.sh --checkand clean any detected temp files. Verified clean 2026-04-13.
- All tasks above are
06.4 Exhaustiveness Guard & Doc Fix
File(s): compiler/ori_ir/src/builtin_constants/protocol/tests.rs
The exhaustiveness guard already exists: all_variants_covered asserts ALL.len() == 5 and iterates all variants. This subsection verifies it is sufficient and adds defense-in-depth if needed.
-
Verify existing exhaustiveness guard (2026-04-12) —
all_variants_covered()inprotocol/tests.rsis sufficient: assertsALL.len() == 5, iterates all variants checkingname()non-empty +from_nameround-trip +arg_ownership().len() == arg_count().is_intercepted_exhaustive()separately confirms all variants have defined interception status.pin_arg_counts()pins exact arg counts per variant. No new code needed. -
Compile-time exhaustiveness note (2026-04-12) — added doc comment on
all_variants_covered()explaining that all four methods use exhaustive match (no_catch-all), so Rust enforces coverage at compile time. Test-time guard is defense-in-depth for theALLconstant and test assertions. -
Subsection close-out (06.4) — MANDATORY before starting 06.R:
- All tasks above are
[x]and the subsection’s behavior is verified - Update this subsection’s
statusin section frontmatter tocomplete
- All tasks above are
06.R Third Party Review Findings
-
[TPR-06-001-codex][medium]compiler/ori_arc/src/borrow/tests.rs:1435— Add mixed-ownership protocol promotion coverage for __iter_next. Evidence: GAP — promote_callee_args coverage only exercises all-borrowed (Index) and single-arg owned (IterDrop). The mixed [Owned, Borrowed] vector for __iter_next is untested. Impact: Partial-promotion path unverified; regression could reintroduce ownership DRIFT at iterator-advance call sites. Basis: direct_file_inspection. Confidence: high. Resolved: Fixed on 2026-04-12. Addedpromote_protocol_iter_next_promotes_first_arg_onlytest. -
[TPR-06-001-gemini][medium]compiler/ori_arc/src/borrow/tests.rs:1434— Add missing promote_callee_args test for __iter_next. Evidence: Plan section 06.2 requested consumer test for __iter_next (Owned, Borrowed). Test was omitted. Impact: Mixed-ownership iteration logic in promote_callee_args unverified. Basis: direct_file_inspection. Confidence: high. Resolved: Fixed on 2026-04-12. Same fix as [TPR-06-001-codex] (convergent finding). -
[TPR-06-002-gemini][low]compiler/ori_arc/src/aims/builtins/tests.rs:180— Test functions lack mandatory shape and prefix. Evidence: Claims test functions omittest_prefix and lack<scenario>component per impl-hygiene.md §Test Function Naming. Impact: Low (naming convention concern). Basis: direct_file_inspection. Confidence: high. Resolved: Rejected after verification on 2026-04-12. The existing 30+ tests in borrow/tests.rs (pre-dating this work) all omit thetest_prefix — this IS the established crate convention. The impl-hygiene.md shape definition is<subject>_<scenario>_<expected>(notest_in the shape). Adding the prefix would introduce inconsistency with the existing file. Names are descriptive and self-explanatory. Codex (HIGH trust, 16 files read, ran all tests) found zero naming issues. -
[TPR-06-003-codex][medium]compiler/ori_llvm/tests/aot/fixtures/iter_rc_matrix/iter_rc_for_do_set_int_full.ori:2— Setmatrix fixtures lacked explicit type annotation, actually created lists not sets. Evidence: GAP — fresh ARC dump verification showed Invoke @collect(...)instead ofApply @__collect_set(...). All 4 E7 fixtures used[10, 20, 30].iter().collect()withoutSet<int>annotation. Impact: Section 06.3 claimed Setcoverage but tests exercised list iteration. Basis: fresh_verification. Confidence: high. Resolved: Fixed on 2026-04-12. Set<int>iteration crashes in AOT (BUG-04-065). Reverted: Set<int>annotations; E7 fixtures kept as list-collect regression guards. Plan updated to document the blocker. Codex finding correctly identified the gap. -
[TPR-06-004-codex][medium]compiler/ori_llvm/tests/aot/fixtures/fat_ptr_iter/method_collect/iter_collect_nested_list.ori:3— Complex-element collect fixtures exercise list collect, not __collect_set. Evidence: GAP — fixtures annotated as[[int]]and[{str: int}](list targets), not Set targets. ARC dumps confirmedInvoke @collect(...)notApply @__collect_set(...). Impact: CollectSet verification for non-trivial elements is limited to existing Setcoverage. Basis: fresh_verification. Confidence: high. Resolved: Fixed on 2026-04-12. Set<[int]> and Set<{str: int}> crash with SIGSEGV (filed BUG-04-065). Fixtures kept as list-collect tests (exercise elem_inc_fn for complex types). CollectSet with complex elements is blocked by BUG-04-065. Notes added to test comments. -
[TPR-06-005-codex][medium]plans/llvm-verification-tooling/section-06-protocol-builtins.md:416— Plan/implementation drift: checklist/overview claims Setcoverage while implementation documents it blocked. Evidence: Checklist claims “Set iteration works in AOT, added Set to iter_rc_matrix” and “CollectSet with complex element types tested” while fixtures and matrix header document BUG-04-065 blocker. Impact: Section presented as complete on criteria not actually verified. Basis: direct_file_inspection. Confidence: high. Resolved: Fixed on 2026-04-12. Updated checklist items, success criteria, and overview to accurately state Set blocked by BUG-04-065. All claims now match implementation reality. -
[TPR-06-006-codex][high]compiler/ori_arc/src/borrow/builtins/mod.rs:49— Protocol Iter pinned as Borrowed but collection override produces Owned; consumer test gap. Evidence: LEAK claim —ProtocolBuiltin::Iter.arg_ownership()returns[Borrowed]butapply_consuming_overrides()overrides toOwnedfor List/Map/Set receivers. The existingannotate_protocol_iter_produces_borrowedtest usesIdx::INT(non-collection), so the override path was never exercised at the consumer level. Impact: Test gap — the protocol-vs-override layered architecture IS intentional (protocol defines base, override adds collection exception), but no unit test verified the full flow with a collection receiver. Basis: fresh_verification. Confidence: high. Resolved: Fixed on 2026-04-12. Addedannotate_iter_on_collection_overrides_to_ownedtest inrc_insert/tests.rsthat constructs aList<int>receiver and verifiesannotate_arg_ownershipproduces[Owned]. Updated existing test doc comment to explain the layered architecture. Architecture is sound (not a true LEAK) — the two layers compose correctly; the gap was test coverage only. -
[TPR-06-003-gemini][medium]compiler/ori_llvm/tests/aot/iter_rc_matrix.rs:374— Setmatrix only has P1-P2 (full/break); P3-P8 variants missing. Evidence: iter_rc_matrix.rsadds E7 (Set) but only fullandbreaktest variants. Missing:nested,two_call,guard,unwind,continue,yield_transform. Impact: Gaps in matrix coverage for Setiteration patterns. Basis: direct_file_inspection. Confidence: high. Resolved: Accepted on 2026-04-12. P3-P8 variants blocked by BUG-04-065 (Set iteration crashes with SIGSEGV). BUG-04-065 already notes “Blocks Set iteration matrix (iter_rc_matrix E7)”. When BUG-04-065 is fixed, the fixer should expand E7 to the full P1-P8 matrix. -
[TPR-06-007-codex][medium]plans/llvm-verification-tooling/section-06-protocol-builtins.md:4— DRIFT: Section 06 status inconsistent across plan surfaces. Evidence: Section file hasstatus: in-progressand body says “Not Started”, but overview/index marked “Complete”. Close-out items (TPR, hygiene, tooling) still unchecked. Impact: Plan tooling and reviewers get contradictory signals about section status. Basis: direct_file_inspection. Confidence: high. Resolved: Fixed on 2026-04-12. Updated overview (effort table + quick ref) and index to “In Progress”. Updated body status to “In Progress (close-out pending)”. Status will be set to Complete only after all 06.N close-out items pass. -
[TPR-06-008-codex][low]compiler/ori_arc/src/rc_insert/tests.rs:1230— DRIFT: Test comment references TPR-06-005-codex but correct ID is TPR-06-006-codex. Evidence: Stale ID — TPR-06-005-codex is the plan-drift finding; TPR-06-006-codex is the collection-receiver test gap. Impact: Incorrect plan annotation provenance. Basis: direct_file_inspection. Confidence: high. Resolved: Fixed on 2026-04-12. Updated comment to reference TPR-06-006-codex. -
[TPR-06-009-codex][medium]plans/llvm-verification-tooling/section-06-protocol-builtins.md:58— DRIFT: Plan references stale BUG-04-063 (now ArgEscaping) instead of BUG-04-065 (Set iteration SIGSEGV). Evidence: Bug tracker renumbered Set iteration crash from BUG-04-063 to BUG-04-065; plan still used BUG-04-063. Basis: direct_file_inspection. Confidence: high. Resolved: Fixed on 2026-04-12. Replaced all BUG-04-063 → BUG-04-065 in section-06 and overview. -
[TPR-06-010-codex][low]plans/llvm-verification-tooling/section-06-protocol-builtins.md:449— Plan-sync item checked but section still in-progress. Evidence: Checklist marks “frontmatter status -> complete” as done while section is in-progress. Basis: direct_file_inspection. Confidence: high. Resolved: Fixed on 2026-04-12. Unchecked plan-sync item; will be re-checked after close-out gates pass.
06.N Completion Checklist
- Existing
protocol/tests.rsaudited — all 10 tests confirmed covering IR-level ownership pins -
IterDropdoc comment fixed: “borrowed” -> “owned (consumed by cleanup)” -
seed_builtin_contractsconsumer tests verifyMemoryContractfield values (access, consumption, cardinality) for all 5 protocol builtins -
annotate_arg_ownershipconsumer test verifies correctArgOwnershipvectors for protocol builtin callees -
promote_callee_argsconsumer test verifies correct promotion/borrowing at protocol call sites -
BuiltinOwnershipSets.protocolintegration test verifies name-to-ownership mapping for all builtins - Negative pin (forbid-old-behavior):
assert_nepins that IterDrop is NOT Borrowed and Index receiver is NOT Owned — forbids the historic regression states - Consistency pin (supplemental): contracts read from
arg_ownership()— drift between constant and contract is caught - AOT gap-fill: map indexing gap-fill (existing
{str:int}covered; add{int:str}and looped indexing) - AOT gap-fill:
CollectSetwith complex element types evaluated — Set<[int]>/Set<{str:int}> crash (BUG-04-065); list-collect equivalents added as regression guards; existing Setcoverage via iter_collect_set_str.oriexercises__collect_set - Set iteration status evaluated — Set
iteration crashes in AOT (BUG-04-065); E7 fixtures exercise list-collect as regression guards; Set iteration works (existing tests pass) -
ORI_AUDIT_CODEGEN=1harness integration evaluated — 38 unwind-path failures, NOT adding globally; filed BUG-04-062 - Debug AND release builds pass for all protocol-exercising AOT tests
- No regressions:
timeout 150 ./test-all.shgreen (17,167 tests pass) -
timeout 150 ./clippy-all.shgreen - Plan annotation cleanup:
bash .claude/skills/impl-hygiene-review/plan-annotations.sh --plan llvm-verification-toolingreturns 0 annotations - All intermediate TPR checkpoint findings resolved (TPR-06-001 convergent finding fixed, TPR-06-002 rejected)
- Plan sync — update plan metadata:
- This section’s frontmatter
status->complete, subsection statuses updated -
00-overview.mdQuick Reference updated (effort table + section reference + success criterion) -
index.mdsection status updated
- This section’s frontmatter
-
/tpr-reviewpassed (final, full-section) — clean on iteration 4 (2026-04-12). Iterations 1-3 found and fixed: missing __iter_next borrow test, Setfixture → crash discovery (BUG-04-065), plan text drift, duplicate BUG ID, stale annotation. Iteration 4 clean (codex findings were stale-worktree artifacts from parallel session). -
/impl-hygiene-reviewpassed (2026-04-12) — Auto Mode, scoped to 8992b03c^..HEAD. Zero LEAK/SSOT/DRY/DRIFT/GAP findings in Section 06 changes. Automated lint: 15 findings all pre-existing (3 test-weak in collections_ext.rs, 12 #[ignore] in iter_rc_matrix.rs). Manual review: annotate.rs dispatch cascade clean, well-documented ordering invariant. -
/improve-toolingsection-close sweep (2026-04-12) — Per-subsection retrospectives: 06.2 no gaps, 06.3 ORI_AUDIT_CODEGEN evaluation surfaced BUG-04-062 (38 unwind-path failures), 06.4 no gaps. Cross-subsection pattern: no repeated command sequences, no integration test message issues, no cross-referencing friction. Section-close sweep: per-subsection retrospectives covered everything; no cross-subsection patterns required new tooling.
Exit Criteria: Protocol builtin ownership is verified at all three layers: IR definition (existing tests audited), ori_arc consumers (new MemoryContract field-level tests + negative pins), and LLVM codegen (AOT type x pattern matrix with ORI_CHECK_LEAKS=1). An exhaustiveness guard ensures new variants cannot be added without test coverage. timeout 150 ./test-all.sh passes with all new tests included.