// Server-execution v2 fan-out stage A — OW17's instance-keyed serving // replica, wire, and tx→replica identity seam, END TO END against a real // memory server, a live ExecutorHost, and TWO flag-ON clients (Alice, // Bob): // // - the serving replica holds BOTH principals' instances of one scoped // doc, and each demanded run reads ITS instance — divergent per-user // inputs land divergent per-instance engine rows with the RIGHT // values (the OW17 VALUE half; pre-stage-A both runs read the one // scope-NAME-keyed local doc, the service's collapsed instance); // - the R7 wall: Alice's authored per-user draft plus her save event → // the served handler runs AS Alice, reads HER draft (not the service // instance's empty one), and writes her per-user consequence with the // typed value (pre-stage-A: consequenced with zero writes); // - the resubscribe path is instance-aware: after both instances ran, // BOB's input change wakes the node (the N-run loop resubscribes after // each instance to the UNION of its logs — pre-stage-A the last instance's // subscription replaced the others); // - S4 (basis rows keyed by the FULL instance address): a demand stamp // broader or narrower than the run's discovered instance leaves no // stranded rows — a session-scoped watch on a user-discovering node // records `user:

` rows, never `session:

:` (the ragged case's // zombie), and a space-discovering node records `space`. import { afterEach, beforeEach, describe, it } from "@std/testing/bdd"; import { expect } from "@std/expect"; import { Identity } from "@commonfabric/identity"; import * as MemoryV2Server from "@commonfabric/memory/v2/server"; import { ArrivalLog, awaitAdmitted, awaitReplica, } from "./support/serving-waits.ts"; import * as Engine from "@commonfabric/memory/v2/engine"; import { resolveScopeKey, type ScopeKeyIdentity, streamEntriesDocId, type StreamEventsDocValue, } from "@commonfabric/memory/v2"; import { acquireExecutionLease, releaseExecutionLease, } from "@commonfabric/memory/v2/execution-lease"; import { EmulatedStorageManager } from "../src/storage/v2-emulate.ts"; import type { Options } from "../src/storage/v2.ts"; import { Runtime } from "../src/runtime.ts"; import type { MemorySpace } from "../src/storage/interface.ts"; import { ExecutorHost } from "../src/executor/host.ts"; import { newSharedServer } from "./memory-v2-test-utils.ts"; /** The serving runtime's storage manager, with the serving-loop suite's * settle-gate seam: while `settleGate` is set, the loop's settle hangs * at its `inputSynced` barrier BEFORE any seal, so a cycle can be held * open across a lease tick with NO wave open (no tenure captured) — * the same-process reacquire then keeps the loop serving instead of * parking on a mid-wave abort. Undefined everywhere else. */ class GatedStorageManager extends EmulatedStorageManager { static override connectTo( server: MemoryV2Server.Server, options: Omit, ): GatedStorageManager { return super.connectTo(server, options) as GatedStorageManager; } settleGate: Promise | undefined; override async inputSynced(): Promise { await super.inputSynced(); if (this.settleGate !== undefined) await this.settleGate; } } const spaceSigner = await Identity.fromPassphrase("instance-keyed replica"); const space = spaceSigner.did() as MemorySpace; const serviceSigner = await Identity.fromPassphrase( "instance-keyed replica service", ); const aliceSigner = await Identity.fromPassphrase( "instance-keyed replica alice", ); const bobSigner = await Identity.fromPassphrase("instance-keyed replica bob"); /** A piece with per-user state on both sides of the run: a PerUser * draft the derivations READ, a PerUser save slot the handler WRITES, * and one space-only derivation (`label`) whose basis rows must key * `space` regardless of who demanded it. */ const PER_USER_PATTERN = [ "import { computed, Default, handler, pattern, PerUser, Stream, Writable } from 'commonfabric';", "type Draft = Writable>;", "const draftText = (draft: Draft): string =>", " (draft.get() as string | undefined) ?? '';", "const save = handler(", " (_ev, { draft, saved }) => {", " const text = draftText(draft).trim();", " if (text.length > 0) saved.set('saved:' + text);", " },", ");", "export default pattern<", " { draft?: PerUser; saved?: PerUser; n?: number },", " { echo: string; savedEcho: string; label: string; save: Stream }", ">(({ draft, saved, n }) => {", " const draftCell: Draft = draft!;", " const savedCell: Draft = saved!;", " return {", " echo: computed(() => 'echo:' + draftText(draftCell)),", " savedEcho: computed(() => 'saved-echo:' + draftText(savedCell)),", " label: computed(() => 'label:' + String(n ?? 0)),", " save: save({ draft: draftCell, saved: savedCell }),", " };", "});", ].join("\n"); /** The same surface with derivations that read NOTHING per-user: no * demanded run ever loads a principal's draft instance into the serving * replica, so the served save handler's read of Alice's draft is the * FIRST touch of her instance — the true R7 shape (group chat: type, * then save; the server may never have loaded the draft). */ const PER_USER_PATTERN_HANDLER_ONLY = PER_USER_PATTERN .replace("'echo:' + draftText(draftCell)", "'echo:const'") .replace("'saved-echo:' + draftText(savedCell)", "'saved-echo:const'"); if (PER_USER_PATTERN_HANDLER_ONLY === PER_USER_PATTERN) { throw new Error("handler-only pattern did not derive from the base"); } const sidecarIdsIn = (engine: Engine.Engine): string[] => (engine.database.prepare( `SELECT id FROM head WHERE id LIKE 'of:stream-events:%' AND op != 'delete'`, ).all() as Array<{ id: string }>).map((row) => row.id); /** Every current row of one scope INSTANCE: id → document value. */ const rowsUnder = ( engine: Engine.Engine, scopeKey: string, ): Map => { const rows = engine.database.prepare( `SELECT id FROM head WHERE scope_key = :scope_key AND op != 'delete'`, ).all({ scope_key: scopeKey }) as Array<{ id: string }>; const out = new Map(); for (const { id } of rows) { out.set(id, Engine.read(engine, { id, scopeKey } as never)?.value); } return out; }; const instanceHolds = ( engine: Engine.Engine, scopeKey: string, needle: string, ): boolean => [...rowsUnder(engine, scopeKey).values()].some((value) => JSON.stringify(value ?? null).includes(needle) ); const basisKeys = (engine: Engine.Engine): Set => new Set( (engine.database.prepare( `SELECT DISTINCT action_scope_key FROM scheduler_basis`, ).all() as Array<{ action_scope_key: string }>).map((row) => row.action_scope_key ), ); describe("stage A: the instance-keyed serving replica (OW17)", () => { let server: MemoryV2Server.Server; let host: ExecutorHost | undefined; let managers: EmulatedStorageManager[]; let runtimes: Runtime[]; let servingRuntime: Runtime | undefined; let servingManager: GatedStorageManager | undefined; let sessions: MemoryV2Server.SessionRegistry; let activations: ArrivalLog<{ space: string; outcome: string }>; const newHost = ( policy: ConstructorParameters[0]["policy"] = {}, ): ExecutorHost => new ExecutorHost({ server, serviceIdentity: serviceSigner.did(), // deno-lint-ignore require-await createRuntime: async () => { const manager = GatedStorageManager.connectTo(server, { as: serviceSigner, }); servingManager = manager; const runtime = new Runtime({ apiUrl: new URL(import.meta.url), storageManager: manager, servingPosture: true, experimental: { serverExecution: true, }, }); servingRuntime = runtime; return { runtime, dispose: async () => { await runtime.dispose(); await manager.close(); }, }; }, policy: { flushDeadlineMs: 5_000, idleParkMs: 600_000, ...policy }, onActivationSettled: (activatedSpace, outcome) => activations.record({ space: activatedSpace, outcome }), }); /** Resolves once `activatedSpace` has an ACTIVE tenure — activation * finishes on no admission or session edge of its own. */ const activated = (activatedSpace: MemorySpace): Promise => activations.matching((entry) => entry.space === activatedSpace && entry.outcome === "active" ); beforeEach(() => { // The registry is the test's own: a detached session lingers for the // TTL and its watches are still DEMAND, and the true-R7 test needs // an ephemeral typer's session GONE. Owning the registry lets it // remove that session outright instead of waiting the window out. sessions = new MemoryV2Server.SessionRegistry({ ttlMs: 250 }); server = newSharedServer({ subscriptionRefreshDelayMs: 0, sessions, }); managers = []; runtimes = []; servingRuntime = undefined; servingManager = undefined; activations = new ArrivalLog(); }); afterEach(async () => { await host?.close(); host = undefined; for (const runtime of runtimes) await runtime.dispose(); for (const manager of managers) await manager.close(); await server.close(); }); const openClient = (signer: Identity): Runtime => { const manager = EmulatedStorageManager.connectTo(server, { as: signer }); const runtime = new Runtime({ apiUrl: new URL(import.meta.url), storageManager: manager, experimental: { serverExecution: true }, }); managers.push(manager); runtimes.push(runtime); return runtime; }; /** Alice stands the piece up; Bob joins it. Each principal registers * BOTH demand halves: the space watch (the value pull) and an * identity-bearing scoped watch on the result doc (the demand row the * run supply consumes — P2-F's existing supply, which is how stage A * reaches cardinality 2 without stage B's space-root demanders). Each * writes a DIVERGENT per-user draft through the argument schema (the * narrowing write lands it in that principal's instance). */ const standUpTwoUsers = async (options: { bobScope: "user" | "session"; names: { arg: string; result: string }; hostPolicy?: ConstructorParameters[0]["policy"]; pattern?: string; }) => { // The host first: activation is triggered by session open / admission // (serving-loop.md §1), so the clients open against a live host. host = newHost(options.hostPolicy); const alice = openClient(aliceSigner); const bob = openClient(bobSigner); const engine = await server.engineForSpace(space); const compiled = await alice.patternManager.compilePattern({ main: "/main.tsx", files: [{ name: "/main.tsx", contents: options.pattern ?? PER_USER_PATTERN, }], }, { space }); const aliceArg = alice.getCell>( space, options.names.arg, undefined, ); const aliceResult = alice.getCell>( space, options.names.result, compiled.resultSchema, ); await aliceArg.sync(); await aliceResult.sync(); { const seed = alice.edit(); aliceArg.withTx(seed).set({ n: 1 }); expect((await seed.commit().settled).error).toBeUndefined(); } { const tx = alice.edit(); alice.run(tx, compiled, aliceArg, aliceResult); expect((await tx.commit().settled).error).toBeUndefined(); } await alice.idle(); await alice.storageManager.synced(); const argId = aliceArg.getAsNormalizedFullLink().id; const resultId = aliceResult.getAsNormalizedFullLink().id; // Demand FIRST (P2-F's supply — stage B's arrival re-arm is what // would let a demander who arrives after a clean run be served; here // the input change below is what re-runs the node): the space watch // (value pull) plus the identity-bearing scoped watch per principal. const bobResult = bob.getCell>( space, options.names.result, undefined, ); await bobResult.sync(); const cancelAlice = aliceResult.sink(() => {}); const cancelBob = bobResult.sink(() => {}); await alice.getCellFromLink({ ...aliceResult.getAsNormalizedFullLink(), scope: "user", }).sync(); await bob.getCellFromLink({ ...bobResult.getAsNormalizedFullLink(), scope: options.bobScope, }).sync(); await activated(space); await awaitAdmitted(server, () => { const demanded = host!.spaceServer(space)?.demandedIdentitiesOf( resultId, ) ?? []; return demanded.some((i) => i.principal === aliceSigner.did()) && demanded.some((i) => i.principal === bobSigner.did()); }); // Divergent per-user drafts, written THROUGH the argument schema so // the PerUser slot narrows into each writer's own instance. Each is // an authored input change that re-runs the demanded node — once // per demanded instance. const typedAliceArg = alice.getCell<{ draft: string; saved: string }>( space, options.names.arg, compiled.argumentSchema, ); { const tx = alice.edit(); typedAliceArg.key("draft").withTx(tx).set("A"); // Alice's `saved` slot exists in HER instance before any handler // touches it: a handler-only write to a never-written PerUser slot // lands at the slot's base scope (pre-existing OFF behavior — the // handler's handle carries no scope cap until the slot redirects; // flagged in the stage-A report, not stage A's), while a write to // an already-narrowed slot follows the sticky redirect into the // writer's instance (scopes.md §2 Permanence) — the group-chat // shape, where the client types the draft first. typedAliceArg.key("saved").withTx(tx).set(""); expect((await tx.commit().settled).error).toBeUndefined(); } const typedBobArg = bob.getCell<{ draft: string }>( space, options.names.arg, compiled.argumentSchema, ); await typedBobArg.sync(); { const tx = bob.edit(); typedBobArg.key("draft").withTx(tx).set("B"); expect((await tx.commit().settled).error).toBeUndefined(); } await alice.idle(); await bob.idle(); await alice.storageManager.synced(); await bob.storageManager.synced(); const aliceKey = resolveScopeKey("user", { principal: aliceSigner.did() }); const bobKey = resolveScopeKey("user", { principal: bobSigner.did() }); await awaitAdmitted( server, () => instanceHolds(engine, aliceKey, '"A"') && instanceHolds(engine, bobKey, '"B"'), ); return { alice, bob, engine, compiled, argId, resultId, aliceKey, bobKey, aliceResult, bobResult, typedAliceArg, typedBobArg, cancel: () => { cancelAlice(); cancelBob(); }, }; }; it("two demanded runs read their OWN per-user inputs through the instance-keyed replica: divergent inputs land divergent per-instance derived rows with the right values, and the serving replica holds both instances of the doc (OW17's value half; the R7 read shape)", async () => { const setup = await standUpTwoUsers({ bobScope: "user", names: { arg: "ika-a-arg", result: "ika-a-result" }, }); const { engine, aliceKey, bobKey, argId } = setup; // THE ARBITRATION: each principal's instance of the echo doc holds // ITS OWN input's echo. Pre-stage-A both instance runs read the one // scope-NAME-keyed local doc — the service instance's (empty) // draft — and wrote "echo:" under both keys. await awaitAdmitted( server, () => instanceHolds(engine, aliceKey, '"echo:A"') && instanceHolds(engine, bobKey, '"echo:B"'), ); // Never the sibling's value, never the collapsed empty one. expect(instanceHolds(engine, aliceKey, '"echo:B"')).toBe(false); expect(instanceHolds(engine, bobKey, '"echo:A"')).toBe(false); // The service identity's instance never received a DEMANDED run's // value (a pre-demand wave-level fallback run may have left the // empty "echo:" there — stage B's B5 residual; never a demander's). const serviceKey = resolveScopeKey("user", { principal: serviceSigner.did(), }); expect(instanceHolds(engine, serviceKey, '"echo:A"')).toBe(false); expect(instanceHolds(engine, serviceKey, '"echo:B"')).toBe(false); // The serving replica HOLDS both instances of the argument doc, // keyed apart, each with its own draft — the read seam's premise. const replica = servingRuntime!.storageManager.open(space).replica; const readDraft = (identity: ScopeKeyIdentity | undefined) => { const doc = replica.getDocument(argId as never, "user", identity); return (doc?.value as { draft?: string } | undefined)?.draft; }; expect(readDraft({ principal: aliceSigner.did() })).toBe("A"); expect(readDraft({ principal: bobSigner.did() })).toBe("B"); // And the replica's OWN (service) instance is not either of them. expect(readDraft(undefined)).not.toBe("A"); expect(readDraft(undefined)).not.toBe("B"); setup.cancel(); }); it("R7: Alice's authored per-user draft + her save event → the served handler runs AS Alice, reads HER draft through the instance-keyed replica, and writes her per-user consequence with the typed value (pre-stage-A: consequenced with zero writes)", async () => { const setup = await standUpTwoUsers({ bobScope: "user", names: { arg: "ika-r7-arg", result: "ika-r7-result" }, }); const { engine, aliceKey, bobKey, alice, aliceResult } = setup; // Let the derivations settle first (the save reads the same draft // instance the echo run already loaded — and the handler must read // it correctly whether or not a prior load happened). await awaitAdmitted( server, () => instanceHolds(engine, aliceKey, '"echo:A"'), ); const before = Engine.serverSeq(engine); (aliceResult.key("save") as unknown as { send(value: unknown): unknown }) .send({}); await alice.idle(); await alice.storageManager.synced(); await awaitAdmitted(server, () => sidecarIdsIn(engine).length === 1); const sidecarId = sidecarIdsIn(engine)[0]; await awaitAdmitted(server, () => { const value = Engine.read(engine, { id: sidecarId })?.value as | StreamEventsDocValue | undefined; return (value?.entries?.length ?? 0) >= 1 && value!.entries!.every((entry) => entry.consequenced === true); }); const entries = (Engine.read(engine, { id: sidecarId })?.value as StreamEventsDocValue) .entries!; expect(entries[0].firedAt?.user).toBe(aliceSigner.did()); expect(entries[0].error).toBeUndefined(); // THE R7 ARBITRATION: the consequence exists, under Alice's instance, // with the value she typed — the handler read HER draft, not the // service instance's empty one (which writes nothing). await awaitAdmitted( server, () => instanceHolds(engine, aliceKey, '"saved:A"'), ); // Under HER instance exactly: the arg doc's user instance holds both // her draft and the typed consequence; the space slot holds the // redirect, never the value. expect(rowsUnder(engine, aliceKey).get(setup.argId)).toEqual({ draft: "A", saved: "saved:A", }); expect( (rowsUnder(engine, "space").get(setup.argId) as { saved?: unknown }) ?.saved, ).not.toBe("saved:A"); expect(instanceHolds(engine, bobKey, '"saved:')).toBe(false); // The consequence rode a derived commit after the append. const consequenceRows = engine.database.prepare( `SELECT seq FROM "commit" WHERE seq > :from_seq AND class = 'derived' AND consequence_of IS NOT NULL`, ).all({ from_seq: before }) as Array<{ seq: number }>; expect(consequenceRows.length).toBeGreaterThanOrEqual(1); // And the per-user derivation over the SAVED slot re-derived for // Alice from her new instance value. await awaitAdmitted( server, () => instanceHolds(engine, aliceKey, '"saved-echo:saved:A"'), ); setup.cancel(); }); it("R7, the true shape: NO derivation ever loaded Alice's draft instance on the serving replica — type, then save — and the served handler still reads HER draft (the presync/preflight AS THE ACTOR is what loads it) and writes her per-user consequence with the typed value", async () => { // The pin the shipped R7 test above cannot be: there, Alice's echo // derivation had already loaded her instance into the serving // replica before the save, so the handler's actor-identity presync // and preflight were redundant backstops (the independent review's // M15/M16/M17 — each removable, all three together removable, and // that test stayed green). Here no demanded run reads the draft, so // the served handler's read of Alice's instance is the FIRST — and // the presync/preflight as the actor is load-bearing: with both // removed the handler reads the service instance's empty draft and // writes nothing (this test goes red). // // Fan-out stage B: the per-demander demand WALK follows a demander's // redirects wherever her watches reach — a RENDERING client (whose // runtime syncs the argument doc it renders) has its draft instance // pre-loaded by the walk, a legitimate demand read. The true-R7 // shape is therefore the NON-RENDERING actor (RULED 2026-08-16, the // event actor as a transient demander): Alice types through an // ephemeral runtime BEFORE the host exists (nothing walks), holds NO // watch on the space afterwards, and fires the save as a raw event // append from a session that syncs nothing. Bob's client watches the // root (the piece is demanded and served); Alice's instance is // untouched by any walk. const engine = await server.engineForSpace(space); const names = { arg: "ika-r7-noload-arg", result: "ika-r7-noload-result" }; let compiled: Awaited< ReturnType >; let argId: string; let resultId: string; { // Ephemeral creator + typer, as Alice, with no host serving. const manager = EmulatedStorageManager.connectTo(server, { as: aliceSigner, }); const creator = new Runtime({ apiUrl: new URL(import.meta.url), storageManager: manager, experimental: { serverExecution: true }, }); compiled = await creator.patternManager.compilePattern({ main: "/main.tsx", files: [{ name: "/main.tsx", contents: PER_USER_PATTERN_HANDLER_ONLY, }], }, { space }); const arg = creator.getCell>( space, names.arg, undefined, ); const result = creator.getCell>( space, names.result, compiled.resultSchema, ); await arg.sync(); await result.sync(); { const seed = creator.edit(); arg.withTx(seed).set({ n: 1 }); expect((await seed.commit().settled).error).toBeUndefined(); } { const tx = creator.edit(); creator.run(tx, compiled, arg, result); expect((await tx.commit().settled).error).toBeUndefined(); } await creator.idle(); argId = arg.getAsNormalizedFullLink().id; resultId = result.getAsNormalizedFullLink().id; // Type: the draft (and the pre-narrowed `saved` slot) through the // argument schema, into HER instance. const typed = creator.getCell<{ draft: string; saved: string }>( space, names.arg, compiled.argumentSchema, ); const tx = creator.edit(); typed.key("draft").withTx(tx).set("A"); typed.key("saved").withTx(tx).set(""); expect((await tx.commit().settled).error).toBeUndefined(); await creator.storageManager.synced(); const creatorSession = manager.id; await creator.dispose(); await manager.close(); // Detaching only starts the resume window; the watch stays DEMAND // until the registry prunes it. Remove it outright. sessions.remove(space, creatorSession); } const aliceKey = resolveScopeKey("user", { principal: aliceSigner.did() }); const bobKey = resolveScopeKey("user", { principal: bobSigner.did() }); expect(instanceHolds(engine, aliceKey, '"A"')).toBe(true); // No watch of Alice's exists when the host activates. expect( server.watchedRootsForSpace(space, { excludePrincipal: serviceSigner.did(), }).some((root) => root.identity?.principal === aliceSigner.did()), ).toBe(false); // NOW the host; Bob's client demands the piece (the root watch). host = newHost(); const bob = openClient(bobSigner); const bobResult = bob.getCell>( space, names.result, compiled.resultSchema, ); await bobResult.sync(); const cancel = bobResult.sink(() => {}); await activated(space); // The served constant derivations land (the piece is served)… await awaitAdmitted( server, () => instanceHolds(engine, "space", '"echo:const"'), ); // …and the serving replica has NOT loaded Alice's instance of the // argument doc — THE PRECONDITION that makes this the true R7 shape // (no watch of Alice's exists for any walk to follow). const replica = servingRuntime!.storageManager.open(space).replica; expect( replica.getDocument(argId as never, "user", { principal: aliceSigner.did(), }), ).toBeUndefined(); // Alice fires the save as a RAW event append from a session that // syncs nothing (the non-rendering actor): the entry is admitted // under her append authority and server-stamped with her `firedAt`. { const manager = EmulatedStorageManager.connectTo(server, { as: aliceSigner, }); try { // The stream the `save` slot links to (as Cell.send resolves it): // read off the stored result doc. const saveLink = (Engine.read(engine, { id: resultId })?.value as { save?: { "/": { "link@1": { id?: string; path?: string[] } } }; })?.save?.["/"]?.["link@1"]; const stream = { id: saveLink?.id ?? resultId, path: saveLink?.path ?? ["save"], }; const delivery = await manager.open(space).replica .enqueueEventAppend!({ sidecarId: streamEntriesDocId(stream as never), stream, eventId: `evt:${crypto.randomUUID()}:${resultId}`, payload: {} as never, }); expect(delivery.delivered).toBe(true); } finally { await manager.close(); } } await awaitAdmitted(server, () => sidecarIdsIn(engine).length === 1); const sidecarId = sidecarIdsIn(engine)[0]; await awaitAdmitted(server, () => { const value = Engine.read(engine, { id: sidecarId })?.value as | StreamEventsDocValue | undefined; return (value?.entries?.length ?? 0) >= 1 && value!.entries!.every((entry) => entry.consequenced === true); }); const entries = (Engine.read(engine, { id: sidecarId })?.value as StreamEventsDocValue) .entries!; expect(entries[0].firedAt?.user).toBe(aliceSigner.did()); expect(entries[0].error).toBeUndefined(); // THE R7 ARBITRATION under the true shape: the handler read HER // draft — loaded by its own actor-identity presync/preflight — and // wrote the typed consequence under her instance. await awaitAdmitted( server, () => instanceHolds(engine, aliceKey, '"saved:A"'), ); expect(rowsUnder(engine, aliceKey).get(argId)).toEqual({ draft: "A", saved: "saved:A", }); expect(instanceHolds(engine, bobKey, '"saved:')).toBe(false); cancel(); }); it("the resubscribe path is instance-aware: after both instances ran, BOB's input change wakes the node and his instance re-derives (the union of instance logs; pre-stage-A the last instance's subscription won)", async () => { const setup = await standUpTwoUsers({ bobScope: "user", names: { arg: "ika-resub-arg", result: "ika-resub-result" }, }); const { engine, aliceKey, bobKey, bob, typedBobArg } = setup; await awaitAdmitted( server, () => instanceHolds(engine, aliceKey, '"echo:A"') && instanceHolds(engine, bobKey, '"echo:B"'), ); // Both instances ran; whichever ran LAST holds the subscription // under the pre-stage-A "last instance wins" replacement. Change the // input of BOTH, one at a time, and require each to re-derive: the // one whose run was NOT last is the mutation target. { const tx = bob.edit(); typedBobArg.key("draft").withTx(tx).set("B2"); expect((await tx.commit().settled).error).toBeUndefined(); } await bob.idle(); await bob.storageManager.synced(); await awaitAdmitted( server, () => instanceHolds(engine, bobKey, '"echo:B2"'), ); expect(instanceHolds(engine, aliceKey, '"echo:B2"')).toBe(false); { const tx = setup.alice.edit(); setup.typedAliceArg.key("draft").withTx(tx).set("A2"); expect((await tx.commit().settled).error).toBeUndefined(); } await setup.alice.idle(); await setup.alice.storageManager.synced(); await awaitAdmitted( server, () => instanceHolds(engine, aliceKey, '"echo:A2"'), ); expect(instanceHolds(engine, bobKey, '"echo:A2"')).toBe(false); setup.cancel(); }); it("a lease lapse the SpaceServer survives in-process does not leave the serving replica silently stale: Alice's write inside the lapse is withheld, then — on the reacquire notice, with NO further write — re-delivered KEYED by the re-arm, her instance re-derives from it, and Bob's instance is untouched (finding 1's silent-stale half, end to end through the serving replica)", async () => { // The tick itself is not driven here (see the note below); the renew // interval is parked out of the way so no tick can interleave. const setup = await standUpTwoUsers({ bobScope: "user", names: { arg: "ika-blip-arg", result: "ika-blip-result" }, hostPolicy: { renewIntervalMs: 600_000, flushDeadlineMs: 3_000 }, }); const { engine, aliceKey, bobKey, alice, argId, typedAliceArg } = setup; await awaitAdmitted( server, () => instanceHolds(engine, aliceKey, '"echo:A"') && instanceHolds(engine, bobKey, '"echo:B"'), ); const spaceServer = host!.spaceServer(space)!; const replica = servingRuntime!.storageManager.open(space).replica; const readDraft = (identity: ScopeKeyIdentity | undefined) => (replica.getDocument(argId as never, "user", identity)?.value as | { draft?: string } | undefined)?.draft; expect(readDraft({ principal: aliceSigner.did() })).toBe("A"); expect(readDraft({ principal: bobSigner.did() })).toBe("B"); // Hold the loop's next cycle in its settle (before any seal): the // cycle Alice's write triggers must not attempt its watermark // advance against the expired row — a derived commit under an // expired row is refused (engine.ts's derived-class rule) and the // loop re-attempts it every cycle until the row is live again // (a PRE-EXISTING blip-window shape, recorded in the stage-A fix // report; not stage A's and not exercised here). const gate = Promise.withResolvers(); servingManager!.settleGate = gate.promise; // THE LAPSE: the lease row expires (an expired row matches nobody — // liveness is judged by expiry, serving-loop.md §2). Every push pass // now judges the loopback session a FORMER holder. releaseExecutionLease(engine, { space, holder: spaceServer.holder }); expect( acquireExecutionLease(engine, { space, holder: spaceServer.holder, now: Date.now() - 60_000, ttlMs: 1, }), ).toBe(true); // Alice types inside the lapse: the push pass WITHHOLDS her // instance from the loopback session (protocol.md §3's filter under // a lapsed lease — the P0 rule; never cached as delivered), so the // serving replica still reads "A" once the server has drained it. { const tx = alice.edit(); typedAliceArg.key("draft").withTx(tx).set("A-blip"); expect((await tx.commit().settled).error).toBeUndefined(); } await alice.idle(); await alice.storageManager.synced(); await server.idle(); expect(instanceHolds(engine, aliceKey, '"A-blip"')).toBe(true); expect(readDraft({ principal: aliceSigner.did() })).toBe("A"); // The reacquire, as the SpaceServer's renew arm performs it on a // survived blip (serving-loop.md §2's same-process reacquire): the // same holder restores the row, then reports it to the memory // server (`noteLeaseReacquired` — the arm's own call is pinned in // `executor-space-server.test.ts`; the tick is not driven here // because two pre-existing SpaceServer shapes make a tick-driven // survived blip non-deterministic in this fixture: the rejection // spin above, and an EMPTY seal — a read probe or a no-op // derivation — opening a `#currentWave` that outlives zero-delta // cycles with the pre-blip tenure, so the first real seal after the // reacquire aborts lease-lost and parks; both recorded in the fix // report as flagged residuals). NO watch is re-issued and NOTHING // else is written. expect( acquireExecutionLease(engine, { space, holder: spaceServer.holder, ttlMs: 600_000, }), ).toBe(true); server.noteLeaseReacquired({ space, principal: serviceSigner.did() }); // The re-arm's full evaluation re-delivers the withheld instance, // keyed. Pre-fix the lapse cleared the exemption for the session's // life; the replica kept "A" and every later per-user run of Alice // read a stale draft — silently. await awaitReplica( servingManager!, () => readDraft({ principal: aliceSigner.did() }) === "A-blip", ); // Release the held cycle: Alice's instance re-derives from the // re-delivered draft (the served per-user run reads the CURRENT // instance). gate.resolve(); servingManager!.settleGate = undefined; await awaitAdmitted( server, () => instanceHolds(engine, aliceKey, '"echo:A-blip"'), ); // Bob's instance and Alice's key never crossed: the re-arm named // instances, it did not collapse them; the loop kept serving. expect(readDraft({ principal: bobSigner.did() })).toBe("B"); expect(instanceHolds(engine, bobKey, '"echo:A-blip"')).toBe(false); expect(host!.spaceServer(space)?.active).toBe(true); setup.cancel(); }); it("S4: basis rows key by the run's FULL instance address — a session-scoped demand on a user-discovering node records user rows and NO session-keyed zombie; a space-discovering node records `space` under any demand stamp", async () => { const setup = await standUpTwoUsers({ bobScope: "session", names: { arg: "ika-s4-arg", result: "ika-s4-result" }, }); const { engine, aliceKey, bobKey } = setup; await awaitAdmitted( server, () => instanceHolds(engine, aliceKey, '"echo:A"') && instanceHolds(engine, bobKey, '"echo:B"'), ); await awaitAdmitted(server, () => { const keys = basisKeys(engine); return keys.has(aliceKey) && keys.has(bobKey) && keys.has("space"); }); const keys = basisKeys(engine); // Bob demanded through a SESSION-scoped watch: his runs are STAMPED // `session::`, but every node he ran discovered `user` (the // per-user draft) or `space` (`label`) — nothing session-scoped — so // no row is recorded under a session key (the ragged case's zombie: // rows a departed session could never overwrite). expect([...keys].some((key) => key.startsWith("session:"))).toBe(false); // The user-discovering derivations recorded rows under each // principal's USER instance — the address they actually served. expect(keys.has(aliceKey)).toBe(true); expect(keys.has(bobKey)).toBe(true); // The space-only `label` derivation recorded `space` (never // over-keyed under a demander's stamp). expect(keys.has("space")).toBe(true); // No row under the service identity's user instance: no demanded // node ran as the service. expect( keys.has(resolveScopeKey("user", { principal: serviceSigner.did() })), ).toBe(false); setup.cancel(); }); });