Section 01: IndexSet Trait + updated Method + ARC COW
Goal
- See frontmatter. Proposal Phase 1.
- The
updatedmethod is the desugar target for index assignment (list[i] = x → list = list.updated(key: i, value: x)); it ships before the section-03 desugar consumes it.
Implementation Sketch
IndexSet<Key, Value>is a prelude trait (companion to read-onlyIndex).- The
updatedmethod is publicly callable (functional style:list.updated(key: 0, value: x)) independent of the assignment sugar. - The contract is value-semantic:
updatedreturns a NEW collection, observably distinct from the receiver. - Built-in impls are compiler-provided intrinsics; for all three types (
[T]/[T, max N]/{K:V}) the existing ARC copy-on-write mutates the backing buffer in place at refcount==1 (provable uniqueness) and allocates-then-rebinds otherwise — observably identical to the always-copy path (Swift Array/Dictionary COW under ARC). - Map in-place COW is live in the runtime:
ori_rt/src/map/cow.rscow_insert_existing/cow_insert_newcarry a unique-fast-path (ori_rc_is_unique) that overwrites in place at refcount==1 — maps are NOT always-allocate. strdeliberately omitsIndexSet(codepoint replacement may change byte length).
01.1 IndexSet Trait + updated Method + ARC COW Implementation
- TDD-first: failing test matrix BEFORE implementation —
updatedon[int]/[str]/{str:int}/[int, max N]× {in-bounds, out-of-bounds, refcount==1 in-place, refcount>1 copy} × {interpreter, LLVM}. OOB semantics per type:[T].updatedpanics,[T, max N].updatedpanics (key>= length),{K:V}.updatedinserts. Negative pin:str.updateddirect-resolution failure (str implementsIndex, notIndexSet).[T, max N].updatedOOB cell (parallels[T]): positive pin — a[int, max 3]-annotated literal.updated(key: 1, value: 9)yields[1, 9, 3]in both backends; negative pin —assert_panics(() -> fixed.updated(key: 5, value: 0))forkey >= length(in-bounds-of-capacity but out-of-bounds-of-length still panics, matching[T]index semantics, NOT the fixed-listtry_pushoverflow path). Construction uses the[int, max 3]annotation form:.to_fixed<$N>()is unimplemented (BUG-02-043).- Ori Tests:
tests/spec/traits/index_set/fixed_oob.ori
- Ori Tests:
- Define
IndexSet<Key, Value>trait incompiler_repo/library/std/prelude.oriwith@updated (self, key: Key, value: Value) -> Self.- Ori Tests:
tests/spec/traits/index_set/basic.ori
- Ori Tests:
- Register
IndexSettrait definition + built-in derived/impl signatures inori_types/src/check/registration/(mirror howIndexis registered). Mirrored outcome:Indexcarries NOcheck/registration/entry — both traits register via prelude parse + registry-driven resolution (registry_bridge), so the registration surface is theori_registryMethodDef (Some("IndexSet")) consumed byresolve_builtin_method; no parallelcheck/registration/table exists to extend.- Rust Tests:
ori_types/src/infer/expr/methods/tests.rs(resolution-path pins;check/registration/tests.rshas no Index-trait analog to mirror)
- Rust Tests:
- Register
updatedas a built-in method on[T]+{K: V}inori_evalmethod dispatch +ori_registry(per.claude/rules/registry.md— methods on builtin types live in the registry). Map registration carries theK: Eq + Hashablebound (mirrorsIndex/ map-key constraints).[T, max N]is NOT a separate registration surface: it erases toTypeTag::Listat registration/resolution, so the[T](List-tag) registration inori_registry/src/defs/list/mod.rs(registered undertag: TypeTag::List) covers fixed-lists — registeringupdatedon[T, max N]separately would be redundant.- Rust Tests:
ori_types/src/infer/expr/methods/tests.rs(companion toresolve_builtin_methodatori_types/src/infer/expr/methods/mod.rs; the resolver lives inori_types, NOTori_eval/src/method_dispatch/) — registry resolution ofupdatedsucceeds for each type:[int].updated→IndexSet<int, int>,{str: int}.updated→IndexSet<str, int>,[int, max 4].updated→IndexSet<int, int>resolves via the List tag (assertresolve_builtin_methodreturns the registered impl + correct key/value types per type). - Rust Tests: non-hashable map-key negative pin lands as the spec compile-fail
tests/spec/traits/index_set/non_hashable_key.ori(E2031 at map-type formation viacheck_map_key_hashable, which is private toinfer/expr/type_resolution.rs— no Rust-level E2031 pin surface exists; the bound is enforced before method resolution is reached); positive pin: hashableKresolves perupdated_method.ori+infer/expr/methods/tests.rs. - Ori Tests:
tests/spec/traits/index_set/updated_method.ori
- Rust Tests:
- Implement
updatedARC copy-on-write inori_patterns/ori_evalvalue model: for[T]/[T, max N]AND{K:V}refcount==1 → mutate backing buffer in place (list:ori_rt/src/list/cow.rs; map:ori_rt/src/map/cow.rsunique-fast-path), refcount>1 → clone-then-mutate + rebind. List/fixed-list out-of-bounds panics; map inserts-or-replaces.- Rust Tests:
ori_patterns/src/value/tests.rs— COW behavior matrix (positive: in-place fires at rc==1 for list/fixed-list AND map; negative: aliased list/map forces copy, alias unchanged) - Ori Tests:
tests/spec/traits/index_set/cow_behavior.ori
- Rust Tests:
- Register
updatedAIMS builtin ownership contract inori_arcso AIMS can prove the value-flow rather than emit RC ops on the inserted value. Addupdated’s param/return ownership + borrow contract toBuiltinOwnershipSets/seed_builtin_contracts(ori_arc/src/aims/builtins/mod.rs) and the borrow-builtin surface:selfis consumed-and-returned (the return aliases or replaces the receiver’s storage),valueis moved into the collection (ownership transferred — its RC must NOT be dropped after insert). Without the interprocedural contract AIMS may emit an erroneous RC dec on the inserted value (leak at rc==1 in-place; double-free at rc>1 copy).- 3-param contract constructor required:
updatedis 3-param (self, key, value); the existingcow_receiver_only_contract(ori_arc/src/aims/builtins/mod.rs) marks ONLY the receiver and cannot express thevalue-param ownership-transfer —seed_builtin_contractsMUST NOT defaultupdatedinto it (param-length mismatch). Add a new 3-param parameterized contract constructor (or specialized memory contract) that modelsselfconsumed-returned +valuemoved-in +keyborrowed. - Uniform COW contract across all three types:
[T]/[T, max N]AND{K:V}share one value-flow shape — in-place-at-rc==1 / clone-at-rc>1, the return aliases-or-replaces receiver storage (no list-vs-map asymmetry; the runtime map unique-fast-path atori_rt/src/map/cow.rs:106is the in-place path). The seeded contract models the single COW value-flow (selfconsumed-returned,valuemoved-in) so AIMS proves all three without parallel emission paths. - Rust Tests:
ori_arc/src/aims/builtins/tests.rs— contract seeded forupdatedon[T]/[T, max N]/{K:V}; value-param ownership-transfer asserted (no RC dec on the movedvalue). - Ori Tests:
tests/spec/traits/index_set/arc_insert.ori— insert an ARC-managed element ([str]/{str: [int]}) underupdated;ORI_CHECK_LEAKS=1reports zero leaks debug + release, interpreter == AOT.
- 3-param contract constructor required:
- LLVM
updatedcodegen for the three built-in types; verify interpreter == AOT (dual-execution parity);ORI_CHECK_LEAKS=1zero leaks debug + release. The codegen + AIMS contract + runtime are CORRECT. BUG-04-142 (parallel session’s59f645300burden-only-default RC regression:__indexdouble-inc str-element leak + premature receiver dec / alias corruption) resolved 2026-06-10; AOT parity restored.- Re:
index_set_updatedAOT 13/13 debug + 13/13 release (incl.test_updated_list_str_elements_no_leak,test_updated_list_str_shared_copy_no_double_free,test_updated_list_shared_preserves_alias,test_updated_map_arc_value_moved_no_leak— the exact cases BUG-04-142 had broken).
- Re:
- Verify: matrix green debug + release, both backends. Interpreter index_set spec corpus green (0 failures in
tests/spec/traits/index_set/); LLVM AOT 13/13 debug + 13/13 release. BUG-04-142 resolved — AOT parity restored, section unblocked.
Intelligence Reconnaissance
2026-06-01 — feature-mode scaffold; approved proposal index-assignment-proposal.md is the research artifact.
scripts/intel-query.sh symbols "Index" --repo ori --kind trait— mirror the read-side trait registration[ori:ori_types/src/check/registration/]forIndexSet.scripts/intel-query.sh file-symbols "ori_eval/src/method_dispatch" --repo ori— built-in method routing surface[ori:ori_eval/src/method_dispatch/].scripts/intel-query.sh similar "updated" --repo swift,rust --limit 5— Array/Dictionary copy-on-write prior art.
Spec References
compiler_repo/docs/ori_lang/v2026/spec/13-variables.md§13.6.2 (index assignment) — the AUTHORITATIVE SSOT definingx = x.updated(key: i, value: v)as the index-assignment desugar contract; spec is SSOT over the proposal. The §13.6 NOTE establishes that in-place mutation under refcount==1 is an optimization observably identical to the always-copy value-semantic path.- Proposal
index-assignment-proposal.md§The IndexSet Trait, §Standard Implementations (research artifact; subordinate to the spec). index-trait-proposal.md(the read-sideIndexpair).- Semantic contract:
t.updated(key:k, value:v).index(key:k) == v(not compiler-enforced).
Tests
tests/spec/traits/index_set/{basic,updated_method,cow_behavior,fixed_oob,arc_insert,non_hashable_key}.ori + Rust unit tests in ori_types / ori_registry / ori_patterns / ori_arc + AOT integration compiler/ori_llvm/tests/aot/index_set_updated.rs per items above.
01.R — Third Party Review Findings
Section-close /tpr-review (codex + agy + opencode + fork-context Opus adjudicator), 2 rounds, exit cap_reached_with_substantive (wall-clock cap).
[TPR-01-001-codex][Major](CURED) Decorative Unicode box-drawing banner comments incompiler/ori_llvm/tests/aot/index_set_updated.rs(6 occurrences,COMMENT_HYGIENE_DRIFT:decorative-banner). Replaced with plain ASCII section comments (working tree; commit deferred behind BUG-04-142 cross-scope gate).[TPR-01-002-codex][Critical](RESOLVED)INVERTED-TDD:commit-with-red-tests— section claimed complete + 13/13 AOT while 5/13index_set_updatedAOT tests fail. Adjudicated: theupdated()feature is correct (interpreter 33/33; AOT was 13/13 atd2237c1df); the regression is the parallel session’s59f645300burden-only-default flip (two general ori_arc burden-path RC bugs). Dispositioned: filed BUG-04-142, reverted premature completion, declaredblocked_by: [BUG-04-142]. BUG-04-142 resolved 2026-06-10; re — AOT 13/13 debug + release, interpreter index_set green.blocked_bycleared.
HISTORY
- 2026-06-12 — BUG-04-142 cleared; §01 re-verified + unblocked: BUG-04-142 (parallel-session burden-only-default RC regression) resolved 2026-06-10. Re-verified
index_set_updatedAOT 13/13 debug + 13/13 release (the str-leak / double-free / alias cases the regression had broken now pass) and the interpreter index_set spec corpus green. Flipped §01.1’s two remaining verification items, clearedblocked_by: [BUG-04-142]. No code changed this session — verify-first re-close after the cross-scope blocker cleared.
Adjudicator-refuted (not actionable, recorded for trail): agy INVERTED-TDD claims on fixed_oob.ori turbofish removal (false positive — .to_fixed<$N>() unimplemented per BUG-02-043, construction rerouted to [int, max 3] annotation with documented rationale); opencode VERIFIED:no-drift positive verification record.
- 2026-06-11 — Stale
review_pipeline:marker cleared by /continue-roadmap orchestrator: marker carriedstage: ?,next_step: ?,updated: ?. Per /review-plan SKILL.md §Step 1a stale-marker rule (reviewed: false+ marker present → STALE by definition), marker invalid; prior diagnosis preserved here for traceability. Cure rooted inscripts/plan_orchestrator/markers.py:clear_stale_marker_if_unreviewed.