Section 16: Async Support
Goal: Suspend-based concurrency via capabilities (verified 2026-03-29)
SPEC:
spec/20-capabilities.md § Suspend CapabilityDESIGN:archived-design/10-async/index.md(archived — runtime architecture TBD)
Dependencies: Section 6 (Capabilities — uses Suspend capability declarations and propagation)
PREREQUISITE FOR: Section 17 (Concurrency Extended) — select, cancellation, enhanced channels.
NOTE: This section is thin for an entire concurrency support system. Before implementation, expand with: async runtime architecture (stackless coroutines vs green threads vs OS threads), task scheduling model (work-stealing, cooperative, event-loop), ARC interaction with task boundaries, Suspend context propagation in typeck, channel buffer semantics (bounded/unbounded, backpressure, close propagation), memory ownership transfer on channel send.
Future Enhancements: Approved proposal
parallel-execution-guarantees-proposal.mdadds:
Sendabletrait for safe cross-task transfer- Role-based channels (
Producer<T>,Consumer<T>)- Ownership transfer semantics for channel send
- Process isolation primitives See Section 17 for implementation details.
16.1 Suspend Capability
Naming: The approved
rename-async-to-suspend-proposal.mdrenamedAsynctoSuspend. The spec, lexer (TokenKind::Suspend), and syntax reference all useSuspend. (verified 2026-03-29)Existing scaffolding:
usesclause parsing works forSuspendvia the general capabilities infrastructure (Section 6). The lexer reservessuspendas a keyword. No async-specific semantic enforcement exists. DRIFT:library/std/prelude.oristill declarespub trait Async {}— must be renamed toSuspendbefore this section begins.
-
Implement:
uses Suspenddeclaration — spec/20-capabilities.md § Suspend Capability- Rust Tests:
ori_types/src/check/capabilities.rs— suspend capability enforcement - Ori Tests:
tests/spec/async/declaration.ori - LLVM Support: LLVM codegen for suspend capability declaration
- LLVM Rust Tests:
ori_llvm/tests/async_tests.rs— suspend capability declaration codegen - AOT Tests: No AOT coverage yet
- Rust Tests:
-
Implement: Sync vs suspend distinction — spec/20-capabilities.md § Suspend Capability
- Type checker must enforce that non-Suspend functions cannot call Suspend functions without propagating the capability (E1200)
- Rust Tests:
ori_types/src/check/capabilities.rs— sync/suspend distinction - Ori Tests:
tests/spec/async/sync_suspend.ori - LLVM Support: LLVM codegen for sync/suspend distinction
- LLVM Rust Tests:
ori_llvm/tests/async_tests.rs— sync/suspend distinction codegen - AOT Tests: No AOT coverage yet
-
Fix: Rename
pub trait Async {}topub trait Suspend {}inlibrary/std/prelude.oriper approved rename-async-to-suspend proposal (DRIFT found 2026-03-29) -
/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 (16.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-16.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 16.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.
16.2 Structured Concurrency
Existing scaffolding:
FunctionExpKind::NurseryIR variant exists. Parser handlesnursery(body:, on_error:, timeout:). Evaluator has stub (unimplemented). (verified 2026-03-29)
-
Implement: Structured concurrency — archived-design/10-async/index.md § Structured Concurrency
- Rust Tests:
ori_eval/src/interpreter/async.rs— structured concurrency - Ori Tests:
tests/spec/async/structured.ori - LLVM Support: LLVM codegen for structured concurrency
- LLVM Rust Tests:
ori_llvm/tests/async_tests.rs— structured concurrency codegen - AOT Tests: No AOT coverage yet
- Rust Tests:
-
Implement:
nurserypattern — spec/15-patterns.md § nursery (verified 2026-03-29 — missing from original plan)- Nursery runtime: task spawning, scoped lifetime, error collection
-
NurseryErrorMode(CancelRemaining | CollectAll | FailFast) per spec -
on_error:callback support -
timeout:enforcement within nursery scope - Rust Tests:
ori_eval/src/interpreter/nursery.rs— nursery pattern - Ori Tests:
tests/spec/async/nursery.ori - LLVM Support: LLVM codegen for nursery pattern
- AOT Tests: No AOT coverage yet
-
Implement: No shared mutable state — archived-design/10-async/index.md § No Shared Mutable State
- Ori’s value semantics (capture by value, no shared mutable refs) provide the foundation, but explicit compiler enforcement is needed for async-specific guarantees
- Rust Tests:
ori_types/src/check/mutability.rs— shared state detection - Ori Tests:
tests/spec/async/no_shared_state.ori - LLVM Support: LLVM codegen for no shared mutable state enforcement
- LLVM Rust Tests:
ori_llvm/tests/async_tests.rs— no shared mutable state codegen - AOT Tests: No AOT coverage yet
-
Implement:
Sendabletrait enforcement — spec/08-types.md § Channel Types (verified 2026-03-29 — missing from original plan)- Auto-derived marker trait: all fields must be
Sendable, no interior mutability, no non-Sendable captures - Required for channel types
T: Sendable - Cannot be implemented manually
- Rust Tests:
ori_types/src/check/sendable.rs— sendable enforcement - Ori Tests:
tests/spec/async/sendable.ori - AOT Tests: No AOT coverage yet
- Auto-derived marker trait: all fields must be
-
Implement:
CancellationError/CancellationReasontypes — prelude types (verified 2026-03-29 — missing from original plan)- Required by parallel/nursery cancellation semantics
-
CancellationReasonenum for nurseryon_error:callback - Ori Tests:
tests/spec/async/cancellation_types.ori
-
Implement:
is_cancelled()builtin — spec prelude (verified 2026-03-29 — missing from original plan)- Returns
boolindicating whether the current task has been cancelled - Ori Tests:
tests/spec/async/is_cancelled.ori
- Returns
-
/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 (16.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-16.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 16.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.
16.3 Concurrency Patterns
Existing scaffolding: All four patterns (
parallel,spawn,timeout,channel) have IR variants, parser support, and evaluator stubs that execute sequentially / return void.tests/spec/patterns/parallel.oriandtests/spec/patterns/channels.oriexist but only test synchronous fallback; all async-specific tests are commented out. (verified 2026-03-29)
-
Implement:
parallelpattern — spec/15-patterns.md § parallel- [partial] IR (
FunctionExpKind::Parallel), parser, typeck partial, evaluator stub (sequential) exist (verified 2026-03-29) - Actual concurrent execution (currently runs tasks sequentially)
-
max_concurrent:enforcement -
timeout:enforcement - Rust Tests:
ori_eval/src/interpreter/parallel.rs— parallel pattern async - Ori Tests:
tests/spec/async/parallel.ori - LLVM Support: LLVM codegen for parallel pattern
- LLVM Rust Tests:
ori_llvm/tests/async_tests.rs— parallel pattern codegen - AOT Tests: No AOT coverage yet
- [partial] IR (
-
Implement:
spawnpattern — spec/15-patterns.md § spawn (verified 2026-03-29 — missing from original plan)- [partial] IR (
FunctionExpKind::Spawn), parser, evaluator stub exist (verified 2026-03-29) - Fire-and-forget task spawning with
max_concurrent:enforcement - Rust Tests:
ori_eval/src/interpreter/spawn.rs— spawn pattern - Ori Tests:
tests/spec/async/spawn.ori - LLVM Support: LLVM codegen for spawn pattern
- AOT Tests: No AOT coverage yet
- [partial] IR (
-
Implement:
timeoutpattern — spec/15-patterns.md § timeout- [partial] IR (
FunctionExpKind::Timeout), parser, evaluator stub exist (verified 2026-03-29) - Actual timeout enforcement with timer/cancellation infrastructure
- Rust Tests:
ori_eval/src/interpreter/timeout.rs— timeout pattern async - Ori Tests:
tests/spec/async/timeout.ori - LLVM Support: LLVM codegen for timeout pattern
- LLVM Rust Tests:
ori_llvm/tests/async_tests.rs— timeout pattern codegen - AOT Tests: No AOT coverage yet
- [partial] IR (
-
Implement: Channels — spec/08-types.md § Channel Types (section 8.5)
- [partial] IR (
FunctionExpKind::Channel/ChannelIn/ChannelOut/ChannelAll), parser, evaluator stub exist (verified 2026-03-29) -
Producer<T>,Consumer<T>,CloneableProducer<T>,CloneableConsumer<T>types in typeck - Channel runtime: buffer, send/receive, close semantics
-
Sendableconstraint enforcement onT - Ownership transfer on send (value consumed)
- Rust Tests:
ori_eval/src/interpreter/channel.rs— channel implementation - Ori Tests:
tests/spec/async/channels.ori - LLVM Support: LLVM codegen for channels
- LLVM Rust Tests:
ori_llvm/tests/concurrency_tests.rs— channels codegen - AOT Tests: No AOT coverage yet
- [partial] IR (
-
/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 (16.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-16.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 16.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.
16.4 Async Error Traces
Proposal: proposals/approved/error-trace-async-semantics-proposal.md (verified exists 2026-03-29)
Implements error trace preservation across task boundaries in async code. Spec coverage in spec/17-errors-and-panics.md section 17.8. (verified 2026-03-29)
-
Implement: Task boundary marker in traces — spec/17-errors-and-panics.md § 17.8.1 Task Boundary Marker
-
TraceEntry { function: "<task boundary>", file: "", line: 0, column: 0 }per spec - Rust Tests:
ori_eval/src/interpreter/async.rs— task boundary marker tests - Ori Tests:
tests/spec/async/trace_boundary.ori - LLVM Support: LLVM codegen for task boundary marker
- LLVM Rust Tests:
ori_llvm/tests/async_tests.rs— task boundary marker codegen - AOT Tests: No AOT coverage yet
-
-
Implement: Trace preservation across parallel tasks — spec/17-errors-and-panics.md § Trace from Parallel Tasks
- Rust Tests:
ori_eval/src/interpreter/async.rs— parallel trace tests - Ori Tests:
tests/spec/async/parallel_traces.ori - LLVM Support: LLVM codegen for parallel trace preservation
- LLVM Rust Tests:
ori_llvm/tests/async_tests.rs— parallel trace codegen - AOT Tests: No AOT coverage yet
- Rust Tests:
-
Implement: Trace preservation across nursery tasks — spec/17-errors-and-panics.md § 17.8 Async Error Traces
- Rust Tests:
ori_eval/src/interpreter/nursery.rs— nursery trace tests - Ori Tests:
tests/spec/async/nursery_traces.ori - LLVM Support: LLVM codegen for nursery trace preservation
- LLVM Rust Tests:
ori_llvm/tests/async_tests.rs— nursery trace codegen - AOT Tests: No AOT coverage yet
- Rust Tests:
-
Implement: Catch and panic trace interaction — spec/17-errors-and-panics.md § 17.8.3 Catch and Panic Traces
- Note: synchronous
catchpattern (FunctionExpKind::Catch) works; async-specific trace interaction is not implemented (verified 2026-03-29) - Rust Tests:
ori_eval/src/interpreter/catch.rs— catch trace tests - Ori Tests:
tests/spec/errors/catch_traces.ori - LLVM Support: LLVM codegen for catch trace interaction
- LLVM Rust Tests:
ori_llvm/tests/error_tests.rs— catch trace codegen - AOT Tests: No AOT coverage yet
- Note: synchronous
-
/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 (16.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-16.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 16.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.
16.5 Section Completion Checklist
- All items above have all checkboxes marked
[x] - DRIFT resolved:
pub trait Async {}renamed topub trait Suspend {}in prelude - Async runtime architecture decision documented (stackless coroutines vs green threads vs OS threads)
- Spec updated:
spec/20-capabilities.mdsuspend section,spec/15-patterns.mdconcurrency patterns - CLAUDE.md updated with async/concurrency syntax
- Re-evaluate against docs/compiler-design/v2/02-design-principles.md
- 80+% test coverage, tests against spec/design
- Run full test suite:
./test-all.sh -
/tpr-reviewpassed — independent Codex review found no critical or major issues (or all findings triaged) -
/impl-hygiene-reviewpassed — implementation hygiene review clean (phase boundaries, SSOT, algorithmic DRY, naming). MUST run AFTER/tpr-reviewis clean. -
/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.
Exit Criteria: Suspend-based concurrent code compiles and runs; parallel/spawn/nursery/timeout/channels all functional with actual concurrency (not sequential stubs)
- Subsection close-out (16.5) — 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-16.5 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 16.5: 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.