Core-1 previewnormative preview; stable Core-1 inactive

Domain identity, portable declarations, and lifecycle ordering.

Core-1 Domains, Portability, and Lifecycle

Status: normative preview

C1-DOM-001 — Closed domains. The only runtime domains, in canonical order, are algorithm, compute, state, flow, and optimize. Their v2 wire tags are respectively 0, 1, 2, 3, and 4. flow is the sole spelling. workflow receives ZL-DOMAIN-0002 and is never an alias.

C1-DOM-002 — Callable fact. Every callable has exactly one domain. Domain participates in typed-message identity, semantic and package identity, dispatch, overrides, requirements, generated interfaces, reflection, checked artifacts, and runtime admission. A phase that discards or infers an explicit domain is nonconforming.

C1-DOM-003 — Direct calls. An ordinary direct call is valid only when caller and callee have the same domain. Cross-domain work uses one of the typed boundaries in C1-BOUND-001. Merely returning the same scalar ABI or IR shape cannot erase this rule.

C1-PORT-001 — Portable templates. A declaration of the form portable { ... } message is a compile-time template and is not callable. Its set is nonempty, contains no duplicate, and canonicalizes in C1-DOM-001 order. Every selected-domain instantiation is independently type-, ownership-, effect-, contract-, and capability-checked and receives a distinct identity.

C1-PORT-002 — Sealing. The initial portable profile is sealed. A portable declaration cannot be open, abstract, or override, and cannot satisfy an override using one shared identity.

C1-LIFE-001 — Ordered lifecycle. Initialization follows base-to-derived order and destruction follows the exact reverse order on success, error, control transfer, and cancellation cleanup. Domain scheduling cannot reorder or omit required cleanup.

C1-LIFE-002 — Shared owned values. Domains share ordinary owned values, borrows, views, errors, contracts, and Result. Crossing a typed boundary requires the boundary’s ownership rule; address-dependent or live borrowed state cannot be silently promoted to owned durable state.

C1-LIFE-003 — Packed aggregate execution tranche. The shared preview’s first multi-field execution tranche admits one sealed nongeneric value with one or more public immutable exact scalar fields whose total width is at most 32 bits. Self { ... } supplies every field once in declaration order. The value remains one nominal, move-only owner; packing is an unobservable materializer choice, and each projection retains its declared scalar type and signedness. The interpreter, C materializer, LLVM JIT, and LLVM AOT must agree on construction, projection, transfer through Result, and cleanup. Core-0’s schema-1.8 single-field boundary is unchanged.

C1-LIFE-004 — Synchronous shared-view tranche. The shared preview admits Ref<T> parameters for sealed owned values and the compiler-known Ref::<T>.borrow(place) expression. In this first executable tranche the borrow expression may flow only into a synchronous Ref<T> message argument; place is a live named owner of exact type T, and the callee may copy scalar fields or synchronously forward the same shared authority. The loan begins at the borrow operation, remains active through the complete child call, and ends before the caller resumes. It never consumes or snapshots ownership: caller cleanup still destroys the owner exactly once after its final use.

Ref locals, results, stored fields, variants, Result payloads, captures, and cross-domain or durable carriers remain rejected with ZL-OWN-0003. Borrowed parameters are nonowning and receive no cleanup edge. The checked semantic graph retains an explicit borrow node, and the interpreter, C materializer, LLVM JIT, and LLVM AOT must agree on field observation, call extent, artifact admission, and cleanup.

C1-LIFE-005 — Bounded lexical shared-loan tranche. The shared preview also admits an immutable local let view: Ref<T> = Ref::<T>.borrow(place) in a straight-line message body. The local must be initialized directly by that exact borrow. Each use flows directly into a synchronous call accepting the exact Ref<T> type; copying into another local, assignment, field projection through the local, return, storage, and crossing a control-flow edge remain rejected in this tranche with ZL-OWN-0003.

The compiler derives the loan interval from the borrow operation through the complete final child call. Moving, replacing, or dropping the origin during that interval rejects. Once the final call completes, the loan ends and the origin may be moved or destroyed normally. The local is nonowning, receives no owned path or cleanup edge, and all four algorithm executors must agree on its behavior.

C1-LIFE-006 — Lexical shared-view projection tranche. A bounded lexical Ref<T> local may additionally copy an immutable scalar field declared by T. Each projection is a loan use, so the loan remains live through the final projection or synchronous child call, whichever occurs later. Projection does not snapshot or consume the owner, and the same move, replacement, drop, straight-line, nonescaping, and cleanup rules from C1-LIFE-005 continue to apply. Projection from borrowed parameters retains its C1-LIFE-004 meaning.

C1-LIFE-007 — Forward-control shared-loan tranche. A bounded lexical shared view may cross acyclic forward control flow when its direct borrow initializer precedes the first branch. Its conservative loan interval extends in instruction order through the latest reachable direct-call or projection use. A move, replacement, or drop of the origin anywhere in that interval rejects, including on a branch that does not itself observe the view.

Every control edge in a message containing such a local must target a later instruction. Loop backedges remain rejected with ZL-OWN-0003; general path-sensitive loan joins are not implied. Normal and error exits retain the existing owner cleanup law, while the shared local remains nonowning and adds no cleanup operation.

Projected fromspec/editions/core-1/domains-portability-and-lifecycle.md