§01 — AIMS FFI Contract Extension
Context
Approved proposal §1 (docs/ori_lang/proposals/approved/ffi-boundary-safety-proposal.md) states that AIMS today treats extern calls as opaque — assume-the-worst conservative — because extern declarations do not produce MemoryContract fragments. This section makes extern declarations first-class contract providers, so the existing interprocedural SCC fixpoint (IC-1 / IC-2 / IC-3 / IC-4 / IC-5) consumes them alongside native Ori callees.
Invariant #5 is load-bearing here. Any implementation approach that introduces a parallel structure (shadow contract table, separate FFI lattice, independent RC annotation pass) is out of scope AND will be rejected at /tpr-review. The extension MUST be additive on MemoryContract / ParamContract / ReturnContract / EffectSummary.
§01.1 — Design Log FIRST (gate — do not implement before this)
Before any Rust changes land, write plans/ffi-boundary-safety/section-01-design-log.md answering:
- Which
ParamContractfield(s) carry the FFI-declared ownership (ownedvsborrowed)? — default: reuseParamContract.access(Owned/Borrowed) since that is the existing SSOT peraims-rules.md §1.1. - Which
ParamContractfield carriesmay_sharefor FFI parameters? — default: reuse the existingmay_sharefield onParamContractperaims-rules.md §5 IC-3. - Which
ReturnContractfield carries the FFI-declared return ownership +preserves_freshness? — default: reuseReturnContract.uniqueness(Uniqueforownedreturns from fresh C allocations) andReturnContract.preserves_freshness(trueforowned+ known-fresh allocator;falseforborrowedreturns which copy immediately per approved Deep FFI). - Which
EffectSummaryfields cover#error(errno)/#error(nonzero)/ etc.? — default:may_throw = truewhen#error(...) != none(error paths produceResult::Err, which the caller’s control-flow graph must account for);may_allocate = truewhen the callee is known to allocate (e.g.,sqlite3_opencreates a handle);may_deallocate = truefor#free(...)functions. - What new field (if ANY) is needed? — if none, note that explicitly. If one is needed, justify why it cannot be expressed on existing fields and verify the addition does not violate L-5 (finite height) or L-10 (monotone join).
- Cite each field mapping against
aims-rules.mdrule anchor (IC-2, IC-3, IC-4, IC-5) — reviewers will check these verbatim.
Acceptance. The design log is complete when it exhaustively lists every FFI-declarable annotation (owned, borrowed, owned CPtr return, borrowed str return, borrowed [byte] return, #error(errno), #error(nonzero), #error(null), #error(negative), #error(success: N), #error(none), #free(fn), out param, #borrow_from(p) — the last deferred to §04 but the schema must accommodate it) and maps each to a concrete MemoryContract field.
Failure mode. If the design log cannot express an annotation using existing contract fields, STOP. Do not add a sibling structure. Either (a) propose a specific field addition with justification, or (b) file a bug per CLAUDE.md §Bug Handling — ZERO DEFERRAL and escalate via AskUserQuestion.
§01.2 — ExternDecl → MemoryContract fragment emitter
Once §01.1 is signed off:
- Add
fn extract_extern_contract(decl: &ExternDecl) -> MemoryContractincompiler/ori_arc/src/aims/interprocedural/extract.rs(NEW function; do NOT modify the existingextract_function_contractcore logic — share helpers only). - Wire into the SCC fixpoint: extern decls appear as nodes in the call graph at IC-1 with their contract pre-populated (no fixpoint iteration needed — externs have no bodies to analyze). Update
compute_aims_contracts()entry point perarc.md §Entry Points. - Each extern function’s contract is produced ONCE at crate-type-check time and cached in the Salsa query layer (per
compiler.md §Salsapurity requirements). - Update
ori_arc/src/aims/contract/mod.rsdocumentation comments to note FFI-origin contracts (reading-only — do not change field definitions unless §01.1 justified a new field).
§01.3 — Call-site refinement (TF-6 interop)
- In the intraprocedural analysis (
compiler/ori_arc/src/aims/intraprocedural/mod.rs), the existing TF-6 (aims-rules.md §3)refine(CONSERVATIVE, callee.return_contract)already handles any callee with a contract, regardless of origin. Verify with a targeted unit test that an extern callee’s contract narrows the call-siteAimsStatecorrectly. - Verify TF-11 argument demand refinement (
aims-rules.md §3 TF-11 Applyrow) fires correctly for FFI arguments: BorrowedAbsent→ zero demand; OwnedAbsent→(arg, Once, Linear)for RL-5 dec; locality/uniqueness/may_share propagation applies identically to FFI calls. - NO new code path needed here — this subsection validates the existing refinement mechanics work for FFI contracts. If they don’t, that’s a bug in TF-6/TF-11, not a new “FFI refinement” code path.
§01.4 — Realization phase validation
- Verify
realize_rc_reuse(Step 5) andrealize_annotations(Step 10) emit correct RC operations for FFI-touching functions. The realization doesn’t branch on FFI-origin — it reads the lattice state, which §01.2 has populated via §01.3’s refinement. - Verify
verify_fip_contract(Step 5a,aims-rules.md §5 IC-6) correctly certifies FFI-only functions: a function whose body islet x = RSA_new(); sign(x, ...); RSA_free(x)with allowned/borrowedcontracts provided should reachFipContract::Certified(zero unmatched alloc/dealloc in realized IR). - NO realization-level code changes expected. If changes ARE needed, flag as a design-log deviation and STOP for review.
§01.5 — Matrix test coverage (MANDATORY)
Per CLAUDE.md §Fix Completeness and tests.md §Matrix Testing Rule:
- Failing tests FIRST (TDD order):
- AOT FileCheck test in
compiler/ori_llvm/tests/aot/ffi_contract.rsthat asserts ZERORcInc/RcDecin emitted LLVM IR for the canonical FFI owned-chain program. - AIMS snapshot test in
compiler/oric/tests/aims-snapshots/ffi_contract/showing the contract fragment for an annotated extern decl.
- AOT FileCheck test in
- Matrix dimensions (must test ALL cells):
- Ownership × Error protocol:
owned/borrowed×#error(errno)/#error(nonzero)/#error(null)/#error(negative)/#error(none)= 10 cells. - Return types:
c_int,owned CPtr,borrowed CPtr,borrowed str,borrowed [byte],Result<..., FfiError>(auto-wrapped by#error(...)!=none) = 6 cells. - Argument patterns:
owned CPtrarg + dead elsewhere;borrowed CPtrarg + used after call;owned CPtrchained into another FFI call (ownership transfer);borrowed str+ interior mutation attempt (should stay COW-safe).
- Ownership × Error protocol:
- Semantic pins:
- One Ori program
tests/spec/ffi/aims_zero_rc.orithat ONLY compiles to zero-RC IR with §01 implementation; a FileCheck assertion (CHECK-NOT: call void @ori_rc_inc/CHECK-NOT: call void @ori_rc_dec) that fails if §01 is reverted. - One negative pin: a program that DOES require an RC op (e.g., an
owned CPtrreturned and assigned to a variable used twice) that MUST emit exactly one RcInc — fails if AIMS over-eliminates.
- One Ori program
- Verification layer matrix:
- VF-1 structural check clean on FFI-touching functions (
cargo test -p ori_arc -- verify::check_function). - VF-2
AbsentParamHasUsesdoes not false-positive on FFI absent params. - VF-3 oracle cross-check re-derives the FFI contract from realized IR and matches the declared contract (
cargo test -p ori_arc -- oracle). - VF-4 FIP certification matrix:
FipContract::Certified,FipContract::Bounded(N),FipContract::Conditional,FipContract::Nevereach reachable via a test program with appropriate FFI call mix.
- VF-1 structural check clean on FFI-touching functions (
- Dual-execution parity: Interpreter and LLVM produce identical observable behavior for all FFI test programs (
ORI_CHECK_LEAKS=1reports zero leaks). - Debug + release: both build modes pass all tests.
§01.6 — AIMS rule additions (documentation)
- Update
.claude/rules/aims-rules.md §5to note thatParamContract/ReturnContract/EffectSummaryaccept FFI-origin contracts identically to native contracts — add a one-paragraph note near IC-2/IC-3 citing this section. Co-commit with §01.2. - Update
.claude/rules/arc.md §"What AIMS does TODAY"bullet list to mention FFI contract participation once §01 ships. Co-commit with §01.2. - NO changes to the formal rules themselves — they already admit FFI contracts; this is a documentation sync.
Completion Checklist
- §01.1 design log exists, cites aims-rules.md anchors, passes independent reading.
- §01.2 extract_extern_contract lands; Salsa-cached; unit-tested.
- §01.3 call-site refinement validated via unit tests.
- §01.4 realization validated; FipContract::Certified reachable for pure-FFI bodies.
- §01.5 matrix tests green (all cells), semantic pins green, negative pin green, both debug + release.
- §01.6 aims-rules.md + arc.md documentation sync committed.
-
./test-all.shgreen (full suite). -
./clippy-all.shgreen (zero warnings introduced). -
ORI_CHECK_LEAKS=1 ./binaryreports zero leaks on the FFI test programs. -
/tpr-reviewrun to consensus (clean). -
/impl-hygiene-reviewrun to consensus (clean). -
/improve-toolingsection-close sweep run. -
/sync-claudesection-close doc sync run. - Plan status flipped:
sections[id=01].status: complete;reviewed: true; overview Quick Reference updated.
§01.R — Third Party Review Findings
- None.