§05 — Callback Capability Propagation
Context
Per approved proposal §5. BLOCKED: cannot begin implementation until capability-propagation-completion-proposal.md ships. That draft documents three infrastructure gaps (LLVM/AOT capability support stubbed, stateful handlers partial, marker capability enforcement partial) — any one of them would make §05’s compile-time verification unsound.
When the blocker clears, the following subsections execute.
§05.1 — Unblock verification
- Verify
capability-propagation-completionhas landed:- LLVM/AOT capability lowering is shipped (check
compiler/ori_llvm/foruseshandling). - Stateful
handler(state: S) { ... }fully implemented in eval + LLVM. - Marker capability E1250 propagation enforced at the type-check layer.
- LLVM/AOT capability lowering is shipped (check
- If any gap remains, STOP; file a bug per
CLAUDE.md §Bug Handling — ZERO DEFERRALand escalate viaAskUserQuestion.
§05.2 — Grammar + parser
- Grammar production (ships with §08):
callback_type = "(" param_list ")" "->" type [ "uses" cap_list ] . - Parser accepts
useson callback parameter function types (currently parsed but not propagated). - AST: callback parameter types carry an optional
cap_listfield.
§05.3 — Subset verification at registration
- In
ori_types/src/check/capabilities/(new file or extension to existing module), addfn check_callback_subset(registered_fn: &FunctionSig, callback_param: &CallbackType) -> Result<(), Diagnostic>. - Rule:
registered_fn.uses⊆callback_param.uses. Set difference → E4019 listing the missing capabilities on the callback parameter. - Applies to every call site that passes an Ori function to a callback parameter. Detected via call-argument type-checking.
§05.4 — Handler-based capability provision at registration
- When the C library provides capabilities via a callback argument (e.g.,
uv_timer_startpasses a handle that exposesClock), the user can write:with Clock = uv_handle_clock(handle) in { uv_timer_start(handle: handle, cb: on_tick, ...) } - The existing
with Cap = handler inmechanism handles this — §05 does not add new machinery, only validates the subset check against the with-in-provided scope.
§05.5 — Matrix tests
- Failing tests FIRST: a program registering a callback that uses
Printwhen the callback parameter type declares onlyuses Clock→ MUST emit E4019. - Matrix:
- Subset position:
uses {} ⊆ uses {Clock}(OK) /uses {Clock} ⊆ uses {Clock}(OK) /uses {Clock, Logger} ⊆ uses {Clock}(E4019 — Logger missing) /uses {Clock} ⊆ uses {}(E4019 — all missing) = 4 cells. - Callback parameter forms: explicit callback type with
uses/ callback type withoutuses(strictest default) / extern function returning a callback type (propagation) = 3 cells. - with…in provision: capability provided via with-in AT the call site → subset check passes; capability NOT provided → E4019 = 2 cells.
- Subset position:
- Semantic pin: a compilable
uv_timer_startexample withon_tick uses Clockand a matching callback parameter compiles clean AND emits the callback registration through the capability-aware lowering (FileCheck for the correct LLVM IR shape once capability-propagation-completion ships). - Negative pin: any cell where the subset fails MUST emit E4019 at compile time.
§05.6 — Documentation
- Update spec §26-ffi.md with §05 surface (co-commit with §08).
- Update
.claude/rules/ori-syntax.mdDeep FFI section with callbackusespropagation.
Completion Checklist
- §05.1 capability-propagation-completion blocker verified cleared.
- §05.2 grammar + parser lands.
- §05.3 subset verification lands with E4019 emission.
- §05.4 with…in integration verified.
- §05.5 matrix tests green; semantic pin green; negative pin green.
- §05.6 spec +
ori-syntax.mdcommitted. -
./test-all.sh,./clippy-all.sh,./llvm-test.shgreen. -
/tpr-reviewclean;/impl-hygiene-reviewclean. -
/improve-tooling+/sync-claudesweeps. -
sections[id=05].status: complete,reviewed: true.
§05.R — Third Party Review Findings
- None.