Section 01: Runtime COW Protocol Centralization
Status: Not Started Goal: Reduce 17+ inline copies of the COW uniqueness formula, 3 copies of propagate_elem_header, 3 copies of write_collection_struct, and 4 copies of the iterator consumer loop harness into single canonical functions. Zero behavioral change.
Context: The COW uniqueness check !is_slice_cap(cap) && (cow_mode == 1 || (cow_mode != 2 && ori_rc_is_unique(data))) is inlined at 17 call sites across 7 files. The cow_mode semantics (0=dynamic, 1=static unique, 2=static shared) have no canonical home. propagate_elem_header exists as two identical functions with different names (propagate_elem_header in cow.rs, propagate_header in cow_sort/mod.rs) plus a third inline copy in cow_structural.rs. write_list_output, write_map_struct, write_set_struct are identical 3-line functions.
01.1 Centralize COW Uniqueness Check
File(s): compiler/ori_rt/src/cow_helpers.rs (new), all COW files
Create a single canonical function:
/// Determine whether a COW mutation can proceed in-place.
///
/// cow_mode semantics:
/// - 0: dynamic — check runtime uniqueness via ori_rc_is_unique
/// - 1: static unique — always mutate in-place (compiler proved uniqueness)
/// - 2: static shared — always copy (compiler proved sharing)
///
/// Slices are never mutated in-place (they are views into another allocation).
#[inline(always)]
pub(crate) fn cow_can_mutate_in_place(data: *const u8, cap: i64, cow_mode: i32) -> bool {
!is_slice_cap(cap) && (cow_mode == 1 || (cow_mode != 2 && ori_rc_is_unique(data)))
}
-
Create
compiler/ori_rt/src/cow_helpers.rswithcow_can_mutate_in_place() -
Add
mod cow_helpers;tocompiler/ori_rt/src/lib.rs(note: lib.rs is already 512 lines — tracked in Section 08.4 for splitting; adding onemodline is fine here) -
Replace all 17 inline copies across these files:
list/cow.rs—ori_list_push_cow,ori_list_pop_cow,ori_list_set_cowlist/cow_structural.rs—ori_list_insert_cow,ori_list_remove_cowlist/cow_sort/mod.rs—ori_list_concat_cow,ori_list_reverse_cowlist/cow_sort/sort.rs—ori_list_sort_cowmap/cow.rs—ori_map_insert_cow,ori_map_remove_cowset/cow/basic.rs—ori_set_insert_cow,ori_set_remove_cowset/cow/algebra.rs—ori_set_union_cow,ori_set_intersection_cow,ori_set_difference_cow
-
Verify:
grep -rn "cow_mode == 1\|cow_mode != 2" compiler/ori_rt/src/ | grep -v cow_helpers | grep -v testreturns 0 matches -
timeout 150 cargo test -p ori_rtpasses after this sub-section -
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (01.1) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, 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-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-01.1 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 01.1: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-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 --checkand clean any detected temp files.
01.2 Unify propagate_elem_header / propagate_header
File(s): compiler/ori_rt/src/cow_helpers.rs, compiler/ori_rt/src/list/cow.rs, compiler/ori_rt/src/list/cow_sort/mod.rs, compiler/ori_rt/src/list/cow_structural.rs
-
Move
propagate_elem_headerfromlist/cow.rs(line 21) intocow_helpers.rsas the single canonical copy -
Delete
propagate_headerfromlist/cow_sort/mod.rs(line 23, identical body) -
Replace the inline copy in
cow_structural.rswith calls tocow_helpers::propagate_elem_header— check bothori_list_insert_cowandori_list_remove_cowfor inline header propagation -
Update all import paths
-
Verify:
grep -rn "fn propagate_header\|fn propagate_elem_header" compiler/ori_rt/src/shows exactly 1 definition incow_helpers.rs -
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (01.2) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, 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-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-01.2 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 01.2: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-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 --checkand clean any detected temp files.
01.3 Unify write_collection_struct
File(s): compiler/ori_rt/src/cow_helpers.rs, compiler/ori_rt/src/list/mod.rs, compiler/ori_rt/src/map/mod.rs, compiler/ori_rt/src/set/mod.rs
write_list_output, write_map_struct, write_set_struct are identical:
pub(crate) unsafe fn write_collection_struct(out: *mut u8, len: i64, cap: i64, data: *mut u8) {
out.cast::<i64>().write(len);
out.cast::<i64>().add(1).write(cap);
out.add(16).cast::<*mut u8>().write(data);
}
-
Add
write_collection_structtocow_helpers.rs -
Replace
write_list_outputinlist/mod.rswith a re-export or inline call -
Replace
write_map_structinmap/mod.rs -
Replace
write_set_structinset/mod.rs -
Replace inline writes in
list/cow.rsori_list_push_cow(which doesn’t usewrite_list_output) -
Verify: all collection sret writes go through
write_collection_struct -
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (01.3) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, 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-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-01.3 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 01.3: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-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 --checkand clean any detected temp files.
01.4 Extract Iterator Consumer Loop Harness
File(s): compiler/ori_rt/src/iterator/consumers.rs
ori_iter_any, ori_iter_all, ori_iter_find, ori_iter_for_each share identical loop harness: null check, cast to IterState, loop calling state.next(), test element, cleanup via Box::from_raw.
- Extract
consume_iter()higher-order function:unsafe fn consume_iter<F, R>( iter: *mut u8, elem_size: i64, init: R, f: F, ) -> R where F: FnMut(R, &[u8]) -> ControlFlow<R, R>, - Rewrite
ori_iter_any,ori_iter_all,ori_iter_find,ori_iter_for_eachusingconsume_iter - Extract
collect_to_reverse_vec()for shared collection phase inori_iter_rfoldandori_iter_rfind - Verify:
timeout 150 cargo test -p ori_rtpasses
Cleanup (fix while touching these files)
-
[WASTE]
compiler/ori_rt/src/iterator/consumers.rs:232— Remove decorative unicode dash banner// ── Backward consumers ...──────────, replace with plain// Backward consumers (require double-ended iterators) -
[WASTE]
compiler/ori_rt/src/list/cow.rs—write_list_outputis still defined here even afterwrite_collection_structextraction; ensure it’s fully removed, not left as dead code -
/tpr-reviewpassed — independent review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — hygiene review clean. MUST run AFTER/tpr-reviewis clean. -
Subsection close-out (01.4) — MANDATORY before starting the next subsection. Run
/improve-toolingretrospectively on THIS subsection’s debugging journey (per.claude/skills/improve-tooling/SKILL.md“Per-Subsection Workflow”): whichdiagnostics/scripts you ran, where you addeddbg!/tracingcalls, 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-pushusing a valid conventional-commit type (build(diagnostics): ... — surfaced by section-01.4 retrospective—build/test/chore/ci/docsare valid;tools(...)is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 01.4: no tooling gaps”. Update this subsection’sstatusin section frontmatter tocomplete. -
/sync-claudesection-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 --checkand clean any detected temp files.
01.R Third Party Review Findings
- None.
01.T Test Strategy
This section is pure structural refactoring with zero behavioral change. The test strategy focuses on:
- Existing test suite as regression gate:
./test-all.shmust pass identically before and after each sub-section. - Unit tests for new canonical functions: Each extracted function gets direct unit tests verifying it matches the old inline behavior.
- Structural invariant tests: Grep-based tests that verify no inline copies remain.
- Add unit tests for
cow_can_mutate_in_place()incompiler/ori_rt/src/cow_helpers/tests.rs:cow_mode=1(static unique) returnstrueregardless of RCcow_mode=2(static shared) returnsfalseregardless of RCcow_mode=0(dynamic) returnstruewhenori_rc_is_uniquereturns truecow_mode=0(dynamic) returnsfalsewhen refcount > 1- Slice cap always returns
falseregardless of cow_mode
- Add unit tests for
write_collection_struct(): verify struct layout matches the (len, cap, data) triple at correct offsets (0, 8, 16) - Add unit tests for
consume_iter(): verify ControlFlow::Break stops iteration, ControlFlow::Continue processes all elements - Verify
timeout 150 cargo test -p ori_rtpasses after each sub-section (01.1, 01.2, 01.3, 01.4) - Verify
timeout 150 ./test-all.shpasses after all sub-sections complete - Verify
ORI_CHECK_LEAKS=1reports zero leaks on COW-heavy test programs (e.g.,tests/spec/collections/cow/)
01.N Completion Checklist
- All 17 inline COW uniqueness checks replaced with
cow_can_mutate_in_place() - Single
propagate_elem_headerfunction incow_helpers.rs - Single
write_collection_structfunction incow_helpers.rs - Iterator consumer loop harness extracted
- Unit tests for all new canonical functions pass
-
timeout 150 cargo test -p ori_rtpasses -
timeout 150 ./test-all.shpasses (zero behavioral changes) -
./clippy-all.shclean -
/tpr-reviewcovering Section 01 -
/impl-hygiene-review -
/improve-toolingretrospective completed — MANDATORY at section close, after both reviews are clean. Reflect on the section’s debugging journey (whichdiagnostics/scripts you ran, which command sequences you repeated, where you added ad-hocdbg!/tracingcalls, 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.