Contents

Interlace Transition Tables

These tables make the 050/060 ownership model executable. A connected carrier owns prefacing or one logical session; a direct pair owns two endpoints. Its runtime transport may own one duplex IO value or split reader and writer values without changing carrier state. Host cancellation retires that complete connected transport. Listener acceptance, process supervision, admission, and task and service ownership remain outside these tables. The numbered specifications remain authoritative for validation and wire encoding.

A phase deadline is one absolute deadline created when a stable prefacing, establishment, or endpoint phase token changes. Partial IO, event reads, replacement staging, and progress by the other endpoint do not reset it. If the machine enters fixed point while the batch accepted at that transition, the settled round’s final request item, remains buffered, the driver retains that batch’s Requesting token and deadline until it is fully written and flushed to the adopted IO; it does not publish FixedPoint first.

Connected carrier owner

CarrierState =
  Prefacing {
    cause: Initial | Reset,
    local_operand: optional (operand, optional expected peer By),
    local_preface: Pending(nonce) | Accepted(nonce),
    peer_nonce: optional nonce,
  }
  | Running {
    session: SessionMachine,
    staged_replacement: optional InterlaceModule,
  }
  | Failed(SessionError)
  | Closed(CloseReason)

CarrierRole::Listener derives protocol side0 and CarrierRole::Connector derives protocol side1. The role is fixed before decoding and is not inferred or negotiated. Carrier role, proof assurance and binding, operand source, By-secret value, configured stream encodings and port, limits, nonce seed, and next nonce sequence survive logical-session replacement. The operand source is Fixed(expected peer By), whose operand replacement changes, or Selected, which asks the host for each session’s operand and expected peer By. The carrier also retains the port of the latest peer preface as a diagnostic. Construction constraints are defined by Lace-050. Endpoint configuration and diagnostics are not policy facts, plan or proof inputs, or carrier authority. The carrier, ConnectedConfig, and Rust runtime connected inputs retain the nonce seed in the core zeroizing NonceSeed owner; each config clone owns an independently erased seed, and unclaimed participants and failed setup erase theirs on drop. These owners, BySecret, and schnorr-blake3’s seed-derived SigningKey use maintained zeroize for owned secret storage. The guarantee covers current owned storage, not caller copies, prior moves, compiler temporaries, registers, opaque hash state or C-library scratch. See schnorr-blake3 for the cryptographic boundary.

The running machine owns the current local operand: establishment owns it until compilation, then its immutable plan owns it. The carrier keeps no duplicate. A selecting carrier owns no operand in prefacing until the host answers.

Owning state/input Transition
new carrier enter Prefacing(Initial) with the fixed operand and its expected peer By, or no operand when selecting, and derived local nonce; expose local preface, with the configured port, immediately
local replacement on a selecting carrier Policy call error; no transition
local replacement in Prefacing replace the fixed local_operand; do not emit another preface
local replacement in Running replace staged_replacement; do not poll, retire, emit, execute IO, or deliver observations
next poll with staged replacement consume session, drop unaccepted machine output and unsettled machine observations, discard old operand, enter Prefacing(Reset) with staged operand, the fixed expected peer By, and fresh nonce; clear the peer’s proved By
peer preface in Running consume session, extract a fixed carrier’s local operand or discard a selected one, drop unaccepted output, enter Prefacing(Reset) with fresh local nonce and received peer nonce; retain the peer port and clear the peer’s proved By
first peer preface in Prefacing retain nonce and peer port; complete pair when local preface is accepted and the operand is owned
selecting, peer preface owned, no operand after local-preface output, poll exposes SelectOperand(peer port) and reads no peer input
host selects an operand validate its expected peer By against assurance (Integration) and its Blob size (LimitExceeded), failing the carrier on error; otherwise own it
host refuses the port Failed(PeerProtocol("port refused"))
second peer preface before construction Failed(PeerProtocol)
both prefaces and the operand owned the codec selects each direction’s 065 encoding from the two offers and installs fresh primed state; move operand, its expected peer By, and nonce texts into one fresh SessionMachine; enter Running.Side0Proof
peer proof validated under confidential or channel-bound assurance retain its By as the peer’s proved By, the session’s PeerConfidential key

The decoder stops at a preface before parsing any bounded suffix. During initial prefacing, ordinary input is premature. During locally initiated reset prefacing, complete old peer items are decoded under the old encoding and discarded until the peer’s end mark, if any, and preface. Malformed or oversized input fails normally. One absolute prefacing deadline covers accepted old-writer drain, local-preface acceptance, discard, peer-preface receipt, and operand selection.

SelectOperand is a poll result, not a host callback: the sans-IO carrier stays synchronous and owns no selector, and each runtime driver answers it with select_operand from its own selector before polling again. Rust drivers call their selector inline, Python on the driving thread, and JavaScript awaits a returned promise. Until the answer, the carrier has no session, effect, or legal peer input.

A connected writer owns at most one accepted batch, ending with the direction’s flush. The codec validates the batch on acceptance, then renders and encodes it into one bounded chunk at a time as the writer takes bytes; an identity direction writes a record larger than the free chunk room from the record’s own bytes. An accepted old batch drains, then the old encoding’s end mark when it has one, before the fresh raw preface; unaccepted old output is dropped. The fresh preface is the next accepted output, and proof or operand bytes cannot overtake it.

Logical session owner and establishment

SessionState =
  Establishing(EstablishmentState)
  | Round(RoundState)
  | FixedPoint(FixedPointState)
  | Failed(SessionError)
  | Closed(CloseReason)
Owning state Owning role action Other role input Result
Side0Proof side0 emits ::as with the exact v3 proof Seal, or the permitted unbound ::as unknown side1 validates shape, nonces, and local binding context, then expected peer By on success retain optional peer By value; enter Side1Proof
Side1Proof side1 emits ::as with the exact v3 proof Seal, or the permitted unbound ::as unknown side0 validates shape, nonces, and local binding context, then expected peer By on success retain optional peer By value; enter Side0Operand
Side0Operand side0 emits ::policy h0 side1 holds h0 as its own operand or a cache entry within max_operand_bytes, or marks it missing enter Side1Operand
Side1Operand side1 emits ::policy h1, then ::policy-known if it holds h0, otherwise ::policy-missing side0 holds or marks h1 missing on the first item and notes whether to deliver h0 on the second enter Side0Delivery
Side0Delivery side0 emits h0’s Blob in ::policy-body if side1 sent ::policy-missing, then ::policy-known if it holds h1, otherwise ::policy-missing side1 validates a requested Blob against h0, caches it, then reads the answer if h1 is needed enter Side1Delivery; otherwise both freeze fresh authority, derive the immutable plan and executable, and enter Round.Advertising
Side1Delivery side1 emits h1’s Blob in ::policy-body side0 validates it against h1 and caches it freeze fresh authority; derive immutable plan and executable; enter Round.Advertising
any establishment state fresh peer preface carrier consumes session and enters reset prefacing
any establishment state malformed/wrong-family input, limit, premature EOF, cancellation, or deadline enter one typed terminal state; close carrier

Rust establishment applies Lace-050’s proof validation before advancing the proof transitions above. Lace-060 defines the proof grammar.

Complete proof, policy announcement, policy answer, and policy-body items, including their labels, count toward logical-session establishment control. Proof and operands are control material, not store admission. A direct pair bypasses establishment, derives its plan from prepared modules and explicit authorities, and starts both endpoints in Round.Advertising.

Round state shape

RoundPhase = Advertising | Requesting | Answering | Fencing
Phase State-local ownership
Advertising local evaluation/output; frozen advertisement and commitments; optional peer advertisement; on a connected carrier, the session adapter’s reconciliation or delta state and one peer item slot
Requesting both advertisements; local evaluation/output; frozen request set; optional peer request set
Answering both request sets; incoming/outgoing obligations; bounded current response ingress; optional early peer fence
Fencing local fence output; optional peer fence; both request sets

A listing slot stores one complete listing and its change since the previous listing. The endpoint owns the session’s local listing, frozen as the previous local listing until the next round changes it; on a connected carrier the session adapter owns the previous peer listing, the entries each side requested in the previous round, the first-round reconciliation state, and the 060 delta and 061 reconciliation encodings, while the endpoint sees only complete listings with their changes. Starting a round drops all other round-local state. The two endpoints may occupy different phases.

Advertising

Local/peer progress Result
phase entry start one coherent local advertisement evaluation and establish the round’s local record-fact boundary
evaluation creates StoreCall retain the endpoint-exclusive effect; accept no peer input until submission
evaluation completes change the local listing by the held MaySend change, loading projections only for added records, and freeze it as the round’s commitments; expose one peer-output effect
direct route accepts the listing insert the complete typed listing and its change into the sibling’s peer-listing slot
connected adapter accepts the listing, first round of the session run Lace-061 reconciliation steps under this phase’s deadline; each step item, complete-listing answer, or unshared listing is one retained output batch
connected adapter accepts the listing, later round encode the listing’s change as one Lace-060 ::offers-changed item against the previous listing plus the entries this side requested in the previous round
valid peer reconciliation item or delta with no active StoreCall advance reconciliation or apply the delta to the previous peer listing in place, first adding the entries the peer requested in the previous round; charge its bytes and the materialized entries to the round’s received-control counter; fill the peer-listing slot with the complete peer listing and its change once materialized
local output accepted and peer listing present enter Requesting with a new phase token
duplicate, wrong-family, malformed, skipped, early, extra, out-of-window, or inconsistent input typed peer failure

Requesting

Local/peer progress Result
phase entry start request evaluation over the complete peer advertisement and the existing round-local record boundary
evaluation creates StoreCall retain the endpoint-exclusive effect; accept no peer input until submission
evaluation completes freeze request set and release the peer listing; expose one peer-output effect; a connected adapter keeps the requested peer-listing entries for the next delta’s base unless the plan omits this side’s MaySend
valid peer request with no active StoreCall fill peer-request slot; a connected adapter keeps the requested local entries for the peer’s next delta’s base unless the plan omits the peer’s MaySend
local output accepted and peer request present, either set nonempty enter Answering with both directions frozen
local output accepted and peer request present, both sets empty create fresh FixedPointId, boundary, and one entry observation; the accepted request batch retains this phase’s deadline until flushed
duplicate, wrong-family, malformed, or skipped input typed peer failure

A local commit after the round boundary freezes cannot affect either the advertisement or request snapshot in that round.

Answering

Progress Result
outgoing obligation create exact-load StoreCall; accept no peer input until submission
outgoing load succeeds validate frozen commitment and expose record output
record output accepted settle outgoing obligation
matching response received validate record and projection; create admission StoreCall; stop peer input until submission
admission returns stored or duplicate settle incoming obligation
all incoming obligations settled, outgoing work remains, peer fence arrives retain one early peer fence
all obligations settle enter Fencing and expose fence output immediately
invalid, duplicate, unrequested, premature, or malformed input typed peer failure

A direct sibling endpoint may continue while this endpoint owns StoreCall, but routing into the blocked endpoint waits.

Fencing and fixed point

Fencing occurs only in a round where either frozen request set is nonempty.

Local fence Peer fence Result
not accepted either retain fence output
accepted absent wait
accepted present start fresh Round.Advertising

Fixed point is entered from Requesting when both frozen request sets are empty; a fence received for such a round is PeerProtocol.

The machine reports:

FixedPointBoundary {
  round: InterlaceRoundId,
  wake_boundaries: [FixedPointWakeBoundary],
}

FixedPointWakeBoundary {
  machine: MachineId,
  fixed_point: FixedPointId,
  position: StorePosition,
}

A connected machine reports one wake boundary; a direct pair reports one per protocol side. Same-Lace composition retains two independently tokened wake boundaries.

Input at fixed point Result
exact-boundary store advance enter Advertising
peer listing (connected: one delta applied to the previous peer listing; the previous request sets were empty) enter Advertising, fill peer slot, start local evaluation
peer fence Failed(PeerProtocol)
peer preface carrier retires session and enters reset prefacing
boundary EOF Closed(PeerClosed)
cancellation or Rust drop offer a compressed direction’s end mark once to the idle writer; Closed(Cancelled)

A retained terminal failure from a runtime-owned Lace is host lifecycle, not a machine input: the driver retires this operation and reports the same typed failure retained by that Lace.

A position delivery must match the complete current boundary. A replacement, peer input, or newer fixed point invalidates the old identity; stale readiness is discarded. Lace terminal failure is never discarded as stale. Fixed-point entry commits the semantic result. A bounded host then stops delivering peer input and settles its route under the settled round’s Requesting deadline, as Lace-050 defines. The write rows and the read row progress concurrently:

Bounded completion progress Result
final batch, then a compressed direction’s end mark, written and flushed shut down the writer
end-mark write fails drop unwritten output; shut down the writer
until the peer direction ends read it, decoding and discarding items
writer shut down and peer direction ended, end-mark write and shutdown succeeded release IO; complete
writer shut down and peer direction ended at boundary EOF with no further item after a failed step release IO; complete
writer shut down and peer direction ended otherwise after a failed step: item, truncation, or read failure release IO; that failure
Requesting deadline expires release IO; Timeout(Requesting)

Endpoint-exclusive effects

An endpoint owns at most one effect: StoreCall or peer output. Only the admission of a received response starts a StoreCall while peer output waits for the writer; the machine then reports the StoreCall first. While StoreCall is active, that endpoint consumes no peer input, stages no replacement, and starts no other effect. The connected driver races store execution, phase deadline, cancellation, and retained terminal failure from its runtime-owned Lace. Lace failure retires the semantic operation before already-started work can submit. Durable-position publication or Lace poisoning and response submission finish before ordinary polling resumes.

Every terminal transition retires active StoreCall in the semantic owner. SessionMachine retires its connected endpoint effect and DirectPair retires both endpoint effects; ConnectedCarrier, hosts, and FFI have no terminal discard input. Already-started work may retain its Lace long enough to publish a confirmed durable mutation, but cannot submit after retirement.

A direct pair may expose one effect from each endpoint in the same poll, including two StoreCall objects. A retained effect on one side never hides the other. Direct replacement is staged synchronously only through exclusive pair ownership and waits until both endpoint store effects settle. At the next poll, before endpoint or watch work, it atomically retires both endpoints and their plan, drops unaccepted typed output and machine observations, and constructs a fresh pair with the prepared operands, existing explicit authorities, and limits.

Peer output and input ownership

Machine output remains borrowed until direct insertion or connected-writer acceptance. The writer retains one accepted batch, its current chunk and offset through partial writes. Replacement drains the entire accepted old batch and writes the old encoding’s end mark before writing a fresh preface. The IO adapter owns any protection/framing and delivers only authenticated plaintext when protected. Its flush completes when it has accepted ownership of preceding plaintext within bounded buffering; it then owns delivery or failure. Reads and writes progress independently while respecting legal-input and active-StoreCall gates. Terminal failure drops retained output and aborts IO immediately. The batch accepted at the transition into fixed point retains its original absolute phase deadline through full write and flush; that flush gates fixed-point observation, bounded completion and clean close.

ConnectedCarrier::peer_record_ingress directs each peer record by the carrier’s state. The host’s codec state checks it at the record’s start, when its canonical length is known, before any byte reaches memory, staging or the store:

Carrier state Record
establishing, proof turn into memory, at most the exact proof size
establishing, requested operand Blob into memory, at most 1 MiB (PeerProtocol) and max_operand_bytes (LimitExceeded)
Answering with a requested response outstanding through the store’s record sink, within the round’s remaining transferred-record budget (LimitExceeded)
locally initiated reset prefacing validated through its framing LF and discarded, within the remaining reset control budget (LimitExceeded); the whole item length, label and framing LF included, is charged
any other state, including fixed point and bounded completion’s read to the peer end PeerProtocol

At most one decoded input may wait for immediate handoff. Without active StoreCall, the carrier classifies an already decoded item as accepted, immediately rejectable by core validation, or backpressured; hosts do not reconstruct this from owning state. Input is accepted only into the current state-local slot. Duplicate, out-of-order, wrong-family, or unrequested input fails at handoff rather than entering a semantic queue. The decoder retains item labels and listing forms; a label or form that does not match the owning state fails with PeerProtocol.

Failure and EOF

State/input Classification
adopted IO/protection error Transport, never successful EOF
boundary EOF during prefacing, establishment, or active/mandatory round PeerProtocol premature EOF
boundary EOF at fixed point clean peer closure
EOF inside a preface, line item, list item, or record item, or before a compressed encoding’s end mark PeerProtocol framing truncation
malformed encoded input or window/dictionary violation PeerProtocol
phase deadline, including a stalled reconciliation, retained final-batch drain, and bounded completion Timeout(phase)
local budget LimitExceeded(limit)
malformed, oversized, or out-of-order peer input PeerProtocol(detail)
policy, store, transport, or integration failure corresponding typed category

Transport establishment precedes Lace adoption and has no ILTP phase or deadline. The application owns its setup failures and cancellation. After adoption, EOF finalizes the ILTP decoder; a partial item or missing end mark still fails and only fixed-point boundary EOF is clean. Decoded canonical ILTP bytes alone count against ILTP control/transfer budgets.

Terminal handling drops retained output and staged replacement, writes no end mark, and immediately initiates carrier closure, without waiting for a peer close acknowledgment. Already platform-queued bytes may still arrive; no subsequent Lace work is submitted. Records already durably admitted remain stored. Successful fixed-point publication confirms settled transfer obligations, not permanent remote retention.