This note owns the implementation cut for restarting an open interlace after local durable store progress. The mechanism is deliberately broad:
FixedPointBoundary + Lace-owned retained position-or-terminal-failure signal
Stores remain policy-neutral. Hosts do not classify commits, replay records, or predict whether policy output will change.
An open endpoint at fixed point must notice a commit newer than the terminal round’s local record-fact boundary without moving interlace policy into the store or duplicating selection logic in each runtime.
The endpoint reports the terminal round’s shared local
StorePosition read-through. Any later position published by
the owning Lace makes another advertisement evaluation eligible. The
evaluation, not the wake signal, determines whether the selected set
changed. It updates the endpoint’s session state with the records
admitted since that boundary, so a wake costs work in proportion to
those records and the selections they change, not to the store (interlace-policy-lowering.md).
On fixed-point entry the machine reports:
FixedPointBoundary {
round: InterlaceRoundId,
wake_boundaries: [FixedPointWakeBoundary],
}
FixedPointWakeBoundary {
machine: MachineId,
fixed_point: FixedPointId,
position: StorePosition,
}
A connected machine has one wake boundary. A direct pair has one independently tokened wake boundary per protocol side, including same-Lace composition.
The fixed-point identity is an opaque ownership token for one exact settled state. Every logical session and direct replacement creates fresh identities. It prevents an asynchronous position result from being applied after peer input, policy replacement, or a newer fixed point has retired the old state.
The endpoint owns protocol state and the transition from a current
boundary to Round.Advertising. It does not own a store,
watch, callback, or task.
Each runtime-owned Lace owns one retained
position-or-terminal-failure signal. Before failure it contains the
latest confirmed monotonic StorePosition, so a subscriber
can read current state even when it missed the change edge. On the first
Lace-terminal failure it permanently contains that typed
Store or Integration error. Local mutation
completion and every authoritative refresh publish through this one
signal and the same mutation/publication gate.
At store adoption the Lace also retains the immutable
position_may_advance_externally boolean. When true, the
Lace owns the shared next_poll_at and
poll_in_flight state, physical probe lifetime, and polling
fanout. Concrete open operations own their subscriptions, endpoint
boundary registrations, transport and cancellation waits, and token
validation. Their fixed-point drivers consult the Lace-owned polling
state; they do not own per-operation cadence or another operation’s
machine.
The store owns durable records, StoreRecordId,
StorePosition, load, search, and store execution.
CurrentStorePosition is the authoritative external refresh
probe. The store does not know the adoption boolean, endpoints, compiled
plans, exposure views, protocol sides, host lifecycle, timers,
subscriptions, or callbacks.
Rust owns scalar StorePosition comparison,
FixedPointBoundary, FixedPointWakeBoundary,
and the endpoint transition that returns Accepted only for
an advance on the exact current token and Stale otherwise.
Native Rust drivers inspect that result. C/WASM projects the boundary
and a safe transition operation that treats stale delivery as a no-op.
PyO3 keeps the boundary in the machine wrapper, exposing its per-side
positions and a delivery that returns whether the advance was accepted.
They expose no policy-interest object, classifier key, candidate hint,
committed-record feed, or replay API.
The runtime-owned Lace owns a mutating store operation
through publication:
execute StoreOp
-> classify durable outcome
-> refresh CurrentStorePosition after mutating success or error
-> publish any position advance to retained Lace state
-> submit the active StoreCall response if its machine remains active
Publication occurs before completion becomes available to code that
could put an endpoint to sleep. Durable progress discovered while
returning StoreError is still published; the error remains
an error. A failed StoreRecords remains operation-local
when its mandatory refresh and publication succeed. Failure to refresh
after ordinary operation work is Store for that operation;
failure to publish a confirmed position is Lace-terminal
Integration. Neither failure permits successful mutation
submission. A position retained before publication fails remains
confirmed progress.
A Lace-owned external refresh performs
CurrentStorePosition under the same publication gate
without manufacturing a machine StoreCall. A successful
refresh publishes the greatest confirmed position even if the initiating
fixed-point token or operation became stale. External-probe failure is
Lace-terminal Store; failure to publish a confirmed
position is Lace-terminal Integration. The first
Lace-terminal failure atomically replaces the retained signal state,
clears polling state, wakes every subscriber, rejects all later store
execution and participant claims, and is returned by Lace close after
active work drains. A poisoned Lace never retries; recovery constructs a
fresh Lace and store object.
Operation retirement does not suppress publication or the terminal transition. Already-started non-cancellable work retains the Lace through durable classification but never submits to a retired machine. An ordinary operation-local store failure does not poison the Lace. Record observations never update position state. This one retained publication path keeps direct and connected routes identical. Stores have no delete operation; position is monotonic, and duplicate admission advances neither position nor the signal.
An open operation establishes its retained Lace-state subscriptions before it can install any fixed-point boundary; current runtimes do this when constructing the operation, or when a selecting connected operation adopts its selected Lace, which precedes its first session, and reuse the subscriptions until operation close. When an endpoint enters fixed point, the host closes the evaluation-to-sleep race in this order:
FixedPointWakeBoundary from the reported
FixedPointBoundary;boundary.position,
validate the token and report the advance;Subscribing before boundary installation ensures that a commit between output evaluation and boundary installation is either already represented by the retained position or observed afterward. No contiguous commit stream, recent-record ring, overflow marker, or record rescan is required.
A bounded operation does not install this registration or request external polling. A new fixed point replaces the previous token and position. Leaving fixed point, logical-session or direct replacement, closure, failure, or drop clears the tokened boundary registration; the operation-lifetime subscription remains until operation close. Poll cadence is Lace state and is not cleared or reset by one operation’s phase transition.
A position wait captures the complete boundary value. Before
delivery, the driver first processes any synchronously staged
replacement, then submits that value to the endpoint. Native Rust
drivers follow the authoritative Accepted or
Stale result. C/WASM hosts submit only a matching projected
token, and the safe binding transition treats any stale delivery as a
no-op; PyO3 delivers to the retained boundary for a side and reports
acceptance.
Advertising with its peer-listing slot
empty.Discarding a stale position result neither fails the active round nor schedules another round. Refresh and confirmed-position publication are Lace-scoped and still complete when delivery becomes stale; only submission of an advance to the endpoint is token-gated. A retained terminal Lace failure is not endpoint input and is not discarded as stale: it terminates every still-subscribed operation that uses that Lace. A commit already visible at the active round’s local record boundary is covered by both output evaluations. A newer commit remains newer than the round boundary at the next fixed point and is found by the next registration race.
There is one round-start mechanism: an advertisement listing, carried
as one Lace-060
::offers-changed item on a connected carrier.
Advertising; the
endpoint evaluates and sends its advertisement as soon as it is
ready.Advertising, stores that listing in the new round’s peer
slot, and starts local evaluation immediately.No side coordinates round start and neither side has priority after fixed point. The advertisement is ordinary policy output, not evidence that a particular record changed or that the round will transfer anything.
Polling is enabled by the immutable adoption metadata
position_may_advance_externally, never by inspecting a
concrete store type. false schedules no external probe.
true selects one fixed internal one-second interval.
Polling is requested only while at least one relevant open operation is
waiting at fixed point; bounded operations and active rounds do not
request it. CurrentStorePosition, not the timer or
metadata, supplies position authority.
Each Lace retains only:
next_poll_at
poll_in_flight
Every fixed-point driver consults that shared state. The first driver
at or after next_poll_at marks one probe in flight and
provisionally moves next_poll_at to one interval after the
start. Other drivers observe the in-flight flag or later time and
continue waiting on retained Lace state, legal transport, cancellation,
or that time. They do not join the probe, create a completion
generation, or queue another probe. If a driver’s observed deadline
expires while the probe remains active, that driver uses one local
interval as a retry bound instead of spinning.
Successful completion clears poll_in_flight and sets
next_poll_at to one interval after completion, including
when position did not advance. This update belongs to the Lace and does
not depend on the initiating operation remaining alive or receiving a
result. An advance follows ordinary monotonic publication and wakes all
subscribers; no advance publishes nothing. Failure instead clears
polling state and follows the Lace-wide poisoning path above. A
same-Lace direct pair and any number of staggered open operations
therefore cause at most one physical probe per shared interval. Separate
Lace objects remain separate refresh owners. Native filesystem Laces
have exclusive root ownership and do not request external polling;
cooperating LMDB processes each refresh through their own Lace.
lace-rt bounds its Mio wait and starts Lace-owned
blocking refresh work. lace-tokio selects the shared
deadline alongside retained state and connected IO and executes the
refresh inline or through spawn_blocking, as the adopted
backend’s execution marker requires. Python bounds both direct condition
waits and connected transport waits, executes a blocking refresh on its
owned store worker, and publishes from an operation driving that Lace.
All three continue legal transport, phase-deadline, and cancellation
driving while refresh is in flight.
There is no public interval option, persistent watcher thread or task, external notification ABI, callback, notification socket, process-wide scheduler, or store registry. Poll state and initiating operations do not process another operation’s machine. A future notification can only prompt the same authoritative refresh and retained publication path.
A position advance makes every open endpoint on that Lace whose current boundary is older eligible. A terminal Lace failure wakes and terminates every subscribed operation using that Lace. Broad fanout is intentional. Hosts do not inspect plans, fields, operation roles, or Datalog dependencies to narrow it.
A direct pair may use the same Lace for both endpoints through two
handles. That Lace’s one retained position-or-terminal-failure signal
serves both independently captured boundary tokens. Atomic direct
replacement drops both old tokens before either fresh endpoint runs. The
driver makes both current endpoints eligible, lets both start
Advertising, and routes their crossed listings normally. No
owner-identity rejection or special same-Lace protocol path is
needed.
Multiple commits before one endpoint runs require only the latest retained position. Once the endpoint leaves fixed point, later commits are covered by active output boundaries or the next registration. There is no per-record host work item.
The boundary comes from the machine’s actual round-local record snapshot, not from the Lace’s latest position when the host processes fixed-point entry. This preserves output scope: a commit after the round boundary freezes cannot alter either output in that round.
A bounded host returns only after the final accepted output batch is
flushed to the adopted IO and its route is closed or released. An open
host accepts clean item-boundary EOF at fixed point from a bounded peer
and transitions to clean closure. Operation close settles an
already-started authoritative refresh. Its retirement never suppresses
confirmed-position publication or Lace-wide poisoning. External-probe or
publication failure wakes every remaining subscriber with the retained
typed Store or Integration error, rejects
later work and participant claims, and is returned by Lace close after
active work drains. No result is submitted to a retired machine. Local
work not exchanged before closure remains eligible in a later fresh Lace
or session when the Lace was not poisoned.
Tests for this ownership cut cover:
StoreError still being
published;false, bounded operations, or open
operations outside fixed point;lace-rt, Tokio, and Python
connected and direct routes;