@demlik/tea 0.14.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -7
- package/dist/agent/index.d.ts +49 -36
- package/dist/agent/index.js +12 -8
- package/dist/chunk-4LPY67E4.js +18 -0
- package/dist/chunk-4LPY67E4.js.map +1 -0
- package/dist/chunk-5XU6ZJO2.js +533 -0
- package/dist/chunk-5XU6ZJO2.js.map +1 -0
- package/dist/{chunk-AQ6ZIMEA.js → chunk-6NG4V5SB.js} +89 -115
- package/dist/chunk-6NG4V5SB.js.map +1 -0
- package/dist/{chunk-HYDWG35Q.js → chunk-7MGXQZPW.js} +11 -9
- package/dist/chunk-7MGXQZPW.js.map +1 -0
- package/dist/{chunk-BLJ2JQSH.js → chunk-BCTEOVOU.js} +3 -3
- package/dist/{chunk-BLJ2JQSH.js.map → chunk-BCTEOVOU.js.map} +1 -1
- package/dist/chunk-CH5KTOEZ.js +710 -0
- package/dist/chunk-CH5KTOEZ.js.map +1 -0
- package/dist/chunk-CIHSHLQX.js +64 -0
- package/dist/chunk-CIHSHLQX.js.map +1 -0
- package/dist/{chunk-Z2L3LSNV.js → chunk-EHUDXAKC.js} +246 -210
- package/dist/chunk-EHUDXAKC.js.map +1 -0
- package/dist/chunk-GOX2CYIM.js +380 -0
- package/dist/chunk-GOX2CYIM.js.map +1 -0
- package/dist/chunk-IVJP3GKJ.js +104 -0
- package/dist/chunk-IVJP3GKJ.js.map +1 -0
- package/dist/{chunk-F7FMAWLA.js → chunk-MVZS5FDM.js} +13 -6
- package/dist/chunk-MVZS5FDM.js.map +1 -0
- package/dist/{chunk-LYLTKJWM.js → chunk-MYNLY3HP.js} +9 -8
- package/dist/chunk-MYNLY3HP.js.map +1 -0
- package/dist/{chunk-I5MQMJDW.js → chunk-NSIAORRY.js} +20 -30
- package/dist/chunk-NSIAORRY.js.map +1 -0
- package/dist/{chunk-MYXFNWAJ.js → chunk-QNGYQMZB.js} +4 -4
- package/dist/chunk-QNGYQMZB.js.map +1 -0
- package/dist/chunk-WT5PBPLB.js +98 -0
- package/dist/chunk-WT5PBPLB.js.map +1 -0
- package/dist/{core-CTzMJ82M.d.ts → core-BbgtiXdg.d.ts} +231 -139
- package/dist/do/index.d.ts +37 -32
- package/dist/do/index.js +21 -14
- package/dist/do/index.js.map +1 -1
- package/dist/{durable-effects-B0-qGQDy.d.ts → durable-effects-7MTK_jnj.d.ts} +1 -1
- package/dist/effect/index.d.ts +151 -0
- package/dist/effect/index.js +98 -0
- package/dist/effect/index.js.map +1 -0
- package/dist/extension/index.d.ts +6 -7
- package/dist/extension/index.js +3 -2
- package/dist/extension/index.js.map +1 -1
- package/dist/flow/index.d.ts +68 -70
- package/dist/flow/index.js +32 -27
- package/dist/flow/index.js.map +1 -1
- package/dist/idempotency/index.d.ts +6 -7
- package/dist/idempotency/index.js +4 -2
- package/dist/{index-DJWIER_3.d.ts → index-7vV8xmsD.d.ts} +1 -1
- package/dist/{index-NjrT3fL2.d.ts → index-Bz5Rh9Ga.d.ts} +19 -96
- package/dist/index-CjFDUBeq.d.ts +207 -0
- package/dist/{index-6A7dB8f6.d.ts → index-CkFYA9Y6.d.ts} +14 -16
- package/dist/{index-B5BZ-_cT.d.ts → index-Cou86-GX.d.ts} +189 -108
- package/dist/{index-TvRb1KVf.d.ts → index-DU6JpQ8G.d.ts} +1 -1
- package/dist/{index-q0hXFeZ0.d.ts → index-Xufl55W8.d.ts} +286 -215
- package/dist/{index-4vZzljCD.d.ts → index-_dOR3xqA.d.ts} +57 -45
- package/dist/index.d.ts +181 -385
- package/dist/index.js +2 -1
- package/dist/jev/index.d.ts +147 -99
- package/dist/jev/index.js +329 -233
- package/dist/jev/index.js.map +1 -1
- package/dist/{machine-CdIcN2Xm.d.ts → machine-BQzTV8On.d.ts} +171 -280
- package/dist/machine-viz/index.d.ts +5 -5
- package/dist/machine-viz/index.js +8 -4
- package/dist/machine-viz/index.js.map +1 -1
- package/dist/mem/index.d.ts +3 -4
- package/dist/mem/index.js +2 -1
- package/dist/mem/index.js.map +1 -1
- package/dist/node/index.d.ts +119 -78
- package/dist/node/index.js +52 -38
- package/dist/node/index.js.map +1 -1
- package/dist/paginate/index.d.ts +27 -33
- package/dist/paginate/index.js +6 -4
- package/dist/parity/index.d.ts +4 -5
- package/dist/parity/index.js +3 -2
- package/dist/parity/index.js.map +1 -1
- package/dist/pbt/index.d.ts +2 -2
- package/dist/pbt/index.js +2 -1
- package/dist/pbt/index.js.map +1 -1
- package/dist/persistence/index.d.ts +6 -7
- package/dist/persistence/index.js +5 -3
- package/dist/promise/index.d.ts +186 -0
- package/dist/promise/index.js +5 -0
- package/dist/promise/index.js.map +1 -0
- package/dist/protocol-ClRZBhHQ.d.ts +53 -0
- package/dist/react/index.d.ts +36 -17
- package/dist/react/index.js +27 -4
- package/dist/react/index.js.map +1 -1
- package/dist/resilience/index.d.ts +63 -455
- package/dist/resilience/index.js +37 -483
- package/dist/resilience/index.js.map +1 -1
- package/dist/{runtime-types-LWDoi943.d.ts → runtime-types-CiVpC0HN.d.ts} +131 -388
- package/dist/testing/index.d.ts +165 -15
- package/dist/testing/index.js +104 -3
- package/dist/testing/index.js.map +1 -1
- package/dist/timing/index.d.ts +25 -22
- package/dist/timing/index.js +4 -3
- package/dist/timing/index.js.map +1 -1
- package/dist/{types-DP3f5NIl.d.ts → types-LxZxGYda.d.ts} +2 -2
- package/dist/work-queue/index.d.ts +5 -6
- package/package.json +18 -5
- package/dist/chunk-AQ6ZIMEA.js.map +0 -1
- package/dist/chunk-F2US5BW6.js +0 -72
- package/dist/chunk-F2US5BW6.js.map +0 -1
- package/dist/chunk-F7FMAWLA.js.map +0 -1
- package/dist/chunk-HUKZQX6U.js +0 -97
- package/dist/chunk-HUKZQX6U.js.map +0 -1
- package/dist/chunk-HYDWG35Q.js.map +0 -1
- package/dist/chunk-I5MQMJDW.js.map +0 -1
- package/dist/chunk-LYLTKJWM.js.map +0 -1
- package/dist/chunk-MYXFNWAJ.js.map +0 -1
- package/dist/chunk-RQULHGYH.js +0 -1804
- package/dist/chunk-RQULHGYH.js.map +0 -1
- package/dist/chunk-Z2L3LSNV.js.map +0 -1
- package/dist/index-DMCeMPMJ.d.ts +0 -272
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/observability.ts","../src/provide/index.ts","../src/pure/core.ts","../src/internal/prediction/index.ts","../src/runtime-types.ts","../src/run.ts","../src/subs/types.ts","../src/subs/define-listener.ts","../src/subs/from-broadcast-channel.ts","../src/subs/from-event-source.ts","../src/subs/from-event-target.ts","../src/subs/from-interval.ts","../src/subs/from-port.ts","../src/subs/from-reconnecting-web-socket.ts","../src/subs/from-timeout.ts","../src/subs/from-web-socket.ts","../src/subs/managed-resource.ts","../src/subs/transport.ts"],"names":["dep","value","acceptedTypes","cell","stateName","opts"],"mappings":"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","file":"chunk-RQULHGYH.js","sourcesContent":["import type { BootingRuntime } from \"./runtime-types\";\n\n// === historyTracker: composable observability helper ===\n//\n// A bounded ring buffer of recent `(msg, state)` transitions, built on the\n// Runtime's public `observe` API. The substrate itself stays minimal — it has\n// no notion of history, no opt to enable one, no method on the Runtime\n// interface to read one. Anything that wants \"recent transitions\" composes via\n// this helper.\n//\n// Why not put this on the Runtime interface as `runtime.history()`? Because\n// history is derivable. Putting it on the Runtime privileges one use case\n// (debug inspectors) at the substrate level and grows the interface for\n// everyone; the composition shape stays out of the dispatch loop entirely, so\n// the substrate's hot path pays no cost for a feature it doesn't need.\n\nexport interface HistoryTracker<S, M extends { type: string }> {\n /**\n * Snapshot of recorded transitions, oldest first. Each entry is\n * `{ msg, state }`: `msg` is `null` for the boot transition (recorded via\n * `onBoot`) and the applied Msg for every other (recorded via `observe`).\n *\n * Returns a shallow copy: the array is fresh on every call (callers may\n * iterate, slice, or replay without affecting the tracker's buffer).\n * Entry values are references to the originals (TEA states/msgs are\n * conventionally immutable; do not mutate them if your S/M is not).\n */\n snapshot(): readonly { readonly msg: M | null; readonly state: S }[];\n /**\n * Detach the underlying observer. After `stop()`:\n * - No new transitions are recorded.\n * - `snapshot()` continues to work and returns the buffer's contents\n * at the moment of stop (useful for post-hoc inspection in tests).\n * - The tracker holds no references that would prevent GC of the\n * `runtime` argument other than the entries already buffered.\n *\n * Idempotent — subsequent calls are no-ops.\n */\n stop(): void;\n}\n\n/**\n * Create a bounded history tracker over a Runtime. The tracker subscribes to\n * the runtime via `observe(...)` and retains the last `size` `(msg, state)`\n * transitions in a FIFO ring buffer.\n *\n * @param runtime Any `BootingRuntime<S, M>` (a full `Runtime` satisfies it).\n * The tracker uses only `observe`, which is total before boot —\n * attach it to the synchronous `run()` handle to record the\n * boot transition.\n * @param size Buffer cap. `size <= 0` produces an inert no-op tracker:\n * no observer is attached to the runtime, `snapshot()` is\n * always `[]`, and `stop()` is a no-op.\n */\nexport function historyTracker<S, M extends { type: string }>(\n runtime: BootingRuntime<S, M>,\n size: number,\n): HistoryTracker<S, M> {\n const buffer: { msg: M | null; state: S }[] = [];\n let stopped = false;\n\n const push = (entry: { msg: M | null; state: S }): void => {\n buffer.push(entry);\n if (buffer.length > size) buffer.shift();\n };\n\n // The boot transition (the `{ msg: null, state }` head entry) arrives via\n // `onBoot`; applied transitions arrive via `observe` with a total `msg`. The\n // public snapshot shape (`msg: M | null`) is unchanged — boot is still\n // `msg: null`.\n const unobserve =\n size <= 0\n ? (): void => {}\n : runtime.observe((msg, state) => {\n push({ msg, state });\n });\n const unboot =\n size <= 0\n ? (): void => {}\n : runtime.onBoot((state) => {\n push({ msg: null, state });\n });\n\n return {\n snapshot() {\n // Shallow copy — callers may freely iterate or mutate the returned\n // array. Entry values are references; see HistoryTracker docs.\n return buffer.slice();\n },\n stop() {\n if (stopped) return;\n stopped = true;\n unobserve();\n unboot();\n },\n };\n}\n","/**\n * @packageDocumentation\n * The host-side provider graph — what satisfies a Cmd's `R` (Requirements)\n * channel.\n *\n * A `Cmd` is journaled data, so it can never carry a provider: a provider is a\n * closure, and a closure does not survive a `Store<S>` round-trip (ADR 0014).\n * The requirement it declares — `R` — is a TYPE, and a type needs no closure.\n * So the graph that SATISFIES it lives one layer out, in the host, where\n * closures are ordinary: `provide({ … })` builds the `ctx` object `run` already\n * takes, acquiring each provider once, in dependency order, and releasing them\n * in reverse when the run ends.\n *\n * The journal never sees any of this. Replay is a fold over Msgs (ADR 0014) and\n * a fold calls no handler, so it calls no `acquire`. The graph is host wiring —\n * hidden, per ADR 0015 — while the State it produced effects over stays visible.\n *\n * The contract is Effect's `Layer` + `Scope`, point for point, because that\n * shape has a decade of production behind it and inventing a fourth one here\n * would only be a fourth one to learn:\n *\n * 1. A provider is `acquire` plus an optional `release`; an `acquire` may depend\n * on other providers.\n * 2. Built once per scope, in dependency order, MEMOIZED — a provider two others\n * depend on is acquired exactly once.\n * 3. Released in reverse acquisition order, exactly once, on every terminal. A\n * `release` that throws does not stop its siblings from running.\n * 4. An `acquire` failure releases whatever was already acquired, in reverse,\n * then surfaces as a typed `ProvideFailedError` (ADR 0011) — never a throw\n * that escapes `run`.\n *\n * A dependency is named with a TOKEN that carries its value type, so `acquire`\n * needs no parameter annotation and a name the tokens do not list is a compile\n * error where it is written. That is Effect's `Context.Tag` — a token carrying\n * name and type together, with the requirement set derived from what the\n * constructor reads (ZIO's `ZLayer` + `ZIO.service[T]` is the same move):\n *\n * ```ts\n * const Config = dep<{ url: string }>()(\"config\");\n *\n * const scoped = provide({\n * config: value({ url: \"postgres://…\" }),\n * db: layer([Config], ({ config }) => connect(config.url), (db) => db.close()),\n * });\n *\n * // Either hand it straight to `run` — which acquires at boot and releases at\n * // `stop()` — or open it yourself when the host wires its own `ctx`.\n * const state = await driveToDone(run(machine, { ctx: scoped }), start, isDone);\n * ```\n *\n * The string-array form — `layer([\"config\"], ({ config }: { config: C }) => …)`\n * — is the UNTYPED escape hatch it remains beside. It spells each dependency\n * twice, once in `deps` and once in the annotation, and nothing ties the two\n * together until `provide` compares both against the map. Reach for it where\n * there is no token to hand: a dep name computed rather than written, or a graph\n * assembled against a `ctx` shape declared elsewhere.\n */\n\n/**\n * Brand marking a {@link Provided} graph apart from a hand-built `ctx`. Symbol\n * keyed and module-private, so it reaches no export and no `ctx` object can\n * collide with it by accident.\n */\nconst providedBrand: unique symbol = Symbol(\"demlik-tea.provided\");\n\n/**\n * One node of the graph: an `acquire`, an optional `release`, and the names of\n * the sibling providers `acquire` reads.\n *\n * `D` is the shape `acquire` receives — a record of the resolved values of\n * {@link Provider.deps}. Build one with {@link layer} or {@link value} rather\n * than by hand; the constructors are what keep `deps` and `D` in step.\n *\n * `K` is the dependency NAME set — the keys `deps` may spell. {@link layer}\n * infers it from the literal you pass, and {@link provide} constrains it to the\n * map's own keys, so a misspelled dependency is a compile error at the call site\n * rather than an {@link UnknownProviderError} at `open()`. It defaults to\n * `string` — the untyped reading, for a provider read back off an erased map.\n *\n * MIGRATION: that default is why an ANNOTATION of the two-argument form no\n * longer fits inside {@link provide}. `readonly string[]` is not assignable to\n * `readonly (\"config\" | \"db\")[]`, so `const db: Provider<string, D> = …` is\n * rejected — a leaf `Provider<Config>` with `deps: []` included, since the\n * default is what is compared, not the value. Either name the key set,\n * `Provider<string, D, \"config\" | \"db\">`, or drop the annotation and let\n * {@link layer} / {@link value} infer `K` from the literal, which is the shape\n * this API is written for.\n */\nexport interface Provider<\n T,\n D = Record<never, never>,\n K extends string = string,\n> {\n /** Names of the sibling providers `acquire` reads, resolved before it runs. */\n readonly deps: readonly K[];\n /**\n * Build the value. May be async; may read its declared `deps`.\n *\n * A function-typed PROPERTY, not a method: a method's parameters are\n * bivariant, and bivariance here would silently accept a provider whose deps\n * disagree with the map's — the one check `provide` exists to make.\n */\n readonly acquire: (deps: D) => T | Promise<T>;\n /**\n * Tear the value down. Optional — a provider with no `release` is a value with\n * no lifetime. May be async; the scope awaits it.\n *\n * A METHOD, unlike `acquire`: its parameter is this provider's OWN value, so\n * there is no sibling to cross-check and the bivariance a method's parameters\n * get is what lets a `Provider<Db, …>` be read through the erased\n * `Provider<unknown, …>` the map's constraint spells.\n */\n release?(value: T): unknown;\n}\n\n/** A provider whose value and dep shape are erased — the map's element type. */\ntype AnyProvider = Provider<unknown, never, string>;\n\n/**\n * The `ctx` a provider map produces: each key mapped to its provider's value.\n */\nexport type ProvidedCtx<M> = {\n [K in keyof M]: M[K] extends Provider<infer T, never, string> ? T : never;\n};\n\n/**\n * A provider with no dependencies — {@link layer}'s one-argument form and\n * {@link value}. Its `K` is `never`, so an empty `deps` fits EVERY map: a\n * leaf provider built through those constructors is admissible wherever it is\n * declared, whatever keys the map around it happens to have.\n *\n * It is the CONSTRUCTED form that this holds for. Annotating the same value\n * `Provider<T>` puts `K` back at its `string` default and outside `provide`'s\n * constraint — see the migration note on {@link Provider}.\n */\ntype LeafProvider<T> = Provider<T, Record<never, never>, never>;\n\n/**\n * A live scope — the `ctx` its graph produced, plus the one call that tears it\n * down. `release` is idempotent: the second call is a no-op, so a host that\n * releases in a `finally` beside a `run` that already released cannot double-free.\n */\nexport interface Scope<Ctx> {\n /** The built `ctx`, one field per provider. */\n readonly ctx: Ctx;\n /**\n * Release every acquired provider in reverse acquisition order, exactly once.\n * Each `release` is isolated: a throw is routed to `onReleaseError` and the\n * remaining releases still run. Never rejects.\n */\n release(): Promise<void>;\n}\n\n/**\n * Sink for a `release` that threw. A release failure has no caller to reject at\n * — the run is already over — so it is reported, never propagated.\n */\nexport type OnReleaseError = (error: unknown, provider: string) => void;\n\n/**\n * An unopened provider graph. Pass it to `run` as `ctx` (it acquires at boot and\n * releases at `stop()`), or {@link Provided.open} it yourself when the host\n * wires its own `ctx`.\n */\nexport interface Provided<Ctx> {\n /** Brand — see the module note. Never assigned by a consumer. */\n readonly [providedBrand]: true;\n /**\n * Acquire the whole graph and return the live {@link Scope}. Rejects with a\n * {@link ProvideFailedError} when an `acquire` fails, having already released\n * everything it had acquired, in reverse.\n */\n open(onReleaseError?: OnReleaseError): Promise<Scope<Ctx>>;\n}\n\n/**\n * An `acquire` failed. A typed failure (ADR 0011) rather than the raw throw:\n * `provider` names the node that failed and `cause` carries what it threw, so a\n * host reads which dependency the run could not stand up without matching on a\n * message.\n *\n * By the time this is raised, every provider acquired before it has been\n * released in reverse.\n */\nexport class ProvideFailedError extends Error {\n readonly _tag = \"provide_failed\" as const;\n /** The provider key whose `acquire` failed. */\n readonly provider: string;\n constructor(provider: string, cause: unknown) {\n super(\n `@demlik/tea: provider ${JSON.stringify(provider)} failed to acquire`,\n { cause },\n );\n this.name = \"ProvideFailedError\";\n this.provider = provider;\n }\n}\n\n/**\n * A provider named a dependency the map has no key for. A contract breach\n * (ADR 0011) — the wiring itself is wrong, so it throws rather than settling.\n *\n * `provide` binds `deps` to `keyof M`, so a map it typechecked can never raise\n * this: the typo is a compile error at the call site instead. What is left is\n * the UNTYPED path — a map cast (`as never`, `as any`), assembled at runtime, or\n * read back through an erased `Provider<unknown, …>` — where there was no key\n * set to check against. The error stays because that path is real, not because\n * the typed one still needs it.\n */\nexport class UnknownProviderError extends Error {\n readonly _tag = \"unknown_provider\" as const;\n /** The missing key. */\n readonly provider: string;\n /** The provider that asked for it. */\n readonly requiredBy: string;\n constructor(provider: string, requiredBy: string) {\n super(\n `@demlik/tea: provider ${JSON.stringify(requiredBy)} depends on ${JSON.stringify(provider)}, which the provider map has no entry for`,\n );\n this.name = \"UnknownProviderError\";\n this.provider = provider;\n this.requiredBy = requiredBy;\n }\n}\n\n/**\n * The dependency graph has a cycle, so no acquisition order exists. A contract\n * breach (ADR 0011): the wiring is wrong and no run can fix it.\n */\nexport class ProviderCycleError extends Error {\n readonly _tag = \"provider_cycle\" as const;\n /** The cycle, in the order it was walked, closing on its own first key. */\n readonly cycle: readonly string[];\n constructor(cycle: readonly string[]) {\n super(`@demlik/tea: provider dependency cycle — ${cycle.join(\" → \")}`);\n this.name = \"ProviderCycleError\";\n this.cycle = cycle;\n }\n}\n\n/**\n * Phantom key carrying a {@link DepToken}'s VALUE type. Declared, never\n * assigned: `dep` builds a token whose only runtime field is `name`, and this\n * property exists so the type survives into {@link DepsOf}. Symbol keyed and\n * module-private, so it reaches no export and no object literal can collide\n * with it.\n *\n * Typed `(probe: never) => T`, which makes the token COVARIANT in `T`: a\n * `DepToken<\"config\", Config>` is readable through the `DepToken<string,\n * unknown>` bound {@link layer}'s tuple is constrained by, while the value type\n * itself is still recovered exactly by {@link DepValue}'s `infer`.\n */\ndeclare const depValue: unique symbol;\n\n/**\n * A typed dependency name — Effect's `Context.Tag`. It carries the dependency's\n * literal NAME and its VALUE type in one value, so {@link layer} derives the\n * whole `acquire` parameter from the tokens and the caller annotates nothing.\n *\n * Build one with {@link dep}; the phantom field is not yours to write.\n */\nexport interface DepToken<N extends string = string, T = unknown> {\n /** The provider key this token stands for — the `keyof M` `provide` checks. */\n readonly name: N;\n /** Phantom — see the note on `depValue`. Never present at runtime. */\n readonly [depValue]?: (probe: never) => T;\n}\n\n/** The value type a {@link DepToken} carries. */\ntype DepValue<Token> = Token extends DepToken<string, infer T> ? T : never;\n\n/**\n * The `acquire` parameter a tuple of {@link DepToken}s describes: one property\n * per token, named by the token and typed with what it carries. This is the\n * derivation that removes the second spelling — `D` is no longer annotated, it\n * falls out of `deps`.\n */\nexport type DepsOf<Tokens extends readonly DepToken<string, unknown>[]> = {\n [N in Tokens[number][\"name\"]]: DepValue<Extract<Tokens[number], { name: N }>>;\n};\n\n/**\n * Mint a typed dependency token: `dep<Config>()(\"config\")`.\n *\n * CURRIED because TypeScript infers type arguments all-or-nothing — naming `T`\n * in a single call would force `N` to be spelled too, and a spelled `N` is the\n * widening this token exists to prevent. Effect's `Context.Tag(\"name\")<Self,\n * Shape>()` curries for the same reason; this one takes the type first so the\n * name stays inferred from the literal.\n *\n * ```ts\n * const Config = dep<{ url: string }>()(\"config\");\n * const Db = dep<Connection>()(\"db\");\n * const cache = layer([Config, Db], ({ config, db }) => …);\n * ```\n */\nexport function dep<T>(): <const N extends string>(name: N) => DepToken<N, T> {\n return (name) => ({ name });\n}\n\n/**\n * Declare a provider with no dependencies: an `acquire` and an optional\n * `release`.\n */\nexport function layer<T>(\n acquire: () => T | Promise<T>,\n release?: (value: T) => unknown,\n): LeafProvider<T>;\n/**\n * Declare a provider that depends on siblings, naming each one with a\n * {@link DepToken} — the TYPED route, and the one to reach for.\n *\n * `D` is {@link DepsOf} the tuple, so `acquire` takes NO annotation: its\n * parameter is already a record of exactly the tokens' names at exactly the\n * tokens' types. Both halves of a dependency mistake then land at THIS call —\n * destructuring a property the tuple does not name does not compile, and\n * reading one at the wrong type does not either — instead of surfacing inside\n * `provide`'s `M` constraint as a message about the map.\n *\n * ```ts\n * const Config = dep<Config>()(\"config\");\n * const db = layer([Config], ({ config }) => connect(config.url), (c) => c.end());\n * ```\n *\n * This is Effect's `Context.Tag`, and ZIO's `ZIO.service[T]`: the requirement\n * set is derived from what the constructor reads rather than restated beside it.\n */\nexport function layer<\n T,\n const Tokens extends readonly DepToken<string, unknown>[],\n>(\n deps: Tokens,\n acquire: (deps: DepsOf<Tokens>) => T | Promise<T>,\n release?: (value: T) => unknown,\n): Provider<T, DepsOf<Tokens>, Tokens[number][\"name\"]>;\n/**\n * Declare a provider that depends on siblings, naming each one with a STRING —\n * the untyped escape hatch. `deps` names them; `acquire` receives their resolved\n * values as a record, and the annotation you give that parameter is what types\n * `D`.\n *\n * Nothing ties the two spellings together: `layer([\"config\"], ({ config }: {\n * cfg: C }) => …)` type-checks here and fails later, inside `provide`'s `M`\n * constraint, in the map's vocabulary rather than the typo's. Prefer the token\n * overload above, which derives the annotation instead of restating it; reach\n * for this one where there is no token to hand.\n *\n * The names are inferred as literals, not widened to `string`, so {@link provide}\n * can check them against the map's keys. `const K` is what pins that: without\n * the modifier TypeScript 7 widens `[\"config\"]` to `string[]` here where 5.x\n * kept the literal, and every provider in the map then fails `provide`'s\n * key constraint with \"`string` is not assignable to `\"config\" | …`\".\n */\nexport function layer<T, D, const K extends string>(\n deps: readonly K[],\n acquire: (deps: D) => T | Promise<T>,\n release?: (value: T) => unknown,\n): Provider<T, D, K>;\nexport function layer<T, D, const K extends string>(\n first: readonly (K | DepToken<K, unknown>)[] | (() => T | Promise<T>),\n second?: ((deps: D) => T | Promise<T>) | ((value: T) => unknown),\n third?: (value: T) => unknown,\n): Provider<T, D, K> {\n // The two forms are told apart by the FIRST argument's kind, never by arity:\n // `layer(acquire)` and `layer(deps, acquire)` are both length 1-or-2 at the\n // call site once a `release` is optional.\n if (typeof first === \"function\") {\n return {\n deps: [],\n acquire: first as (deps: D) => T | Promise<T>,\n release: second as ((value: T) => unknown) | undefined,\n };\n }\n return {\n // Tokens collapse to their names here: `deps` is a name list at runtime\n // whichever overload wrote it, so the walk in `provide` stays one path and\n // a graph assembled from tokens journals nothing extra.\n deps: first.map((entry) =>\n typeof entry === \"string\" ? entry : entry.name,\n ),\n acquire: second as (deps: D) => T | Promise<T>,\n release: third,\n };\n}\n\n/**\n * Lift an already-built value into the graph — a provider with no `acquire` work\n * and no lifetime. The escape hatch for the config object, the clock, the\n * `fetch` you were handed: things a `ctx` carries that were never resources.\n */\nexport function value<T>(v: T): LeafProvider<T> {\n return { deps: [], acquire: () => v };\n}\n\n/**\n * Build an unopened provider graph from a map of providers.\n *\n * The map's own key set is the resulting `ctx`'s shape, and each provider is\n * checked against that shape on BOTH of its ends — so both halves of a wiring\n * mistake are a compile error here, not a surprise at 3 a.m.:\n *\n * - the `acquire` parameter, so a provider that reads `{ config: Config }`\n * beside a `config` provider of some other type does not compile;\n * - the `deps` names, bound to `keyof M`, so `layer([\"confg\"], …)` does not\n * compile either.\n *\n * Nothing is acquired until the graph is opened — by `run`, at boot, or by\n * {@link Provided.open}.\n */\nexport function provide<\n M extends {\n [K in keyof M]: Provider<unknown, ProvidedCtx<M>, Extract<keyof M, string>>;\n },\n>(map: M): Provided<ProvidedCtx<M>> {\n // Snapshot the map's own keys once, in declaration order: that order is the\n // tie-break the topological walk falls back on, so two runs of one graph\n // acquire in the same order and a journal-parity test has something stable to\n // compare against.\n const keys = Object.keys(map);\n const nodes = map as unknown as Record<string, AnyProvider>;\n\n return {\n [providedBrand]: true,\n async open(\n onReleaseError: OnReleaseError = defaultOnReleaseError,\n ): Promise<Scope<ProvidedCtx<M>>> {\n const built = new Map<string, unknown>();\n // Acquisition order, oldest first. This is the ONLY record release walks,\n // so a provider that never finished acquiring is never released — the\n // acquire/release pairing is by construction, not by bookkeeping.\n const acquired: { key: string; provider: AnyProvider }[] = [];\n // The current dependency PATH, not the visited set: a key is added on the\n // way down and removed on the way back up, so re-entering one that is\n // still on the path is a cycle, while a diamond re-entering a FINISHED one\n // hits the memo above and is not.\n const path: string[] = [];\n\n async function build(key: string, requiredBy: string): Promise<unknown> {\n if (built.has(key)) return built.get(key);\n const provider = nodes[key];\n if (provider === undefined) {\n throw new UnknownProviderError(key, requiredBy);\n }\n if (path.includes(key)) {\n throw new ProviderCycleError([...path.slice(path.indexOf(key)), key]);\n }\n path.push(key);\n const deps: Record<string, unknown> = {};\n for (const dep of provider.deps) {\n deps[dep] = await build(dep, key);\n }\n let acquiredValue: unknown;\n try {\n acquiredValue = await provider.acquire(deps as never);\n } catch (error) {\n throw new ProvideFailedError(key, error);\n }\n path.pop();\n built.set(key, acquiredValue);\n acquired.push({ key, provider });\n return acquiredValue;\n }\n\n // Release the acquired prefix in reverse, isolated. The one teardown path:\n // both the acquire-failure unwind and the scope's own `release` call it,\n // so \"reverse, exactly once, isolated\" is written down once.\n let released = false;\n async function releaseAll(): Promise<void> {\n if (released) return;\n released = true;\n for (let i = acquired.length - 1; i >= 0; i--) {\n const entry = acquired[i];\n if (entry === undefined) continue;\n const { key, provider } = entry;\n const release = provider.release;\n if (release === undefined) continue;\n try {\n await release(built.get(key) as never);\n } catch (error) {\n onReleaseError(error, key);\n }\n }\n }\n\n try {\n for (const key of keys) await build(key, key);\n } catch (error) {\n // Unwind before surfacing: whatever DID acquire has a lifetime, and a\n // failed boot is exactly when nobody else will end it.\n await releaseAll();\n throw error;\n }\n\n const ctx = Object.fromEntries(\n keys.map((key) => [key, built.get(key)]),\n ) as ProvidedCtx<M>;\n return { ctx, release: releaseAll };\n },\n };\n}\n\n/** Is this `ctx` argument an unopened provider graph rather than a plain `ctx`? */\nexport function isProvided<Ctx>(\n candidate: Ctx | Provided<Ctx> | undefined,\n): candidate is Provided<Ctx> {\n return (\n typeof candidate === \"object\" &&\n candidate !== null &&\n (candidate as Partial<Provided<Ctx>>)[providedBrand] === true\n );\n}\n\n// Absent sink → warn. A release throw is a real defect (a handle stayed open)\n// but the run it belonged to is already over, so there is nothing left to fail:\n// loud enough to be found, never fatal — the same reading `run`'s default\n// `onError` gives a teardown notice.\nfunction defaultOnReleaseError(error: unknown, provider: string): void {\n console.warn(\n `@demlik/tea: release of provider ${JSON.stringify(provider)} threw`,\n error,\n );\n}\n","/**\n * @demlik/tea — pure-core leaf (ADR 0006).\n *\n * This is the runtime-free pure core of the substrate. It holds the\n * client-prediction fold seam (`foldMsgs`), the form reader\n * (`formOf`/`detectUpdateForm`), and the pure type vocabulary (`Machine`,\n * `Reducer`, `Transitions`, `Cmd`, `Sub`, `Port`, …).\n *\n * **Dependency direction (the actual decoupling):** this module imports\n * NOTHING from the runtime — no `better-result`, no `run`/host/`Store`. The\n * runtime (`run`, the host, interpret, `Store`, subscribe — all in\n * `../index.ts`) imports *from* here; never the reverse. The root door\n * re-exports this surface through `./index.ts`, and\n * `pure/import-graph.test.ts` is the regression fence asserting the pure\n * entrypoint's import graph never reaches `run`.\n *\n * The one external name it reaches for is zod's TYPE surface (`import type`),\n * erased at compile time — `Cmd.define` accepts zod schemas, and the parse\n * against them happens at the interpret edge in `../run.ts`, never here.\n */\n\nimport type { z } from \"zod\";\n\n// === Dev-mode invariant enforcement ===\n//\n// Three runtime guards that catch TEA invariant violations during development.\n// Dead-code-eliminated in production by any bundler that replaces\n// `import.meta.env.DEV` (Vite) or `process.env.NODE_ENV` (webpack/esbuild).\n//\n// 1. deepFreeze(state) before passing to update — catches mutation\n// 2. Thenable check on return value — catches async update\n// 3. Walk cmd fields for function types — catches closures-as-data\n//\n// These enforce invariants 1 and 2 at runtime where the type system cannot.\nexport const __DEV__: boolean = (() => {\n try {\n const meta = import.meta as unknown as { env?: { DEV?: boolean } };\n if (meta.env?.DEV !== undefined) {\n return meta.env.DEV;\n }\n } catch {\n // import.meta not available (Node CJS, service workers)\n }\n try {\n return (\n typeof process !== \"undefined\" && process.env?.NODE_ENV !== \"production\"\n );\n } catch {\n return false;\n }\n})();\n\nexport function deepFreeze<T>(obj: T, seen?: WeakSet<object>): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n const proto = Object.getPrototypeOf(obj);\n if (proto !== Object.prototype && proto !== Array.prototype && proto !== null)\n return obj;\n const visited = seen ?? new WeakSet();\n if (visited.has(obj as object)) return obj;\n visited.add(obj as object);\n Object.freeze(obj);\n for (const v of Object.values(obj as Record<string, unknown>))\n deepFreeze(v, visited);\n return obj;\n}\n\nexport function hasFunctionValues(obj: unknown): string | null {\n if (obj === null || typeof obj !== \"object\") return null;\n for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {\n if (typeof value === \"function\") return key;\n }\n return null;\n}\n\nexport function assertPureResult(result: unknown, msgType: string): void {\n if (result && typeof (result as { then?: unknown }).then === \"function\") {\n throw new Error(\n `@demlik/tea: update cell \"${msgType}\" returned a Promise. ` +\n `update must be synchronous. Move async work to interpret.`,\n );\n }\n if (\n !Array.isArray(result) ||\n result.length < 2 ||\n !Array.isArray(result[1])\n ) {\n throw new Error(\n `@demlik/tea: update cell \"${msgType}\" returned a non-tuple. ` +\n `Expected [State, Cmd[]], got ${typeof result}.`,\n );\n }\n const cmds = result[1] as readonly { type: string }[];\n for (const cmd of cmds) {\n const fnField = hasFunctionValues(cmd);\n if (fnField !== null) {\n throw new Error(\n `@demlik/tea: Cmd \"${cmd.type}\" has function field \"${fnField}\". ` +\n `Cmds must be plain data, not closures.`,\n );\n }\n }\n}\n\n/**\n * Drop one `key` from a `Record` immutably — returns a new record with `key`\n * omitted, leaving the input untouched. The immutable-record-key-drop the L2\n * resilience bricks reach for whenever a settled/restarted call must forget its\n * per-key bookkeeping (a retry counter, a parked input). A plain\n * object-rest spread, lifted here so `resilient-call` and `authed-call` share\n * one definition instead of open-coding `const { [key]: _drop, ...rest } = rec`\n * at each site.\n */\nexport function without<V>(\n rec: Readonly<Record<string, V>>,\n key: string,\n): Readonly<Record<string, V>> {\n const { [key]: _dropped, ...rest } = rec;\n return rest;\n}\n\n// === Cmd: tagged-union, one-shot effect ===\n//\n// `E` and `R` are Effect's error and requirements channels, carried as PHANTOM\n// type parameters (ADR 0014): the runtime value stays `{ readonly type: T }` —\n// JSON-plain, hashable, replayable — and the two channels ride on optional\n// fields that are never assigned, exactly as `Port.__t` carries its `T`.\n//\n// - `E` — the `_tag` union this Cmd can settle with (`{ _tag: \"timeout\" } |\n// …`). A reducer's `_err` cell reads it, so a new failure mode is a compile\n// error at the cell, not a runtime surprise. Defaults to `unknown`, the\n// \"untyped\" reading every hand-written battery Cmd has today.\n// - `R` — REQUIREMENTS: the slice of `Ctx` this Cmd's interpret handler needs.\n// `run` demands the intersection of every Cmd's `R` (`RequiredCtx`), so a\n// missing dependency fails at `run`, not at 3 a.m. Defaults to `unknown` —\n// \"needs nothing\", and the identity of `&`, so `Ctx & RequiredCtx<C>` is\n// exactly `Ctx` for a machine with no typed Cmds. (`{}` would read the same\n// in prose but is NOT the identity: `Ctx & {}` refuses an unconstrained\n// `Ctx`, which every host adapter has.)\n//\n// Both channels are named by `Cmd.define`; a Cmd literal never spells them.\n// Every existing `Cmd<A>` and every battery's local Cmd union compiles unchanged\n// — the phantoms are optional, so a `{ type }` literal still satisfies `Cmd`.\n/**\n * A tagged-union, one-shot effect — JSON-plain, hashable, replayable.\n *\n * `T` is the tag. `E` and `R` are Effect's Error and **Requirements** channels,\n * carried as phantom type parameters (ADR 0014): `E` is the `_tag` union this\n * Cmd can settle with, and `R` is the slice of `Ctx` its interpret handler\n * reads. `R` is a requirement, not a wiring — what SATISFIES it is the `ctx`\n * handed to `run`, built by hand or by a `provide` graph that acquires each\n * dependency once and releases it when the run ends.\n *\n * @see {@link RequiredCtx} — every Cmd's `R`, intersected: what `run` demands.\n * @see `provide` — the host-side graph that builds a `ctx` satisfying `R`.\n */\nexport type Cmd<T extends string = string, E = unknown, R = unknown> = {\n readonly type: T;\n /** Phantom — the `_tag` union this Cmd can settle with. Never assigned. */\n readonly __e?: E;\n /** Phantom — the `Ctx` slice this Cmd's handler needs. Never assigned. */\n readonly __r?: R;\n};\n\n// === Typed effect channels: reading `E` and `R` back off a Cmd (ADR 0014) ===\n//\n// `RequirementsOf<C>` is one Cmd's `R`; `RequiredCtx<C>` is the intersection over a\n// whole Cmd union — what `run` demands of `ctx` beside the machine's own `Ctx`.\n// An untyped Cmd (`{ type }`, `__r` absent) infers `unknown` — \"requires\n// nothing\", the identity of `&` — so a machine of hand-written Cmds demands\n// exactly what it demanded before. `never` (a cmdless machine) intersects to\n// `unknown` too.\nexport type RequirementsOf<C> = C extends { readonly __r?: infer R }\n ? R\n : unknown;\n\n/** The `E` union one Cmd can settle with; `unknown` for an untyped Cmd. */\nexport type ErrorsOf<C> = C extends { readonly __e?: infer E } ? E : unknown;\n\ntype UnionToIntersection<U> = (\n U extends unknown\n ? (u: U) => void\n : never\n) extends (u: infer I) => void\n ? I\n : never;\n\n// `unknown` is the identity of `&` but the annihilator of `|`: a union of\n// `RequirementsOf` over a MIXED Cmd set (`{ http } | unknown`) collapses to\n// `unknown` before it can be intersected, and the machine demands nothing. Box\n// each member first so the \"requires nothing\" arms can be dropped, not absorbed.\ntype RequirementsBoxed<C> = C extends unknown ? [RequirementsOf<C>] : never;\ntype KnownRequirements<B> = B extends [infer R]\n ? unknown extends R\n ? never\n : R\n : never;\n\n/**\n * The `ctx` a machine's whole Cmd union requires: every Cmd's `R`, intersected.\n * `run` types its `ctx` as `Ctx & RequiredCtx<C>`, so handing a machine whose\n * Cmds need `{ http }` to a `run` whose ctx lacks it is a compile error. A Cmd\n * that requires nothing — untyped, or `Cmd.define`d without `requirements` — leaves\n * the demand of its siblings intact (#56).\n *\n * This is the requirement. `provide` is what satisfies it: hand `run` a\n * `provide({ … })` graph in place of the object and the same `Ctx` is built once\n * at boot, in dependency order, and released in reverse when the run ends.\n */\nexport type RequiredCtx<C> = UnionToIntersection<\n KnownRequirements<RequirementsBoxed<C>>\n>;\n\n// === Cmd.define: the typed Cmd constructor (ADR 0014 §1, 0015 §1) ===\n//\n// \"Types on the constructor, data in the record.\" A Cmd built by hand carries\n// no `E` and no `R`; one built by `Cmd.define` carries both, and the minted\n// settled Msgs (`<name>_ok` / `<name>_err`) are derived from the same\n// declaration — so the reducer, the interpret handler and the runtime edge all\n// read ONE source for what this effect can produce.\n//\n// Everything a constructor names is a TYPE or a SCHEMA; the value it returns is\n// still the dead record `{ type, ...input }`. `input` and `ok` are zod schemas\n// (zod is the one runtime dependency this adds); `err` is the `_tag` list a\n// handler may settle with; `requirements` is the `Ctx` slice the handler reads.\n//\n// The failure union always carries one kernel tag beside the declared ones:\n// `MalformedResult`, minted at the interpret edge when a handler's `_ok` value\n// fails the `ok` schema. Invariant 8 (the boundary parses, the core trusts): a\n// corrupt result becomes a typed `_err` the reducer already has a cell for, and\n// never reaches Model.\n\n/** The shape every settled failure has (ADR 0011): a plain `_tag` record. */\nexport type Tagged = { readonly _tag: string };\n\n/**\n * One declared failure per tag. Distributive, so `TaggedError<\"a\" | \"b\">` is\n * the two-arm union a `switch (error._tag)` narrows; the index signature lets a\n * settle site carry detail beside the tag (`{ _tag: \"timeout\", afterMs }`).\n */\nexport type TaggedError<Tag extends string> = Tag extends string\n ? { readonly _tag: Tag; readonly [detail: string]: unknown }\n : never;\n\n/**\n * The kernel-minted failure: a handler returned a `_ok` value the Cmd's `ok`\n * schema rejects. Plain data, so it folds into Model like any settled error;\n * `issues` is zod's issue list flattened to `path` + `message` strings.\n */\nexport type MalformedResult = {\n readonly _tag: \"malformed_result\";\n readonly issues: ReadonlyArray<{\n readonly path: string;\n readonly message: string;\n }>;\n};\n\n/** Render zod's issue list into the JSON-plain `MalformedResult`. */\nexport function malformedResult(\n issues: ReadonlyArray<{\n readonly path: ReadonlyArray<PropertyKey>;\n readonly message: string;\n }>,\n): MalformedResult {\n return {\n _tag: \"malformed_result\",\n issues: issues.map((issue) => ({\n path: issue.path.map(String).join(\".\"),\n message: issue.message,\n })),\n };\n}\n\n/**\n * The payload a constructor accepts: a plain record spread beside `type`. A\n * `type` key is refused at the type level — it would overwrite the discriminant.\n */\nexport type CmdInput = { readonly type?: never } & Record<string, unknown>;\n\n/**\n * Phantom carrier for a Cmd's `R`. `Cmd.requirements<{ http: Http }>()` is how a\n * declaration names the `Ctx` slice its handler reads — a type, not a value, so\n * nothing is constructed and nothing is checked at runtime.\n */\nexport type Requirements<R> = { readonly __r?: R };\n\n/** The value `Cmd.define(\"fetch\", …)` builds: `{ type: \"fetch\", ...input }`. */\nexport type CmdValue<\n Name extends string,\n Input extends CmdInput,\n E extends Tagged,\n R,\n> = Cmd<Name, E | MalformedResult, R> & Readonly<Input>;\n\nexport type SettledOk<Name extends string, C, Ok> = {\n readonly type: `${Name}_ok`;\n readonly cmd: C;\n readonly value: Ok;\n /** Stamped by the runtime at the interpret edge (`run`'s `clock`). */\n readonly at: number;\n};\n\nexport type SettledErr<Name extends string, C, E extends Tagged> = {\n readonly type: `${Name}_err`;\n readonly cmd: C;\n readonly error: E | MalformedResult;\n /** Stamped by the runtime at the interpret edge (`run`'s `clock`). */\n readonly at: number;\n};\n\n/**\n * What `Cmd.define` returns: the Cmd builder itself (`fetch({ url })`), with\n * the minted Msg builders and the declaration hung on it. `E` here is the\n * DECLARED tag union; the settled `_err` arm widens it by `MalformedResult`.\n *\n * `ok` / `err` take an optional `at` for minting OUTSIDE the runtime (a\n * `replay` log, a unit test); inside `run` the interpret edge stamps it from\n * the clock, so a handler never reads `Date.now()` itself.\n */\nexport interface CmdDef<\n Name extends string,\n Input extends CmdInput,\n Ok,\n E extends Tagged,\n R,\n> {\n (input: Input): CmdValue<Name, Input, E, R>;\n /** The `type` discriminant of every Cmd this builds. */\n readonly cmdType: Name;\n readonly okType: `${Name}_ok`;\n readonly errType: `${Name}_err`;\n readonly ok: (\n cmd: CmdValue<Name, Input, E, R>,\n value: Ok,\n at?: number,\n ) => SettledOk<Name, CmdValue<Name, Input, E, R>, Ok>;\n readonly err: (\n cmd: CmdValue<Name, Input, E, R>,\n error: E,\n at?: number,\n ) => SettledErr<Name, CmdValue<Name, Input, E, R>, E>;\n readonly schema: {\n readonly input: z.ZodType<Input>;\n readonly ok: z.ZodType<Ok>;\n };\n /** The declared `_tag` list, verbatim. */\n readonly errTags: ReadonlyArray<E[\"_tag\"]>;\n}\n\n/**\n * The declaration-erased view the runtime reads: which `type` a def builds,\n * which two Msg types it settles with, and the `ok` schema the edge parses\n * against. Every `CmdDef<…>` is one of these structurally.\n */\nexport type AnyCmdDef = {\n readonly cmdType: string;\n readonly okType: string;\n readonly errType: string;\n readonly schema: { readonly ok: z.ZodType };\n};\n\n// === The interpret edge — the boundary a `Cmd.define`d result crosses ===\n//\n// `run` builds ONE edge over `machine.cmds` and its clock, applies it to every\n// interpret handler's return, and hands the same edge to the handlers under\n// `cmdEdge` on ctx (beside `emit`). The hand-off is for a wrapper that invokes\n// a base handler INSIDE its own — `withResilience`'s `$resilience:run` carrier\n// — where `run`'s edge sees the carrier's `type`, never the def's, so the\n// base result would cross unparsed (#66). Settling through `cmdEdgeOf(ctx)`\n// at the site the def's handler is actually invoked keeps one parse and one\n// clock for the bare and the wrapped machine alike.\n\n/** Settle one handler's follow-up: parse an `_ok`, stamp `at`, or pass through. */\nexport type CmdEdge = (\n cmd: { readonly type: string },\n follow: unknown,\n) => unknown;\n\n/** The ctx key `run` hands its edge under. A symbol, so no Ctx port can collide. */\nexport const cmdEdge: unique symbol = Symbol(\"tea.cmdEdge\");\n\n/**\n * The edge over a def list (invariant 8: the boundary parses, the core trusts).\n * For a follow-up that is a def's own settled Msg: an `_ok` whose `value` fails\n * the `ok` schema becomes the minted `_err` carrying `malformed_result`, so a\n * corrupt result never reaches a reducer cell that would fold it into Model; an\n * `_ok` that passes carries the PARSED value (zod's strip/transform applied);\n * either arm gets `at` from the clock unless the builder was handed one.\n * Anything else — a hand-written Cmd's follow-up, a Msg outside the settled\n * pair — passes through untouched.\n */\nexport function cmdEdgeOver(\n defs: Iterable<AnyCmdDef>,\n clock: () => number,\n): CmdEdge {\n const byType = new Map<string, AnyCmdDef>();\n for (const def of defs) byType.set(def.cmdType, def);\n return (cmd, follow) => {\n const def = byType.get(cmd.type);\n if (def === undefined || !isSettledShape(follow)) return follow;\n const at = follow.at ?? clock();\n if (follow.type === def.okType) {\n const parsed = def.schema.ok.safeParse(follow.value);\n if (!parsed.success) {\n return {\n type: def.errType,\n cmd: follow.cmd,\n error: malformedResult(parsed.error.issues),\n at,\n };\n }\n return { ...follow, value: parsed.data, at };\n }\n if (follow.type === def.errType) return { ...follow, at };\n return follow;\n };\n}\n\n/**\n * The edge `run` put on this ctx, or the pass-through when the handler runs\n * outside `run` (a unit test calling it directly).\n */\nexport function cmdEdgeOf(ctx: unknown): CmdEdge {\n const edge =\n typeof ctx === \"object\" && ctx !== null\n ? (ctx as { [cmdEdge]?: CmdEdge })[cmdEdge]\n : undefined;\n return edge ?? ((_, follow) => follow);\n}\n\n// === The detached-work edge — work a handler outlives ===\n//\n// A handler that returns BEFORE its effect finishes (so the serial interpret\n// loop can reach the next Cmd — ADR 0018's fan-out-inside-the-Cmd shape) leaves\n// the runtime with no promise to count. Handing that promise to `detachWorkOf`\n// puts it back on the two accountings a returned promise would have been on:\n// `inFlightCmds`, which `stop()` reports as discarded work, and the serial\n// dispatch tail, which `idle()` drains to quiescence. Without it a fanned run\n// reads as quiescent while its tools are still running.\n\n/** Enlist a promise the handler will not return in the runtime's accounting. */\nexport type DetachWork = (work: Promise<unknown>) => void;\n\n/** The ctx key `run` hands its detach seam under — a symbol, like `cmdEdge`. */\nexport const detachWork: unique symbol = Symbol(\"tea.detachWork\");\n\n/**\n * The detach seam `run` put on this ctx, or a no-op when the handler runs\n * outside `run` (a unit test calling it directly), where there is no tail to\n * extend and no count to hold.\n */\nexport function detachWorkOf(ctx: unknown): DetachWork {\n const detach =\n typeof ctx === \"object\" && ctx !== null\n ? (ctx as { [detachWork]?: DetachWork })[detachWork]\n : undefined;\n return detach ?? (() => undefined);\n}\n\nfunction isSettledShape(follow: unknown): follow is {\n readonly type: string;\n readonly cmd: unknown;\n readonly value?: unknown;\n readonly at?: number;\n} {\n return (\n typeof follow === \"object\" &&\n follow !== null &&\n typeof (follow as { type?: unknown }).type === \"string\"\n );\n}\n\n/** The Cmd value a def (or a union of defs) builds. */\n// (`infer C extends Cmd` keeps the derived union inside `Machine`'s `C extends\n// Cmd` constraint — without it the inference site is unconstrained.)\nexport type CmdOf<D extends AnyCmdDef> = D extends ((\n input: never,\n) => infer C extends Cmd)\n ? C\n : never;\n\n/**\n * The settled-Msg union a def (or a union of defs) mints: `<name>_ok` carrying\n * `value`, `<name>_err` carrying `error`. `defineMachine({ cmds })` folds this\n * into the machine's `M` so the user never spells the effect half of it.\n */\nexport type Settled<D extends AnyCmdDef> =\n D extends CmdDef<infer Name, infer Input, infer Ok, infer E, infer R>\n ?\n | SettledOk<Name, CmdValue<Name, Input, E, R>, Ok>\n | SettledErr<Name, CmdValue<Name, Input, E, R>, E>\n : never;\n\n// Both read one slot of a `CmdDef`; every OTHER slot is `infer`red too, because\n// a fixed `string` / `CmdInput` there would sit in a contravariant position (the\n// call signature's `input`) and refuse every concrete def.\n\n/** The `Ok` a def's handler must produce. */\nexport type OkOf<D extends AnyCmdDef> =\n D extends CmdDef<infer _Name, infer _Input, infer Ok, infer _E, infer _R>\n ? Ok\n : never;\n\n/** The DECLARED failure union a def's handler may settle with. */\nexport type ErrOf<D extends AnyCmdDef> =\n D extends CmdDef<infer _Name, infer _Input, infer _Ok, infer E, infer _R>\n ? E\n : never;\n\nfunction defineCmd<\n const Name extends string,\n Input extends CmdInput,\n Ok,\n const Tags extends readonly string[],\n R = unknown,\n>(\n name: Name,\n spec: {\n readonly input: z.ZodType<Input>;\n readonly ok: z.ZodType<Ok>;\n readonly err: Tags;\n readonly requirements?: Requirements<R>;\n },\n): CmdDef<Name, Input, Ok, TaggedError<Tags[number]>, R> {\n type E = TaggedError<Tags[number]>;\n type C = CmdValue<Name, Input, E, R>;\n const okType = `${name}_ok` as const;\n const errType = `${name}_err` as const;\n const build = (input: Input): C => ({ ...input, type: name });\n return Object.assign(build, {\n cmdType: name,\n okType,\n errType,\n ok: (cmd: C, value: Ok, at?: number) =>\n stamp({ type: okType, cmd, value }, at),\n err: (cmd: C, error: E, at?: number) =>\n stamp({ type: errType, cmd, error }, at),\n schema: { input: spec.input, ok: spec.ok },\n errTags: spec.err,\n });\n}\n\n// The builders leave `at` ABSENT unless given one; the runtime fills it at the\n// interpret edge. The return type carries `at: number` because that is what\n// every reducer sees — no Msg reaches `update` unstamped.\nfunction stamp<T extends object>(\n msg: T,\n at: number | undefined,\n): T & { at: number } {\n return (at === undefined ? msg : { ...msg, at }) as T & { at: number };\n}\n\n// === SyncReturn<S, C>: the compile-time reentrancy guard (ADR 0003 #5) ===\n//\n// The canon rule (`.patterns/tea-do/reentrancy.md`,\n// `.patterns/tea-do/reentrancy-deadlock.md`): a reducer must never\n// inline-`await` a re-entrant result. \"Non-reentrant by default\" ≡ \"the reducer\n// is pure AND synchronous\": a reducer that returns a `Promise` (because it is\n// `async`, or inline-`await`s) is the suspended-but-still-blocking turn Orleans\n// serializes against — it occupies the single-writer slot across a suspension\n// point and can be re-entered mid-flight → deadlock.\n//\n// So the guard is purely type-level: every reducer/transition cell returns\n// `SyncReturn<S, C>` — the synchronous result tuple, intersected with `{ then?:\n// never }` to make it *non-thenable*. A `Promise<readonly [S, readonly C[]]>`\n// is an object with a `then` method, so it fails to satisfy `then?: never`; an\n// `async (s, m) => [...]` (or one that inline-`await`s) is therefore\n// unrepresentable at compile time — `tsc` rejects it *at the cell*, not at a\n// runtime hang. A plain synchronous tuple `[next, cmds]` has no `then` property,\n// so the optional-absent `then?: never` is satisfied and existing pure reducers\n// compile unchanged. `SyncReturn<S, C>` is also assignable *to* `readonly [S,\n// readonly C[]]` (the intersection is narrower), so the runtime dispatch in\n// `run`/`replay` consumes a cell result exactly as before.\n//\n// This mirrors `retry-backoff`'s `Rng` brand (#63): the obligation lives in the\n// type at the construction boundary (\"parse, don't validate\"), not in a comment.\nexport type SyncReturn<S, C extends Cmd> = readonly [S, readonly C[]] & {\n // A thenable carries a callable `then`; forbidding it rejects every Promise.\n // Optional + `never` means \"absent on a sync tuple, impossible on a Promise\".\n readonly then?: never;\n};\n\n// === update form: Reducer vs Transitions, tagged once ===\n//\n// The substrate accepts two `update` shapes (see the `Machine.update` union and\n// the `defineMachine` overloads):\n//\n// - \"reducer\" — flat record keyed by Msg.type, every cell a function.\n// - \"transitions\" — 2D table keyed by State.type then Msg.type, every cell a\n// record of functions.\n//\n// Which one a given machine is must be known at runtime by `run`, `replay`, and\n// the `withX` wrappers (their dispatch / key-enumeration / reserved-namespace\n// scans differ per form). Rather than re-derive it structurally at every reader\n// — a `typeof update[firstKey] === \"function\"` heuristic that breaks the day a\n// reducer cell is itself an object-with-a-call — `defineMachine` computes the\n// form ONCE at construction and stamps it on the machine as a non-enumerable\n// `__form` (so it never serializes, never collides with a Msg.type key, never\n// shows up in `Object.keys(machine)`). Every reader calls `formOf(machine)`.\nexport type UpdateForm = \"reducer\" | \"transitions\";\n\n// The single structural heuristic, defined ONCE. Used only by `defineMachine`\n// (and `formOf`'s fallback for machines built without it, e.g. a plain object\n// literal annotated as `Machine`). A Reducer's first own value is a function; a\n// Transitions table's first own value is a record (of functions). An empty\n// record (`M` is `never`) can never dispatch a Msg, so the form is irrelevant —\n// \"reducer\" is returned arbitrarily.\nexport function detectUpdateForm(update: object): UpdateForm {\n const firstKey = Object.keys(update)[0];\n if (firstKey === undefined) return \"reducer\";\n const firstValue = (update as Record<string, unknown>)[firstKey];\n return typeof firstValue === \"function\" ? \"reducer\" : \"transitions\";\n}\n\n// The single reader every form-sensitive site goes through. Prefers the\n// `__form` tag stamped by `defineMachine` (authoritative — computed once at the\n// typed construction boundary); falls back to `detectUpdateForm` only for a\n// machine that never passed through `defineMachine`. No reader re-implements the\n// heuristic.\nexport function formOf(machine: {\n update: object;\n __form?: UpdateForm;\n}): UpdateForm {\n return machine.__form ?? detectUpdateForm(machine.update);\n}\n\n// === NoCellError: the named cell-lookup failure (#276) ===\n//\n// An unknown `msg.type` (wire data reaching dispatch) or a type-bypassed\n// missing cell used to surface as a bare `TypeError: ... is not a function`\n// deep inside dispatch — no msg.type, no state name, nothing actionable. The\n// guard lives in `applyCell` because it is the single dispatch primitive\n// every stepping site goes through (#275), so one guard covers `run`,\n// replay/foldMsgs, the PBT fold runner, and the withX wrappers.\n//\n// It also carries `acceptedTypes` — what the refusing state WOULD have taken\n// (#14). Without it a caller learns \"not this one\" and nothing else, so\n// discovering that a state accepts nothing at all took one refusal per Msg\n// type: N probe dispatches to establish one fact. The empty set is the\n// load-bearing case, so the message states it in words rather than rendering an\n// empty list — a caller skimming `accepts: []` reads a formatting artefact,\n// not a dead end.\nexport class NoCellError extends Error {\n override readonly name = \"NoCellError\";\n readonly _tag = \"NoCellError\" as const;\n constructor(\n public readonly msgType: string,\n public readonly stateName: string,\n /** The Msg types the refusing state has cells for; empty when it has none. */\n public readonly acceptedTypes: readonly string[],\n ) {\n super(\n // The pre-#14 text is kept VERBATIM as a prefix: a caller matching on it\n // keeps matching, and the new clause only ever appends.\n `@demlik/tea: no update cell for msg.type \"${msgType}\" in state ` +\n `\"${stateName}\" — the machine's update does not handle this Msg ` +\n `(an unknown wire msg.type, or a missing cell reached by bypassing ` +\n `the mapped types).` +\n (acceptedTypes.length === 0\n ? ` This state accepts no Msg at all.`\n : ` This state accepts: ${acceptedTypes\n .map((t) => `\"${t}\"`)\n .join(\", \")}.`),\n );\n }\n}\n\n// Reducer-form State carries no mandatory discriminant; best-effort read of a\n// string `state.type` for the error, else a placeholder.\nfunction stateNameOf(state: unknown): string {\n if (state === undefined || state === null) return \"(no state)\";\n if (typeof state === \"object\" && \"type\" in state) {\n const t = (state as { type: unknown }).type;\n if (typeof t === \"string\") return t;\n }\n return \"(untagged state)\";\n}\n\n// === acceptedTypes: what a state WOULD take, asked before the refusal ===\n//\n// The refusal's `acceptedTypes` and this helper are ONE reading, not two that\n// agree by inspection: `lookupCell`'s miss arm calls this function, so a caller\n// that asks first and a caller that dispatches and catches can never be told\n// different things about the same `(machine, state)` pair (#14, folded #21).\n//\n// It takes a STATE, not a `state.type`, which is what separates it from\n// `acceptsOf` next door: `acceptsOf` answers about a state NAME a tool already\n// has in hand, and this answers about the state value a caller is actually\n// holding — including a reducer-form state that carries no discriminant at all.\n// That untagged case is handled exactly as the refusal path handles it: the\n// reducer form never consults the state, so the flat table's keys ARE the\n// answer and nothing throws.\n//\n// A NULLISH state is not an untagged state — it is no state at all, so it\n// accepts nothing in either form (#196). Reading `.type` off it would have\n// thrown under the transitions form, which the doc below promises never\n// happens, and answering the flat table's keys under the reducer form would\n// name a set for a machine that has not booted.\n//\n// Returns a fresh array, empty when the state has no cells — never `undefined`,\n// so a caller can `.includes` the result without a null check.\n/**\n * The Msg types this machine would accept in this state — the same set a\n * `NoCellError` reports, asked before anything is dispatched. Returns the\n * state's own row keys in transitions form and the flat table's keys in\n * reducer form, counting only keys whose cell is a function, and an empty\n * array (never `undefined`, never a throw) for a state with no cells, no row\n * at all, or no state value at all.\n */\nexport function acceptedTypes<S>(\n machine: { update: object; __form?: UpdateForm },\n state: S,\n): readonly string[] {\n if (state === undefined || state === null) return [];\n if (formOf(machine) === \"reducer\") {\n // Dispatch here never consults the state, so the flat table's own keys are\n // the whole accepted set — the same reading `msgKeysOf` gives this form,\n // and it is well-defined for an untagged state.\n return cellKeysOf(machine.update);\n }\n const table = machine.update as Record<\n string,\n Record<string, unknown> | undefined\n >;\n const row = table[(state as unknown as { type: string }).type];\n // A state with no row at all — a type-bypassed or absent `state.type` —\n // accepts nothing, which is true of it.\n return row === undefined || row === null ? [] : cellKeysOf(row);\n}\n\n// `lookupCell` admits a cell only on `typeof cell === \"function\"`, so the\n// accept-set reading applies the SAME admission (#196). A non-function row\n// value is unreachable through the mapped `Transitions`/`Reducer` types and\n// reachable through a cast or wire-shaped data, and reporting one as accepted\n// promises a dispatch the refusal path would then refuse.\nfunction cellKeysOf(row: object): readonly string[] {\n return Object.keys(row).filter(\n (key) => typeof (row as Record<string, unknown>)[key] === \"function\",\n );\n}\n\n// === lookupCell: THE single cell SELECTION, split from the invocation ===\n//\n// The form-branching (`reducer` → flat `update[msg.type]`; `transitions` →\n// `update[state.type][msg.type]`) lives here and NOWHERE else. `applyCell`\n// (throwing) and `tryApplyCell` (`Result`-returning, in `../runtime-types`)\n// are both thin skins over this one selection, so the two error disciplines\n// can never disagree about WHICH cell a `(machine, state, msg)` triple picks\n// — the failure mode a second hand-written copy of the branching would have.\n//\n// Returns the selected cell (or `undefined` when there is none) together with\n// the `stateName` the `NoCellError` message needs — the caller decides whether\n// that absence becomes a throw or an `Err`.\n//\n// The MISS arm additionally carries `acceptedTypes`, and it is a union rather\n// than one optional field because the accepted set is only ever a fact about a\n// refusal: on a hit there is no set to state, and a field holding `[]` there\n// would read as \"accepts nothing\" to anyone who looked (#14).\n//\n// Pure and allocation-light: one small record per lookup, never a closure. The\n// keys array is allocated on the miss arm only, so the dispatch hot path is\n// unchanged.\nexport type CellLookup<S, M, C extends Cmd> =\n | {\n readonly cell: (state: S, msg: M) => readonly [S, readonly C[]];\n readonly stateName: string;\n }\n | {\n readonly cell: undefined;\n readonly stateName: string;\n readonly acceptedTypes: readonly string[];\n };\n\nexport function lookupCell<S, M extends { type: string }, C extends Cmd>(\n machine: { update: object; __form?: UpdateForm },\n state: S,\n msg: M,\n): CellLookup<S, M, C> {\n type CellFn = (state: S, msg: M) => readonly [S, readonly C[]];\n // A nullish state is no state at all, and it refuses BEFORE the form branch\n // in both forms (#199). Under transitions, reading `.type` off it threw a\n // `TypeError` where the whole path otherwise raises `NoCellError`; under\n // reducer, dispatch never consults the state, so a cell would have RUN on a\n // machine that has not booted — and `acceptedTypes` already answers `[]`\n // there (#196), which this arm is what makes true.\n if (state === undefined || state === null) {\n return {\n cell: undefined,\n stateName: stateNameOf(state),\n acceptedTypes: acceptedTypes(machine, state),\n };\n }\n if (formOf(machine) === \"reducer\") {\n const record = machine.update as Record<string, CellFn | undefined>;\n const cell = record[msg.type];\n const stateName = stateNameOf(state);\n return typeof cell === \"function\"\n ? { cell, stateName }\n : {\n cell: undefined,\n stateName,\n acceptedTypes: acceptedTypes(machine, state),\n };\n }\n const table = machine.update as Record<\n string,\n Record<string, CellFn | undefined> | undefined\n >;\n // The ONE sanctioned `state as unknown as { type }` read: the Transitions\n // overload constrains S to `{ type: string }` at the `defineMachine`\n // boundary, but that constraint is erased on the runtime-facing `object`\n // here — every former per-site copy of this double-cast collapsed into\n // this line (#275).\n const stateKey = (state as unknown as { type: string }).type;\n const cell = table[stateKey]?.[msg.type];\n const stateName = String(stateKey);\n return typeof cell === \"function\"\n ? { cell, stateName }\n : {\n cell: undefined,\n stateName,\n acceptedTypes: acceptedTypes(machine, state),\n };\n}\n\n// === applyCell: THE single reducer-vs-transitions dispatch primitive ===\n//\n// Applies the one update cell selected by `lookupCell(machine, state, msg)` and\n// returns its `[nextState, cmds]` verbatim. Every site that steps a machine —\n// `run`'s applyUpdate, `foldUpdates` (replay/foldMsgs), the PBT fold runner,\n// and the withX wrappers — dispatches through THIS function, so production and\n// the verification tools agree on the update form by construction (#275).\n// Pure and dev-check-free: `deepFreeze`/`assertPureResult` stay at the call\n// sites that want them. A missing cell throws `NoCellError` (#276), never a\n// bare TypeError.\n//\n// The `Result`-returning twin is `tryApplyCell` (`@demlik/tea` root; it needs\n// `better-result`, which this pure leaf must not import). Both read the SAME\n// `lookupCell`, so \"which cell\" is decided once.\nexport function applyCell<S, M extends { type: string }, C extends Cmd>(\n machine: { update: object; __form?: UpdateForm },\n state: S,\n msg: M,\n): readonly [S, readonly C[]] {\n const found = lookupCell<S, M, C>(machine, state, msg);\n if (found.cell === undefined) {\n throw new NoCellError(msg.type, found.stateName, found.acceptedTypes);\n }\n return found.cell(state, msg);\n}\n\n// === applyCellChecked: `applyCell` wrapped in the DEV pre/post invariant pair ===\n//\n// The dev-mode discipline every fold site shares: `deepFreeze` the input `state`\n// so a reducer that mutates it in place trips synchronously, then\n// `assertPureResult` the returned `[state, cmds]` shape. Both guards compile out\n// of production (`__DEV__`). `run`'s dispatch loop and `foldUpdates` both step\n// through THIS wrapper so the invariant enforcement lives in exactly one place\n// and cannot drift between the runtime and the pure fold.\nexport function applyCellChecked<S, M extends { type: string }, C extends Cmd>(\n machine: { update: object; __form?: UpdateForm },\n state: S,\n msg: M,\n): readonly [S, readonly C[]] {\n if (__DEV__) deepFreeze(state);\n const result = applyCell<S, M, C>(machine, state, msg);\n if (__DEV__) assertPureResult(result, msg.type);\n return result;\n}\n\n// === msgKeysOf: recover the Msg.type set from either update form ===\n//\n// A Reducer's own keys ARE the Msg.type set. A Transitions table's keys are\n// state.type; its INNER keys are the Msg.type set, so the UNION of every row's\n// inner keys is read — first-seen order, deduped. An empty update (`M` is\n// `never`) yields `[]`. Keyed on `formOf` — the withX wrappers and the PBT\n// `msgTypeKeys` all read through this one helper (#275).\n//\n// Why the union and not the first row's keys (the former reading): the\n// mapped-type `Transitions<S, M, C>` contract makes the Msg key set uniform\n// across phases, so for a hand-written TOTAL table the first row already IS\n// the union and this is a no-op. But the contract only binds where the types\n// bind. A table assembled DYNAMICALLY — the discriminants widened to plain\n// `string`, rows pushed in a loop — is structurally ragged, and reading row\n// zero then under-reports the Msg union. That under-report is not cosmetic:\n// all three withX wrappers build their flat merged Reducer by iterating\n// `msgKeysOf(base)`, so a Msg missing from row zero got NO cell in the wrapped\n// machine and threw `NoCellError` at dispatch for a Msg the base handles\n// perfectly well; and `withDeadline`'s reserved-namespace scan silently missed\n// a `$deadline:`-prefixed base Msg that appeared only in a later row.\n//\n// The widening is pure: for any total table the returned array is identical\n// (same keys, same order). Cost goes from O(msgs) to O(states × msgs), paid\n// ONCE per wrapper construction — never inside the dispatch loop.\nexport function msgKeysOf(machine: {\n update: object;\n __form?: UpdateForm;\n}): readonly string[] {\n const keys = Object.keys(machine.update);\n if (keys.length === 0) return [];\n if (formOf(machine) === \"reducer\") return keys;\n const table = machine.update as Record<string, object | undefined>;\n const seen = new Set<string>();\n const union: string[] = [];\n for (const stateKey of keys) {\n const row = table[stateKey];\n if (row === null || row === undefined) continue;\n for (const msgKey of Object.keys(row)) {\n if (seen.has(msgKey)) continue;\n seen.add(msgKey);\n union.push(msgKey);\n }\n }\n return union;\n}\n\n// === describeMachine / acceptsOf: the per-state accept-sets, as a reading ===\n//\n// \"Which Msgs does this machine accept, and in which state?\" — the question a\n// tool asks when it drives a machine ITSELF instead of through `run`: a CLI\n// rendering the legal next moves, a doc generator, a log validator. Before\n// this the only answer was to cast `machine.update as Record<string,\n// Record<string, unknown>>` at the call site and hand-branch the form — one\n// private copy of the form-branching per consumer, drifting from the kernel's.\n//\n// This is a DERIVED READING over the table, deliberately NOT a property on the\n// machine. It has to be: every `withX` wrapper builds a fresh flat\n// `Record<string, Cell>`, casts it to `Reducer`, and returns a NEW object\n// literal carrying `init`/`update`/`subscriptions`/`subscribe`/`interpret`\n// plus the base's `cmds` — the one property a wrapper forwards on purpose,\n// because `run`'s interpret edge reads it (#66). Any OTHER property hung on a\n// machine is destroyed by the first wrap, and the wrapped table is\n// reducer-form regardless of the base's. A function over `(update, formOf)`\n// survives wrapping and tells the truth about the machine it is actually\n// handed.\n//\n// The return type is a DISCRIMINATED union on `form` because the two forms\n// genuinely answer different questions, and faking the missing one would be a\n// lie the type system would then propagate:\n// - `transitions` — carries `states` and `accepts` (state.type → Msg.types).\n// - `reducer` — has NO per-state accept-sets AT ALL. Its dispatch does\n// not consult the state, so `msgs` is the whole answer and there is no\n// `accepts` field to read. Reaching for one is a compile error, not an\n// empty object.\nexport type MachineShape =\n | {\n readonly form: \"reducer\";\n /** Every `Msg.type` the flat reducer has a cell for. */\n readonly msgs: readonly string[];\n }\n | {\n readonly form: \"transitions\";\n /** The union of every row's `Msg.type` keys (see `msgKeysOf`). */\n readonly msgs: readonly string[];\n /** Every `state.type` the table has a row for, in table order. */\n readonly states: readonly string[];\n /** `state.type` → the `Msg.type`s that state has a cell for. */\n readonly accepts: Readonly<Record<string, readonly string[]>>;\n };\n\nexport function describeMachine(machine: {\n update: object;\n __form?: UpdateForm;\n}): MachineShape {\n const msgs = msgKeysOf(machine);\n if (formOf(machine) === \"reducer\") return { form: \"reducer\", msgs };\n const table = machine.update as Record<string, object | undefined>;\n const states = Object.keys(table);\n const accepts: Record<string, readonly string[]> = {};\n for (const stateKey of states) {\n const row = table[stateKey];\n accepts[stateKey] =\n row === null || row === undefined ? [] : Object.keys(row);\n }\n return { form: \"transitions\", msgs, states, accepts };\n}\n\n// The one-state shorthand over `describeMachine`. Reducer-form is not a\n// special case being papered over: a flat reducer's dispatch never reads the\n// state, so EVERY state accepts the full Msg set and returning it is the true\n// answer, not a stand-in. A `stateType` with no row in a Transitions table\n// accepts nothing, so `[]` — equally true.\nexport function acceptsOf(\n machine: { update: object; __form?: UpdateForm },\n stateType: string,\n): readonly string[] {\n const shape = describeMachine(machine);\n if (shape.form === \"reducer\") return shape.msgs;\n return shape.accepts[stateType] ?? [];\n}\n\n// === Reducer<S, M, C>: record-of-handlers form of `update` ===\n//\n// Flat dispatch table keyed by `Msg.type`. Each cell is a pure transition for\n// a single Msg variant, narrowed via `Extract<M, { type: K }>`. The mapped type\n// is *load-bearing*: adding a Msg variant without a matching key in the\n// Reducer record is a compile error — no `absurd()` helper at call sites, no\n// silent fall-through, no default branch hiding impurity.\n//\n// Strengthens invariant 2 (pure transitions — the record form has no\n// fall-through default to hide impurity behind) and invariant 7 (identity is\n// explicit — the Msg variant set is load-bearing at the type level).\n//\n// `defineMachine` accepts the Reducer record form via overload. The runtime\n// dispatches via `update[msg.type](state, msg)`.\nexport type Reducer<S, M extends { type: string }, C extends Cmd> = {\n [K in M[\"type\"]]: (\n state: S,\n msg: Extract<M, { type: K }>,\n // `SyncReturn<S, C>` (not `readonly [S, readonly C[]]`) is the reentrancy\n // guard: a non-thenable return type, so an `async`/inline-`await`ing cell —\n // which returns `Promise<...>` — fails to compile at the cell. See the\n // `SyncReturn` doc above.\n ) => SyncReturn<S, C>;\n};\n\n// === Transitions<S, M, C>: table form of `update` for state-machine-shaped machines ===\n//\n// When `State` is itself a discriminated union (`State.type` is the active\n// phase), the table form keys every cell by (state.type × msg.type). Each cell\n// receives the narrowed `State` for its phase and the narrowed `Msg` for its\n// variant via two `Extract` lookups. Phantom-narrow at the type level; pure\n// data at runtime.\n//\n// The ROW is required and the CELL is optional, and that asymmetry is the whole\n// declaration (#203). A state must appear — adding a phase to `S` is a\n// compile-time obligation to say what it does, and a state that accepts nothing\n// writes the empty row `{}` rather than being silently absent. A cell is\n// optional because a MISSING cell is a declared refusal, not an omission: it\n// says this state does not accept that message, exactly as a statechart's `on`\n// lists the events a state handles and XState treats an unlisted event as no\n// transition. What tea does differently is stay loud (ADR 0011) — `lookupCell`\n// misses, and the dispatch raises `NoCellError` naming `acceptedTypes`, or\n// `tryApplyCell` returns it as data. Nothing is silently absorbed.\n//\n// Required cells made every phase check an `if (msg.phase !== …) return [s, []]`\n// inside a cell that had to exist, which both cost a 6×9 machine 54 cells and\n// made `acceptedTypes` report every message type for every state — truthfully,\n// and uselessly, for anything asking which buttons to light.\n//\n// `defineMachine` accepts a third `update` form for `Transitions<S, M, C>` —\n// the runtime dispatches via `update[state.type]?.[msg.type]`.\n//\n// Authors who want the old floor back take it per machine with\n// `ExhaustiveTransitions<S, M, C>` below; it is opt-in, never the default.\n//\n// Strengthens invariant 2 (table form has no fall-through default — an absent\n// cell refuses, it does not fall through), invariant 6 (runtime walks the table\n// predictably, no hidden dispatch fallback), and invariant 7 (both state.type\n// and msg.type are load-bearing at the type level).\n/**\n * The state × message table form of `update`. Every state of `S` needs a row;\n * a cell inside a row is optional, and leaving one out DECLARES that the state\n * does not accept that message — the runtime refuses it with `NoCellError`\n * naming `acceptedTypes`. `ExhaustiveTransitions` requires every cell instead.\n */\nexport type Transitions<\n S extends { type: string },\n M extends { type: string },\n C extends Cmd,\n> = {\n [P in S[\"type\"]]: Partial<ExhaustiveTransitions<S, M, C>[P]>;\n};\n\n// === ExhaustiveTransitions: the opt-in \"every cell must exist\" floor ===\n//\n// The same table with every cell REQUIRED — what `Transitions` was before\n// optional cells landed (#203). It is one definition, not a second copy:\n// `Transitions` is this type with each row made `Partial`, so the cell\n// signature can never drift between the two.\n//\n// Reach for it when a machine genuinely wants the compiler to force a decision\n// per (state, message) pair — a protocol where every pair is meaningful, or a\n// table under review. The cost is the one that made it a bad default: every\n// refusal has to be spelled as a cell that returns `[state, []]`, and every\n// state then reports every message type from `acceptedTypes`.\n//\n// Use it as an annotation on the table, then hand the table to `defineMachine`:\n//\n// const update: ExhaustiveTransitions<State, Msg, Cmds> = { … };\n// export const machine = defineMachine({ init, update, interpret });\n//\n// `satisfies` works the same way and keeps the literal's own type.\n/**\n * `Transitions<S, M, C>` with every cell REQUIRED — the opt-in floor for a\n * machine that wants the compiler to force a decision on every (state,\n * message) pair. An annotation on your own table, not a third update form:\n * `defineMachine` takes the annotated table unchanged.\n */\nexport type ExhaustiveTransitions<\n S extends { type: string },\n M extends { type: string },\n C extends Cmd,\n> = {\n [P in S[\"type\"]]: {\n [K in M[\"type\"]]: (\n state: Extract<S, { type: P }>,\n msg: Extract<M, { type: K }>,\n // Same reentrancy guard as `Reducer`: a transition cell that returns a\n // Promise (async / inline-await) is the suspended-blocking turn the canon\n // forbids, so its return is the non-thenable `SyncReturn<S, C>`.\n ) => SyncReturn<S, C>;\n };\n};\n\n// === Cmd: namespace for conditional Cmd emission ===\n//\n// Two recurring frictions in reducer cells:\n//\n// 1. \"Emit cmd X only when condition Y holds.\"\n// Hand-rolled: `cond ? [{ type: \"x\", ... }] : []`\n// With Cmd: `Cmd.when(cond, { type: \"x\", ... })`\n//\n// 2. \"Emit cmd X carrying a value that may be undefined; if undefined,\n// emit nothing.\"\n// Hand-rolled: `value !== undefined ? [{ type: \"x\", value }] : []`\n// With Cmd: `Cmd.whenDefined(value, (v) => ({ type: \"x\", value: v }))`\n//\n// Both forms return `readonly C[]` so they spread cleanly into the cmds\n// array returned by a Transitions cell:\n//\n// return [next, [\n// ...Cmd.when(state.tabId !== undefined, { type: \"detach_debugger\", tabId: state.tabId }),\n// ...Cmd.whenDefined(state.queueItemId, (id) => ({\n// type: \"queue:complete\", queueItemId: id, status: \"done\",\n// })),\n// ]];\n//\n// `Cmd` as a value namespace coexists with `Cmd<T>` as a type — TypeScript's\n// declaration merging puts them in different name spaces (type vs. value).\n// The reader sees `Cmd<...>` in type position and `Cmd.when(...)` in\n// expression position; no ambiguity at use sites.\n//\n// Why a namespace and not top-level `when` / `whenDefined`: `when` at module\n// scope reads as a generic conditional, but these helpers are specifically\n// for *Cmd emission* (return `readonly C[]`, the cmds-array contract of\n// every Transitions cell). The namespace pins that intent at the call site.\nexport const Cmd = {\n /**\n * Declare a typed Cmd constructor (ADR 0014). Returns the builder —\n * `fetch({ url })` yields `{ type: \"fetch\", url }` — carrying the minted Msg\n * builders `fetch.ok(cmd, value)` / `fetch.err(cmd, error)` and the\n * declaration the runtime edge parses against. `Settled<typeof fetch>` is\n * the two-arm Msg union it settles with; `defineMachine({ cmds: [fetch] })`\n * folds that union into the machine's `M`.\n *\n * const fetch = Cmd.define(\"fetch\", {\n * input: z.object({ url: z.string() }),\n * ok: z.object({ status: z.number(), body: z.string() }),\n * err: [\"not_found\", \"timeout\"],\n * requirements: Cmd.requirements<{ http: Http }>(),\n * });\n *\n * `err` is the `_tag` list the handler may settle with; the runtime adds\n * `malformed_result` for an `_ok` value the `ok` schema rejects. `requirements`\n * names the `Ctx` slice the handler reads — `run` refuses a ctx without it.\n *\n * A Cmd must not wait; see `DepKeyedSub` for anything that watches.\n */\n define: defineCmd,\n\n /**\n * Name a Cmd's `R` — the `Ctx` slice its handler reads. A phantom: nothing\n * is built, nothing is checked at runtime; the type is what `run` reads.\n */\n requirements: <R>(): Requirements<R> => ({}),\n\n /**\n * The empty Cmd array. Typed `readonly never[]` so it's assignable to any\n * `readonly C[]` for any `C extends Cmd`. Use in `init` returns and\n * Transitions cells that emit zero effects:\n *\n * init: (loaded) => [loaded ?? initial, Cmd.none],\n * tick: (state) => [state, Cmd.none],\n *\n * Elm's `Cmd.none` analogue. Cultural signal alongside the runtime help:\n * `[state, Cmd.none]` reads as intent (\"this transition emits nothing\"),\n * `[state, []]` reads as \"empty array of what\".\n *\n * Frozen at runtime so a downstream consumer can't `.push()` into the\n * shared reference.\n */\n none: Object.freeze([]) as readonly never[],\n\n /**\n * Flat concat of cmd arrays. Use when a cell composes effects from\n * multiple conditional sources:\n *\n * return [next, Cmd.batch(\n * Cmd.whenDefined(state.queueItemId, (id) => ({ type: \"complete\", id })),\n * Cmd.when(state.windowId !== undefined, { type: \"close_window\", windowId }),\n * [{ type: \"detach_debugger\", tabId: state.tabId }],\n * )];\n *\n * `<const C>` keeps inline cmd literals' discriminants narrow (same\n * rationale as `when` / `whenDefined` above).\n */\n batch: <const C extends Cmd>(\n ...arrs: readonly (readonly C[])[]\n ): readonly C[] => {\n const out: C[] = [];\n for (const arr of arrs) out.push(...arr);\n return out;\n },\n\n /**\n * Emit `cmd` wrapped in a single-element array iff `cond` is true.\n * Otherwise return the empty array. Spreads cleanly into the cmds array\n * returned by a Transitions cell.\n *\n * `const C` (TypeScript 5.0+) keeps the inferred `type:` discriminator\n * literal narrow when called with an object literal — so `Cmd.when(b,\n * { type: \"x\", ... })` infers as `{ type: \"x\", ... }`, not `{ type:\n * string, ... }`, and stays assignable to a discriminated-union arm\n * without `as const` at the call site.\n */\n when: <const C extends Cmd>(cond: boolean, cmd: C): readonly C[] =>\n cond ? [cmd] : [],\n\n /**\n * If `value` is defined, call `build(value)` and emit the resulting cmd\n * wrapped in a single-element array. If `value` is `undefined`, return\n * the empty array. `value` is narrowed to `T` inside `build`.\n *\n * `const C` on the return type keeps the callback's object-literal\n * `type:` field narrow (see `when` above for the full rationale).\n */\n whenDefined: <T, const C extends Cmd>(\n value: T | undefined,\n build: (value: T) => C,\n ): readonly C[] => (value !== undefined ? [build(value)] : []),\n} as const;\n\n// === SubId: branded string for Sub identity ===\n//\n// Subs are reconciled by id on every transition (canon §2.5, invariant 7).\n// Before branding, `Sub.id` was a raw `string` — a typo at one call site and a\n// different typo at another would silently produce two distinct subs that\n// looked identical to a human reader. The brand makes id construction explicit\n// (`subId(\"...\")`) and catches accidental string-where-SubId at the type\n// level.\n//\n// The brand is structural: `string & { __brand: \"SubId\" }`. The `subId(s)`\n// constructor is the ONE permitted cast in the substrate — every other call\n// site must go through it.\nexport type SubId = string & { readonly __brand: \"SubId\" };\n\n/**\n * Construct a `SubId` from a string. Use this everywhere a Sub literal is\n * built — including ids derived from runtime data (`subId(\\`ws:${auditId}\\`)`).\n * The brand is structural, not nominal, so dynamic ids are permitted; the\n * constructor's job is to make the identity decision explicit at every call\n * site so the type system can catch accidental raw-string drift.\n *\n * Strengthens invariant 7 (identity is explicit).\n */\nexport function subId(s: string): SubId {\n return s as SubId;\n}\n\n// === Sub: tagged-union, continuous source of msgs; stable id used for diff/reconcile ===\nexport type Sub<T extends string = string> = {\n readonly id: SubId;\n readonly type: T;\n};\n\n// === Dispose: the cleanup a dep-keyed Sub's source returns ===\n//\n// A `source` opens a resource and returns the function that closes it. The\n// substrate's reconcile calls it when the Sub's `deps` go null (torn down) or\n// change (re-armed: old `Dispose` then a fresh `source`). Same contract as the\n// `() => void` cleanup every `subscribe[type]` handler returns — named so a\n// dep-keyed Sub's `source` reads as \"open → returns close\".\nexport type Dispose = () => void | Promise<void>;\n\n// === depsInactive: the dep-keyed gate, defined ONCE ===\n//\n// \"This Sub has no slice in this state\" is one fact read by two places — the\n// runtime's `reconcileDepSubs` and `replay`'s desired-set projection — so it\n// gets one definition rather than a `deps === null` written twice.\n//\n// It reads NULLISH, not `null`. `(s) => s.runId` over an optional field is the\n// natural projection an author writes, and it yields `undefined` on the states\n// that mean \"inactive\"; a `=== null` gate armed the Sub there and hashed the\n// slice to the string `\"undefined\"` — one shared key under which a resource\n// was acquired for a state that had none. The typed alternative (`deps: (s) =>\n// {} | null`) would reject that projection at compile time, but it also rejects\n// every battery's `(state) => TKey | null` for an unconstrained `TKey`, so the\n// gate is widened instead of the type narrowed.\nexport function depsInactive(deps: unknown): boolean {\n return deps === null || deps === undefined;\n}\n\n// === structuralHash: deterministic, order-independent id from a deps value ===\n//\n// The id of a dep-keyed Sub (invariant 7 — identity is explicit) is DERIVED\n// from the slice of state the Sub depends on, never hand-authored. So adding a\n// field to `deps` changes the id exactly when that field changes, and a\n// churning id — the named #1 Sub bug (a Sub that remounts every tick, so its\n// timer never fires) — becomes impossible by construction: the author cannot\n// build the id wrong because the author does not build it.\n//\n// Determinism is load-bearing (invariant 2 — the reconcile pass runs inside\n// the pure-transition path's reconcile step; the same `deps` must always hash\n// to the same id). So: NO `Date`, NO random, NO insertion-order dependence.\n// Object keys are sorted so `{ runId, phase }` and `{ phase, runId }` hash\n// identically — the canonical \"name the slice → stable key\" adaptation FoldKit\n// makes for TS (its `modelToDependencies`), which Elm gets free from its\n// structural compare.\n//\n// The supported `deps` shape is plain JSON-compatible data (string / number /\n// boolean / null / array / plain object). A function, class instance, symbol,\n// or bigint in `deps` is a programming error — `deps` names a state SLICE, and\n// state is a value (invariant 1); such a value would also break the\n// determinism this hash promises. The walk throws on all of them to surface\n// that loudly rather than silently producing an unstable — or, worse, a\n// COLLIDING — id.\n//\n// The non-plain OBJECT case is the one that bites: `Object.keys` reports no own\n// enumerable property on a `Date`, `Map`, `Set`, `Error`, or a typical class\n// instance, so a walk that trusts it renders every one of them — and `{}` —\n// as `\"{}\"`. That is not an unstable id, it is ONE id for every value, which\n// defeats the identity filter (a foreign run's message compares equal), pins a\n// dep-keyed Sub to its first slice forever, and makes a battery's handle table\n// return the previous key's handle. The guard is therefore on the PROTOTYPE\n// (`Object.prototype` or `null`), not on a list of known classes: a\n// user-defined `RunKey` is refused by the same rule as `Date`, and no future\n// exotic builtin slips through.\n//\n// Rendering `Date`/`Map`/`Set` structurally was the alternative. It was\n// rejected: it buys a second rule to remember for a value the author can\n// project in one call (`startedAt.toISOString()`), and `Map`/`Set` iteration is\n// INSERTION-ordered, so any faithful rendering is order-sensitive — exactly the\n// churn this hash exists to prevent. One rule, stated once: plain data only.\n//\n// It is also the ONE \"turn this key value into a stable string\" primitive the\n// Sub factories in `src/subs/` address their interpret-local handle tables\n// with, so a battery's key rendering and the kernel's Sub identity can never\n// drift into two hashes for one fact.\nexport function structuralHash(deps: unknown): string {\n return stableStringify(deps);\n}\n\nfunction stableStringify(value: unknown): string {\n if (value === null) return \"null\";\n const t = typeof value;\n if (t === \"string\") return JSON.stringify(value);\n if (t === \"number\" || t === \"boolean\") return String(value);\n if (t === \"undefined\") return \"undefined\";\n if (t === \"function\") {\n throw new Error(\n \"@demlik/tea: structuralHash received a function in `deps`. \" +\n \"A dep-keyed Sub's `deps` must be a plain state slice (string / number / \" +\n \"boolean / null / array / object), not a closure — see invariant 1.\",\n );\n }\n if (Array.isArray(value)) {\n return `[${value.map(stableStringify).join(\",\")}]`;\n }\n if (t === \"object\") {\n // Plain-object gate. `Object.keys` is only a faithful reading of a value\n // whose prototype is `Object.prototype` (or `null` — a bag built with\n // `Object.create(null)` is plain by every measure that matters here).\n // Anything else keeps its data somewhere `Object.keys` cannot see, and\n // would render as `\"{}\"` — one id for every such value.\n const proto = Object.getPrototypeOf(value) as object | null;\n if (proto !== Object.prototype && proto !== null) {\n const ctor = (value as { constructor?: { name?: string } }).constructor;\n const label = ctor?.name ?? \"object\";\n throw new Error(\n `@demlik/tea: structuralHash received a non-plain object (${label}) in \\`deps\\`. ` +\n \"A `Date`, `Map`, `Set`, `Error` or class instance carries no own enumerable \" +\n \"properties, so every one of them would hash to the same id as `{}` — a silent \" +\n \"collision, not a wrong-looking key. Project it to plain data first \" +\n \"(e.g. `startedAt.toISOString()`, `[...set].sort()`) — see invariant 1.\",\n );\n }\n const obj = value as Record<string, unknown>;\n const keys = Object.keys(obj).sort();\n return `{${keys.map((k) => `${JSON.stringify(k)}:${stableStringify(obj[k])}`).join(\",\")}}`;\n }\n // bigint / symbol — not JSON-representable; same class of error as function.\n throw new Error(\n `@demlik/tea: structuralHash received an unsupported \\`deps\\` value of type \"${t}\". ` +\n \"Use plain JSON-compatible data for a dep-keyed Sub's `deps`.\",\n );\n}\n\n// === DepKeyedSub<S, M, Ctx>: a Sub whose identity AND gate fall out of `deps` ===\n//\n// The author declares the slice of state the Sub depends on (`deps`) and how\n// to open the resource for that slice (`source`). The substrate derives BOTH:\n//\n// - the **id** = `structuralHash(deps(state))` — changes exactly when the\n// slice changes (re-arm), stable otherwise (no churn). The author never\n// writes `subId(...)` — the hand-written subId was the drift away from\n// Elm's structural identity, which this restores.\n// - the **gate** = `deps(state)` returning `null` ⇒ inactive in this state\n// (dispose if running); non-null ⇒ active. The substrate folds every\n// `DepKeyedSub` into its own active set, so the author deletes the central\n// `subscriptions(state)` aggregate — there is no list to forget to edit\n// when a new phase is added (a per-Sub gate travels with the Sub).\n//\n// This is the FoldKit `modelToDependencies` shape: a Sub names the state slice\n// it depends on, the kernel keys on that slice. The manual `subscriptions?:`\n// field stays as the documented escape hatch (see `Machine`).\n//\n// `source` returns a `Dispose`. On a `deps` change the substrate runs the old\n// `Dispose` then re-runs `source` with the new deps (re-arm); on `deps` going\n// null it runs `Dispose` (teardown). The same reconcile machinery the manual\n// `Sub` path uses (`reconcileSubs` in `../run.ts`) — no second loop.\n//\n// Strengthens invariant 4 (external lifecycle owned by the substrate — the\n// dep-keyed Sub is reconciled, never hand-driven) and invariant 7 (identity is\n// explicit — derived deterministically from `deps`, never an ad-hoc string).\nexport interface DepKeyedSub<S, M, Ctx = unknown> {\n /**\n * The slice of state this Sub depends on. `null` OR `undefined` ⇒ the Sub is\n * inactive in this state (the substrate disposes it if it was running) — see\n * `depsInactive`, so `(s) => s.optionalRunId` gates correctly. Otherwise the\n * Sub is active, keyed on `structuralHash(deps)`.\n *\n * Pure (invariant 2). Plain JSON-compatible data only (invariant 1) — the\n * structural hash walks it deterministically and THROWS on a `Date`, `Map`,\n * `Set`, `Error` or class instance rather than collapsing them all onto one\n * id. Project such a value first (`startedAt.toISOString()`).\n */\n readonly deps: (state: S) => unknown;\n /**\n * Open the resource for the current `state` (whose `deps` the kernel just\n * found non-null). Receives `dispatch` to fire follow-up Msgs (a timer's\n * fire, an inbound frame) and the machine's `ctx` (the host's transport\n * factory, storage handles). Returns the `Dispose` the substrate runs on\n * teardown / re-arm. Same role as a `subscribe[type]` handler's returned\n * cleanup.\n *\n * `source` takes `state` (not the deps slice) so the slice type `D` never\n * escapes the entry — each battery's `.depKeyed` closes over its own typed\n * deps internally (cast-free existential: the entry that produced the deps\n * is the entry that consumes them).\n */\n readonly source: (state: S, dispatch: (msg: M) => void, ctx: Ctx) => Dispose;\n}\n\n// === Identity<S, M>: declare the instance's identity once; the kernel drops\n// mis-addressed messages before they reach `update` ===\n//\n// Without this: the substrate dispatches EVERY message to `update`, so an\n// author who needs \"this message is for THIS run\" must repeat\n// `if (msg.runId !== state.runId) return [state, []]` in every reducer cell.\n// Forget one cell and a stale or foreign run's message is applied → silent\n// corruption. That per-cell check is a rung-4 runtime stand-in for invariant 7\n// (identity is explicit): the identity invariant the host already holds (one\n// instance per run — `idFromName(runId)`) is re-asserted, cell by cell, where\n// it can be forgotten.\n//\n// `Identity<S, M>` lifts that to ONE declaration the kernel enforces. The\n// machine names two projections:\n//\n// - `ofState(state)` → the identity THIS instance owns, derived from state.\n// - `ofMsg(msg)` → the identity a message is ADDRESSED to, or\n// `undefined` when the message carries no identity\n// (lifecycle messages like `boot`, or `start_audit`\n// before the run exists — those are never dropped).\n//\n// Per transition the kernel compares `ofMsg(msg)` to `ofState(state)` by\n// `structuralHash` (so the identity can be any plain value, same machinery the\n// dep-keyed Sub id uses). A message addressed to a DIFFERENT identity is\n// dropped BEFORE `update` runs — the reducer never sees it, so no cell needs a\n// guard. A message with `ofMsg === undefined` is identity-agnostic and always\n// reaches `update`.\n//\n// Two projections rather than a single `(state) => state.runId`: the kernel\n// needs BOTH the state's identity AND the message's to compare, and splitting\n// them keeps the comparison `K`-to-`K` with no `as` cast (a message union\n// carries its identity field on only SOME arms — `ofMsg` narrows per arm in\n// author-land, returning `undefined` on the arms that have none, instead of\n// the substrate reaching into `msg.runId` it cannot type).\n//\n// Opt-in (escape hatch): a machine that declares no `identity` skips the filter\n// entirely — every message reaches `update`, exactly as before.\n//\n// Strengthens invariant 7 (identity is explicit — declared once, derived\n// deterministically, kernel-enforced rather than re-checked per cell) and\n// invariant 6 (the runtime is small and inspectable — a mis-addressed message\n// is dropped at ONE observable point, not silently mishandled in N cells).\nexport interface Identity<S, M> {\n /** The identity THIS instance owns. Pure (invariant 2); plain value. */\n readonly ofState: (state: S) => unknown;\n /**\n * The identity a message is addressed to, or `undefined` when the message\n * carries no identity (lifecycle / pre-identity messages — never dropped).\n * Pure (invariant 2); plain value when defined.\n */\n readonly ofMsg: (msg: M) => unknown;\n}\n\n// === Port<T>: typed escape hatch for \"data leaving the runtime\" ===\n//\n// A Port is a named, typed channel that Cmd handlers can `emit` to via the\n// augmented `ctx.emit(port, value)`. Subscribers attach via\n// `runtime.subscribePort(port, listener)` and receive every emitted value\n// synchronously (same fanout discipline as `runtime.observe`).\n//\n// Why Ports are a substrate primitive, distinct from State and Observe:\n// - **State** is \"the world as the program sees it.\" Folding outgoing\n// announcements into State turns ephemeral signals into persisted facts —\n// the classic anti-pattern that motivated this primitive.\n// - **Observe** sees every transition `(msg, state)`. That's the right channel\n// for devtools and logging, but it forces every consumer to filter the\n// entire firehose for a single signal.\n// - **Ports** are typed and selective: one channel per concept, subscribers\n// only see what the handler chose to emit. Mirrors Elm's outgoing-port\n// semantics — a typed declaration with `port` keyword whose values flow\n// out of the program to the host.\n//\n// Port identity is **by reference** — the returned object IS the identity.\n// Name is metadata for debugging. To prevent the \"two modules definePort the\n// same name expecting to share a channel, silently get distinct ports\" class\n// of bug, `definePort` asserts the name has not been seen in this process —\n// the symmetric runtime check to `SubId` (canon §2.12, invariant 7). Each\n// definePort call must use a unique name; if two modules need the same port,\n// one module exports it and the other imports it.\nexport interface Port<T> {\n readonly __brand: \"port\";\n readonly name: string;\n // Phantom field — never assigned, never read at runtime. Carries `T` for\n // inference at `ctx.emit` and `subscribePort` call sites. Using `?` so\n // `definePort` can produce a Port without constructing a value of `T`.\n readonly __t?: T;\n}\n\n/**\n * Augmentation injected onto `ctx` inside Cmd handlers. Handlers receive\n * `ctx & PortEmitter` so they can call `ctx.emit(port, value)` synchronously.\n * Subscribers registered via `runtime.subscribePort(port, listener)` receive\n * the value immediately.\n *\n * Emitting to a port with no subscribers is a no-op (does not throw).\n */\nexport interface PortEmitter {\n emit<T>(port: Port<T>, value: T): void;\n}\n\n// === NoCtx: the context-free marker ===\n//\n// A handler, Sub, or machine that reads NOTHING from `ctx` says so by using\n// `NoCtx` for its Ctx slot. This is the DELIBERATE absence of context — not\n// the accidental `unknown` looseness that erodes a boundary (see issue #64).\n//\n// `unknown` at a Ctx seam is ambiguous: it can mean \"I intentionally need no\n// context\" OR \"I gave up tightening this type.\" `NoCtx` resolves that\n// ambiguity at the type level. A reader (and the next agent) sees `NoCtx` and\n// knows the context-free-ness is a choice the author made, not a hole.\n//\n// Shape: an empty readonly record. A `Ctx & PortEmitter` is-a `NoCtx`, so a\n// context-free handler still composes at a richer call site. It carries no\n// own fields, so the name's claim (\"reads nothing from ctx\") is what callers\n// read at the seam.\n//\n// Strengthens invariant 6 (no silent looseness — a context-free seam is named,\n// not inferred) and invariant 8 (the boundary is legible; `unknown` stays\n// reserved for genuine wire-edge erasure, not for \"didn't bother\").\nexport type NoCtx = Readonly<Record<never, never>>;\n\n// === Interpret<M, C, Ctx>: record-of-handlers form of `interpret` ===\n//\n// Flat dispatch table keyed by `Cmd.type`. Each cell receives the narrowed Cmd\n// and the runtime-augmented Ctx (`Ctx & PortEmitter`) and resolves to a\n// follow-up Msg or `void` (fire-and-forget). The mapped type makes a missing\n// handler a compile error — `defineMachine` cannot accept the dictionary until\n// every Cmd variant has one.\n//\n// **The injected `dispatch` — the typed Cmd→Msg edge.** A leaf handler that\n// resolves on its own returns its follow-up Msg (`Promise<M | void>`) and\n// IGNORES the third argument. A DETACHED handler (one that hands long-running\n// work to `ctx.waitUntil` and CANNOT return its terminal Msg inline — awaiting\n// it would deadlock the serial dispatch tail) fires its terminal Msg through\n// this injected `dispatch` instead. Today such a handler reaches for a\n// host-wired `ctx.dispatch` typed to the FULL Msg union — so a typo'd or wrong\n// terminal Msg from a detached site compiles silently (rung 5: the allowed set\n// lives only in a comment). `wrapDetached<C, Allowed>` (in `../runtime-types`)\n// narrows THIS injected `dispatch` to the Cmd's declared result-Msg set, so a\n// wrong terminal Msg fails to compile (rung 2).\n//\n// Additive: the third arg is OPTIONAL (`dispatch?: (msg: M) => void`), so a\n// handler declaring only `(cmd, ctx)` stays assignable, and a unit test that\n// invokes a handler directly with two args still typechecks. The kernel ALWAYS\n// passes the dispatch (see `runInterpret` in `../run.ts`); the optionality is\n// purely a backward-compatibility affordance on the TYPE, not a runtime \"maybe\n// absent\". A handler authored via `wrapDetached` receives a NARROWER view of\n// this dispatch (only its declared result-Msg set).\n//\n// Hoisted out of `Machine.interpret` so consumers can type a free-standing\n// handler dictionary with `Interpret<MyMsg, MyCmd, MyCtx>` instead of\n// re-declaring the mapped type at every effects module.\n//\n// **The `R` channel lands here.** A cell's `ctx` is the machine's `Ctx`\n// intersected with ITS Cmd's `RequirementsOf` — so a `Cmd.define`d effect's handler\n// reads `ctx.http` typed, while `run` (via `RequiredCtx`) is what guarantees\n// the slice was actually supplied. An untyped Cmd's `RequirementsOf` is `unknown`,\n// so every hand-written handler's `ctx` is exactly what it was.\n//\n// Strengthens invariant 2 (the record form has no fall-through default to\n// hide impurity behind) and invariant 7 (identity is explicit — the Cmd\n// variant set is load-bearing at the type level).\nexport type Interpret<M extends { type: string }, C extends Cmd, Ctx> = {\n [K in C[\"type\"]]: (\n cmd: Extract<C, { type: K }>,\n ctx: Ctx & RequirementsOf<Extract<C, { type: K }>> & PortEmitter,\n dispatch?: (msg: M) => void,\n // biome-ignore lint/suspicious/noConfusingVoidType: an interpret handler returns a follow-up Msg or nothing; `void` permits no-return bodies that `M | undefined` would reject\n ) => Promise<M | void>;\n};\n\n// === InterpretDetached<C, Allowed, Ctx>: a detached interpret handler ===\n//\n// A handler that detaches long-running work (`ctx.waitUntil(...)`) and therefore\n// CANNOT return its terminal Msg inline (awaiting it would deadlock the serial\n// dispatch tail). It returns `Promise<void>` and fires its terminal Msg through\n// the kernel-injected `dispatch`, which is NARROWED to `Allowed` — the subset\n// of the Msg union this Cmd is permitted to produce. A wrong / typo'd terminal\n// Msg then fails to compile.\n//\n// `Allowed extends { type: string }` is the declared result-Msg set (e.g.\n// `GraphFinished | GraphFailed`). `dispatch: (msg: Allowed) => void` is the\n// narrowed edge. The handler still receives `ctx` (carrying `waitUntil`).\n//\n// Authored via `wrapDetached` (in `../runtime-types`), which adapts this shape\n// back into a plain `Interpret` cell so it drops into the existing `interpret`\n// dictionary with no kernel change at the call site.\nexport type InterpretDetached<\n C extends Cmd,\n Allowed extends { type: string },\n Ctx,\n> = (\n cmd: C,\n ctx: Ctx & PortEmitter,\n dispatch: (msg: Allowed) => void,\n) => Promise<void>;\n\n// === Subscribe<M, U, Ctx>: record-of-handlers form of `subscribe` ===\n//\n// Flat dispatch table keyed by `Sub.type`. Each cell receives the narrowed\n// Sub, the Ctx, and a `dispatch` to fire follow-up Msgs. Returns a cleanup\n// function the substrate calls when the Sub is reconciled out (state\n// transitioned away). The mapped type guarantees every Sub variant has a\n// handler at the type level; runtime dispatch is a single property lookup.\n//\n// The cleanup shares `Dispose`'s shape: a returned Promise is AWAITED by\n// `stop()` (bounded), so an async teardown a host relies on before evicting the\n// isolate actually completes. Mid-run reconcile does not await it — the\n// reconcile pass is synchronous by construction (invariant 2) — but the promise\n// is tracked from the moment it exists, so `stop()` catches it either way.\n//\n// Hoisted out of `Machine.subscribe` so consumers can type a free-standing\n// handler dictionary with `Subscribe<MyMsg, MySub, MyCtx>` instead of\n// re-declaring the mapped type at every subs module.\n//\n// Strengthens invariant 7 (identity is explicit — the Sub variant set is\n// load-bearing at the type level).\nexport type Subscribe<M extends { type: string }, U extends Sub, Ctx> = {\n [K in U[\"type\"]]: (\n sub: Extract<U, { type: K }>,\n ctx: Ctx,\n dispatch: (msg: M) => void,\n ) => Dispose;\n};\n\n// === Machine: pure data, host-agnostic ===\n//\n// `update` is stored as a union of the two record forms — the runtime branches\n// on shape at dispatch time. The public `defineMachine` overloads enforce one\n// shape per call so consumers never see the union themselves.\n//\n// - Reducer form: `Reducer<S, M, C>` — flat record keyed by Msg.type;\n// exhaustiveness enforced by the mapped type.\n// - Transitions form: `Transitions<S, M, C>` — 2D table keyed by\n// `state.type` then `msg.type`; only available when `S extends { type:\n// string }`. Conditional in the union so machines without a discriminated\n// State don't widen to include this branch.\n//\n// `M` is constrained to `{ type: string }` because both record forms require\n// a string discriminant.\n//\n// `interpret` is conditionally optional: when `C` is `Cmd<never>` the\n// interpret map is keyed by `never`, so the only valid value is `{}`. Forcing\n// every cmdless machine to write `interpret: {} as never` is ceremony for a\n// shape the type already pins. The tuple-wrap (`[C] extends [Cmd<never>]`)\n// disables distributive conditional so a real cmd union (e.g.\n// `Cmd<\"a\"> | Cmd<\"b\">`) doesn't degrade to optional just because one arm\n// happens to be `Cmd<never>`. Same trick the `update` field uses.\nexport type Machine<\n S,\n M extends { type: string },\n C extends Cmd,\n U extends Sub,\n Ctx,\n> = {\n /**\n * Boot the runtime. Called once by `run(...)` with whatever `Store.load()`\n * returned: `null` on fresh boot, the persisted state on rehydrate.\n *\n * **Contract:** when `loaded !== null`, init MUST return `[loaded, []]` —\n * no Cmds. Init's rehydrate branch is the migration / parse boundary, not\n * the boot-effect hook. See Invariant 2 in `.patterns/tea/tea-invariants.md`.\n *\n * Boot effects routes:\n * - Stateless infrastructure → host module top, outside TEA.\n * - State-conditional resume → a `boot` Msg the host dispatches once\n * after `run(...)` returns.\n *\n * Violations are caught at runtime by `replay` (which throws with a\n * pointer to the alternatives).\n */\n init: (loaded: S | null, ctx: Ctx) => readonly [S, readonly C[]];\n /**\n * The typed Cmd constructors this machine emits (`Cmd.define`). Declared\n * through `defineMachine({ cmds })`, which derives `C` and the settled half\n * of `M` from them; the runtime reads the list to parse each handler's\n * `_ok` value against its `ok` schema and stamp `at` at the interpret edge.\n * A machine of hand-written Cmds omits it and runs exactly as before.\n */\n readonly cmds?: readonly AnyCmdDef[];\n update:\n | Reducer<S, M, C>\n // Wrap in tuple to disable distributive conditional behavior. Without\n // `[S]`, TS distributes the conditional across `S`'s union members,\n // producing `Transitions<A,...> | Transitions<B,...>` instead of the\n // desired `Transitions<A|B,...>` — the table form needs a single\n // mapping over the full union of state types, not separate tables per\n // member.\n | ([S] extends [{ type: string }] ? Transitions<S, M, C> : never);\n /**\n * Dep-keyed Subs. Each declares the state slice it depends on; the substrate\n * derives the id (`structuralHash(deps)`) and the gate (`deps` non-null) and\n * folds them into the SAME reconcile loop `subscriptions` feeds. The author\n * never writes `subId(...)` and never lists Subs in a central\n * `subscriptions(state)` aggregate — a per-Sub gate travels with the Sub, so\n * a new phase can't silently forget to arm it.\n *\n * The deps slice type is erased to `unknown` per entry — each Sub's slice\n * differs, but the slice type never crosses this field (the kernel only needs\n * to hash it and pass `state` back to that same entry's `source`).\n *\n * Optional and independent of `subscriptions` / `subscribe`: a machine that\n * omits `subs` reconciles exactly as before.\n *\n * Strengthens invariant 4 (lifecycle owned by the substrate) and invariant 7\n * (identity derived, not hand-authored).\n */\n subs?: ReadonlyArray<DepKeyedSub<S, M, Ctx>>;\n /**\n * Instance-identity filter. Declares THIS instance's identity once; the\n * substrate drops any message addressed to a DIFFERENT identity before it\n * reaches `update`. Replaces the per-cell `if (msg.runId !== state.runId)`\n * guard entirely — the reducer never sees a foreign-instance message, so no\n * cell needs to check.\n *\n * Opt-in: a machine that omits `identity` skips the filter (every message\n * reaches `update`, exactly as before). A message whose `ofMsg` returns\n * `undefined` is identity-agnostic and always reaches `update` (lifecycle /\n * pre-identity messages).\n *\n * Strengthens invariant 7 (identity is explicit — declared once, enforced by\n * the substrate) and invariant 6 (mis-addressed messages dropped at one\n * observable point, not per cell).\n */\n identity?: Identity<S, M>;\n /**\n * Manual Sub aggregate — the documented escape hatch, KEPT alongside `subs`.\n * The machine that needs cross-Sub logic the per-Sub `deps` fold can't\n * express lists Subs here; the substrate reconciles them via `subscribe`.\n * Both paths feed ONE reconcile pass.\n */\n subscriptions?: (state: S) => readonly U[];\n subscribe?: Subscribe<M, U, Ctx>;\n /**\n * The update form (\"reducer\" | \"transitions\"), stamped non-enumerably by\n * `defineMachine` at construction (see `UpdateForm` / `formOf`). Optional in\n * the type so the structural `Machine` annotation form keeps accepting plain\n * object literals; readers go through `formOf`, which falls back to\n * `detectUpdateForm` when the tag is absent. Never written by hand.\n */\n readonly __form?: UpdateForm;\n} & ([C] extends [Cmd<never>]\n ? { interpret?: Interpret<M, C, Ctx> }\n : { interpret: Interpret<M, C, Ctx> }) &\n // `subscribe`/`subscriptions` are conditionally REQUIRED the same way\n // `interpret` is (#276): a machine declaring a real Sub union without a\n // subscribe map compiled and silently wired no subs (`reconcileSubs` skips\n // undefined handlers) — the exact silent-failure class the `interpret`\n // conditional prevents. The optional declarations above stay as U's\n // inference sites (a conditional type is not an inference site); this\n // intersection only adds requiredness when U is a real union. Same\n // tuple-wrap trick as `interpret` to disable distribution.\n ([U] extends [Sub<never>]\n ? unknown\n : {\n subscriptions: (state: S) => readonly U[];\n subscribe: Subscribe<M, U, Ctx>;\n });\n\n// === foldUpdates: the single internal fold `replay` and `foldMsgs` share ===\n//\n// Folds `machine.update` over `msgs` from `initialState`, dispatching each\n// Msg through `applyCell` — the same primitive `run` uses — so every fold site\n// agrees on the reducer-vs-transitions form by construction (no second copy of\n// the dispatch to drift). Returns the final state plus the Cmds the cells emitted\n// along the way; the caller keeps them (`replay`) or discards them (`foldMsgs`).\n//\n// Touches no `Store`, no `interpret` handler, and starts no subscription — it\n// only calls `update` cells. The two public folds differ only in how they\n// enter and what they return: `replay` enters via `init` and returns\n// `{ state, cmds, subs }`; `foldMsgs` enters from a base state and returns `S`.\nexport function foldUpdates<S, M extends { type: string }, C extends Cmd>(\n machine: { update: object; __form?: UpdateForm },\n initialState: S,\n msgs: readonly M[],\n): { state: S; cmds: C[] } {\n let state: S = initialState;\n const cmds: C[] = [];\n\n for (const msg of msgs) {\n const [next, emitted] = applyCellChecked<S, M, C>(machine, state, msg);\n state = next;\n cmds.push(...emitted);\n }\n\n return { state, cmds };\n}\n\n// === foldMsgs: runtime-free client-prediction fold seam (ADR 0006, #211) ===\n//\n// Folds `machine.update` over an ordered `Msg[]` starting from a caller-supplied\n// `base` state and returns the resulting state ONLY. This is the client-side\n// replay primitive a prediction loop needs (the Gambetta/Valve\n// authoritative-server reconcile step): re-simulate a queue of un-acked inputs\n// on top of an authoritative snapshot —\n// `foldMsgs(machine, snapshot, pendingInputs)`.\n//\n// Distinct from `replay` (the test idiom), by design (ADR 0006):\n// - Enters from a direct `base` parameter, NOT via `init`/`loaded` — so\n// reconciliation correctness never depends on the machine author's `init`\n// rehydrate discipline. Takes no `ctx` (the fold calls `update` only).\n// - Returns just the final `S` — not `{ state, cmds, subs }`. During prediction\n// the inputs' effects were already sent to the server; re-emitting their Cmds\n// on the client would double-fire, and `subs` are a runtime concern. Returning\n// only `S` makes \"replay fires no effects\" structural, not caller discipline.\n// A caller that wants the emitted Cmds for assertions uses `replay`.\n//\n// Invokes no `Store`, no `interpret` handler, and starts no subscription — it\n// shares `replay`'s `foldUpdates` fold, which only calls `update` cells, and\n// reads the reducer-vs-transitions form via the same `formOf(machine)` reader\n// `run`/`replay` use, so it agrees with them by construction.\n//\n// Per ADR 0006 the runtime-free *guarantee* lives in `src/pure/`, whose module\n// graph never reaches `run`; that barrel + the import-graph guard are #213's\n// scope. `foldMsgs` ships as a reachable public API from the root door, which\n// is where the whole runtime-free surface publishes since #51.\nexport function foldMsgs<\n S,\n M extends { type: string },\n C extends Cmd,\n U extends Sub,\n Ctx,\n>(machine: Machine<S, M, C, U, Ctx>, base: S, msgs: readonly M[]): S {\n return foldUpdates<S, M, C>(machine, base, msgs).state;\n}\n","/**\n * internal/prediction — the client-prediction ack primitive (epic #186, facet 2).\n * Internal since #49 — not published on any subpath of its own; the\n * client-safe barrel `src/pure/` re-exports the public surface, and the root\n * `@demlik/tea` door publishes it.\n *\n * The contract the Gambetta/Valve authoritative-server netcode loop needs:\n * **command-seq-in → last-applied-seq-out.** A client tags each predicted\n * command/`Msg` with a monotonic `seq`; the authoritative side replies with the\n * `lastAppliedSeq` it has processed. `partitionByAck` then splits the client's\n * pending buffer into the inputs the server has ACKED (`seq <= lastAppliedSeq`)\n * and those still PENDING (`seq > lastAppliedSeq`) — the un-acked tail the\n * reconciliation pass (#214) replays over the authoritative snapshot via\n * `foldMsgs` (#211, the client-safe barrel `src/pure/`).\n *\n * Deliberately **Model-shape-agnostic** (ADR 0006): the ack is a standalone\n * value, NOT a field this module requires on the consumer's `State`. It\n * generalizes the `lastAckedSeq`-on-the-Model + `seq`-threaded-through-the-Msg\n * pattern vortex hand-rolled (epic #186). It is a LEAF module — pure and\n * runtime-free, importing nothing from the tea core or host, so it can never\n * drag `run`/the host into a client bundle.\n *\n * This is the read/ack side of the primitive; `tagSeq`/`nextSeq` are the write\n * side, letting a client mint monotonic seqs from its pending buffer alone —\n * again with no counter field on the Model.\n *\n * `reconcile` (the read side's payoff, #214) composes this ack partition with\n * the pure fold seam `foldMsgs` to perform the whole Gambetta/Valve\n * reconciliation step in one call. The `foldMsgs` import is the ONLY dependency\n * this leaf takes, and it reaches into the pure-core leaf (`../pure/core`) — NOT\n * the runtime root — so the module stays runtime-free and the client-safe\n * import-graph guard (ADR 0006, #213) still holds.\n */\n\nimport type { Cmd, Machine, Sub } from \"../../pure/core\";\nimport { foldMsgs } from \"../../pure/core\";\n\n/**\n * A monotonic, non-negative sequence number tagging one client-predicted\n * command. Monotonicity is the client's contract (mint successive seqs with\n * `nextSeq`); this module only ever *compares* seqs.\n */\nexport type Seq = number;\n\n/** A command (or `Msg`) tagged with the `seq` the client assigned it. */\nexport interface SeqTagged<T> {\n readonly seq: Seq;\n readonly value: T;\n}\n\n/** Tag a command/`Msg` with its sequence number. */\nexport const tagSeq = <T>(seq: Seq, value: T): SeqTagged<T> => ({ seq, value });\n\n/**\n * The authoritative side's acknowledgement: the highest `seq` it has applied.\n * Everything with `seq <= lastAppliedSeq` is settled; everything above is still\n * in flight. This *is* the whole \"ack from the authoritative side\" — a value\n * the consumer carries however it likes (a wire field, a message payload),\n * never a shape this module imposes on the Model.\n */\nexport interface Ack {\n readonly lastAppliedSeq: Seq;\n}\n\n/** Construct an `Ack` for a last-applied sequence number. */\nexport const ack = (lastAppliedSeq: Seq): Ack => ({ lastAppliedSeq });\n\n/**\n * The \"nothing applied yet\" cursor — the ack value for a server that has applied\n * no client input at all. Because `nextSeq` mints **0-based** seqs and\n * `partitionByAck` acks **inclusively** (`seq <= lastAppliedSeq`), the pre-first\n * cursor must sit strictly *below* seq 0: `lastAppliedSeq = 0` would falsely ack\n * the seq-0 input before the server ever saw it. `-1` is \"before any seq\", and\n * `partitionByAck(buffer, NO_ACK)` therefore leaves the whole buffer PENDING.\n *\n * This names the boundary value on the seam so no consumer has to re-discover it\n * as a magic number: it is the primitive's own design (0-based mint + inclusive\n * partition) that creates the trap, so it is the primitive's job to name the\n * escape. Pair with {@link initAck} when an {@link Ack} is wanted instead of the\n * bare `Seq`.\n */\nexport const NO_ACK: Seq = -1;\n\n/**\n * The `Ack` for a server that has applied nothing yet — `ack(NO_ACK)`. The `Ack`\n * counterpart to the {@link NO_ACK} `Seq` sentinel, for a consumer that carries\n * an `Ack` rather than a bare `lastAppliedSeq`.\n */\nexport const initAck = (): Ack => ack(NO_ACK);\n\n/** The result of splitting a seq-tagged buffer against an ack. */\nexport interface AckPartition<T> {\n /** Inputs the authoritative side has applied (`seq <= lastAppliedSeq`). */\n readonly acked: readonly SeqTagged<T>[];\n /** Inputs still in flight / un-acked (`seq > lastAppliedSeq`) — the replay tail. */\n readonly pending: readonly SeqTagged<T>[];\n}\n\n/**\n * Partition a buffer of seq-tagged commands into ACKED and PENDING against the\n * authoritative `lastAppliedSeq`. Pure and total: every item lands in exactly\n * one bucket, input order is preserved within each bucket, and the boundary\n * `seq == lastAppliedSeq` is ACKED (inclusive `<=`). Routing is by `seq` value,\n * not buffer position, so an out-of-order or duplicate-seq buffer partitions\n * correctly. Accepts either an {@link Ack} or a bare `lastAppliedSeq` number, so\n * a caller passes whichever it holds.\n */\nexport const partitionByAck = <T>(\n buffer: readonly SeqTagged<T>[],\n ackOrSeq: Ack | Seq,\n): AckPartition<T> => {\n const lastAppliedSeq =\n typeof ackOrSeq === \"number\" ? ackOrSeq : ackOrSeq.lastAppliedSeq;\n const acked: SeqTagged<T>[] = [];\n const pending: SeqTagged<T>[] = [];\n for (const item of buffer) {\n if (item.seq <= lastAppliedSeq) {\n acked.push(item);\n } else {\n pending.push(item);\n }\n }\n return { acked, pending };\n};\n\n/**\n * The next sequence number to assign: one past the highest `seq` in the buffer,\n * or `0` for an empty buffer. Lets a client mint monotonic seqs from its pending\n * buffer alone — no counter field on the Model — and is tolerant of an unordered\n * buffer (it takes the max, not the last element).\n */\nexport const nextSeq = <T>(buffer: readonly SeqTagged<T>[]): Seq =>\n buffer.reduce((max, item) => (item.seq > max ? item.seq : max), -1) + 1;\n\n/**\n * The client prediction/reconciliation helper — the Gambetta/Valve\n * authoritative-server loop's reconcile step, generalized.\n *\n * Given the latest `authoritativeState` from the server, the server's\n * `lastAppliedSeq` ack, and the client's `pending` buffer of seq-tagged inputs,\n * it returns the corrected predicted state: drop the inputs the server has\n * already applied (`seq <= lastAppliedSeq`) and replay ONLY the un-acked tail\n * (`seq > lastAppliedSeq`) over the authoritative snapshot.\n *\n * It is **composed, not re-derived** (ADR 0006): the drop is {@link partitionByAck}\n * (the ack primitive, #212) and the replay is `foldMsgs` (the pure fold seam,\n * #211) — there is no second copy of the partition logic and no second copy of\n * the fold. `lastAppliedSeq` accepts either an {@link Ack} or a bare `Seq`, so a\n * caller passes whichever it holds, matching `partitionByAck`.\n *\n * Pure and host-agnostic: it takes the `machine` (which `foldMsgs` needs to\n * dispatch `update`) but touches no `Store`, `interpret`, or subscription, and\n * imports nothing from the runtime — so it ships through the client-safe\n * umbrella without dragging `run` into a client bundle.\n */\nexport function reconcile<\n S,\n M extends { type: string },\n C extends Cmd,\n U extends Sub,\n Ctx,\n>(\n machine: Machine<S, M, C, U, Ctx>,\n authoritativeState: S,\n lastAppliedSeq: Ack | Seq,\n pending: readonly SeqTagged<M>[],\n): S {\n const { pending: unacked } = partitionByAck(pending, lastAppliedSeq);\n return foldMsgs(\n machine,\n authoritativeState,\n unacked.map((tagged) => tagged.value),\n );\n}\n","/**\n * @demlik/tea runtime interface surface + pure helpers — the public types,\n * interfaces, and construction/composition helpers the runtime (`./run`)\n * implements against: `Store`, the error-sink and supervision contracts, the\n * `RuntimeRef` / `BootingRuntime` / `Runtime` handle hierarchy, `definePort`, the\n * identity-typed constructors `defineMachine` / `asReducer`, and the pure tools\n * `replay` (compose without running) and `tryInterpret` (Railway).\n */\n\nimport { Result } from \"better-result\";\nimport type { Provided } from \"./provide\";\nimport type {\n AnyCmdDef,\n CmdOf,\n ErrOf,\n InterpretDetached,\n Machine,\n OkOf,\n Port,\n PortEmitter,\n Reducer,\n RequirementsOf,\n Settled,\n Sub,\n Transitions,\n} from \"./pure/core\";\nimport {\n __DEV__,\n assertPureResult,\n type Cmd,\n deepFreeze,\n depsInactive,\n detectUpdateForm,\n foldUpdates,\n lookupCell,\n NoCellError,\n structuralHash,\n type UpdateForm,\n} from \"./pure/core\";\n\n// The nominal brand minted ONLY through the validated construction path\n// (`asReducer` / `defineMachine`). A raw record of handlers is a structural\n// `Reducer<S, M, C>`; a branded one has passed through the single minting\n// boundary. The brand is an *optional* phantom so the structural annotation form\n// (`const update: Reducer<...> = { ... }`) keeps accepting plain object literals\n// — the guard that rejects an async reducer is `SyncReturn`'s non-thenable\n// return, enforced on every cell.\ndeclare const ReducerBrand: unique symbol;\n\n// A `Reducer` (or `Transitions`) minted through `asReducer` / `defineMachine`.\n// Carries the phantom brand; otherwise identical to its structural counterpart.\nexport type Branded<T> = T & { readonly [ReducerBrand]: true };\n\n/**\n * Compile-time exhaustiveness assertion for default branches of switches over\n * discriminated unions narrowed by hand (Sub handlers, message-bridge\n * dispatchers, port fanouts) — TS narrows the operand to `never` only if every\n * variant is covered, so adding one produces a compile error at the `absurd(x)`\n * site. Strengthens invariant 7 (identity is explicit).\n *\n * @example\n * switch (msg.type) {\n * case \"a\": return ...;\n * case \"b\": return ...;\n * default: return absurd(msg); // compile error if a \"c\" is added\n * }\n */\nexport function absurd(x: never): never {\n throw new Error(`unreachable: ${JSON.stringify(x)}`);\n}\n\n// The explicit \"this cell ignores this msg\" helper. Naming the no-op forces the\n// author to *decide* \"this cell does nothing\" (a real decision), distinct from\n// \"I forgot to write this cell\" (which the mapped type rejects); an implicit\n// wildcard would silently swallow a future Msg variant that should be handled.\n// Assignable to any Transitions cell regardless of S/M/C concrete types.\nexport const noop = <S, M, C extends Cmd>(\n state: S,\n _msg: M,\n): readonly [S, readonly C[]] => [state, []];\n\n// Module-level registry — process-scope, identity-by-name. The runtime witness\n// that every port name in this process is unique. Cleared only by the test-only\n// `__resetPortRegistry()` helper.\nconst definedPortNames = new Set<string>();\n\n/**\n * Thrown by `definePort` when a name has already been registered in the current\n * process. Symmetric with `SubIdCollisionError` (thrown by `reconcileSubs`) —\n * both mechanize invariant 7 (identity is explicit) at the runtime layer the\n * type system cannot reach (string names compared at runtime).\n */\nexport class PortNameCollisionError extends Error {\n override readonly name = \"PortNameCollisionError\";\n readonly _tag = \"PortNameCollisionError\" as const;\n constructor(portName: string) {\n super(\n `definePort: a port named \"${portName}\" was already defined. ` +\n `Each definePort call must use a unique name. ` +\n `If two modules need the same port, export it from one module and import it.`,\n );\n }\n}\n\n/**\n * Thrown by `reconcileSubs` when, within ONE desired subscription set, two subs\n * share an `id` but declare different `type`s — a silent bug class the type\n * system cannot reach (ids are strings compared at runtime). The symmetric twin\n * of `PortNameCollisionError`: both mechanize invariant 7 (identity is explicit)\n * at the runtime layer. Same id across transitions is the no-churn case and does\n * NOT throw; only a within-set type conflict does.\n */\nexport class SubIdCollisionError extends Error {\n override readonly name = \"SubIdCollisionError\";\n readonly _tag = \"SubIdCollisionError\" as const;\n constructor(id: string, declaredType: string, conflictingType: string) {\n super(\n `@demlik/tea: Sub.id collision: id=\"${id}\" declared as ` +\n `type=\"${declaredType}\" and type=\"${conflictingType}\"`,\n );\n }\n}\n\n/**\n * Test-only escape hatch — clears the module-level port-name registry so the\n * collision assert in `definePort` doesn't false-positive across vitest's\n * non-isolated runs. Production code MUST NOT call this.\n *\n * @internal test-only\n */\nexport function __resetPortRegistry(): void {\n definedPortNames.clear();\n}\n\n/**\n * Which otherwise-unattributable runtime path produced an error. Every fanout is\n * throw-isolated so one bad consumer never strands its siblings, and the\n * isolated throw routes to the `OnError` sink rather than a bare `console.error`.\n *\n * - `\"follow-up\"` — a follow-up Msg an interpret handler returned rejected when\n * re-dispatched (the original dispatcher already resolved, so no caller).\n * A rejection caused by `stop()`'s own teardown is NOT this phase — see\n * `\"discard\"`.\n * - `\"stop-save\"` — the final `store.save(state)` inside `stop()` threw\n * (`stop()` resolves regardless, so without the sink this was silent loss).\n * - `\"reduce\"` — the pure `update` (reducer) threw synchronously; the configured\n * `Supervision` strategy decides what happens next, but the throw is surfaced\n * here as data first.\n * - `\"listener\"` — a `runtime.subscribe(...)` listener threw during fanout.\n * - `\"observer\"` — a `runtime.observe(...)` observer threw during fanout.\n * - `\"event\"` — the `events` projector or an `on(type, ...)` handler threw.\n * - `\"boot\"` — an `onBoot` handler threw (boot fanout, or a late registration).\n * - `\"port-emit\"` — a `subscribePort` listener threw during a port emission.\n * - `\"sub-cleanup\"` — a subscription's cleanup threw (reconcile-removal or\n * `stop()` teardown).\n * - `\"discard\"` — work lost to a teardown the host asked for. Two witnesses,\n * both carrying a `RuntimeDiscardNotice`: `stop()` was called while interpret\n * handlers were still awaiting (`RuntimeDiscardedError`), and a Msg that\n * arrived DURING `stop()`'s drain and so could not be delivered\n * (`DispatchDiscardedError`), and teardown work that did not settle inside\n * `disposeTimeoutMs` (`DisposeTimeoutNotice`). The one phase that is a\n * LIFECYCLE report rather than a failure: legal, merely lossy.\n * - `\"identity-drop\"` — the `Identity` filter dropped a message addressed to a\n * different instance (`IdentityDropNotice`). Its own phase rather than\n * `\"discard\"`: the loss is the FILTER WORKING, not a teardown, and a host\n * routing it (a metric, a 409 back to the caller) wants it apart from\n * unmount-time noise. Warn-only, like every `RuntimeDiscardNotice`.\n * - `\"provide\"` — a `provide({ … })` graph handed to `run` as `ctx`. Two\n * witnesses: an `acquire` failed at boot (a `ProvideFailedError`, ALSO the\n * rejection of `ready`, so this report is the copy a sink gets rather than the\n * only route out), and a `release` threw during `stop()`, which carries\n * `context.provider` and has no other route out at all — the run is over.\n *\n * The phase never decides fatality — the ERROR CLASS does (`RuntimeDiscardNotice`\n * warns, everything else rethrows). A phase is attached by the report site, so a\n * consumer sink that throws while handling a `\"discard\"` report inherits that\n * phase; keying the warn-only path on it would make the sink's own defect vanish.\n */\nexport type RuntimeErrorPhase =\n | \"follow-up\"\n | \"stop-save\"\n | \"reduce\"\n | \"listener\"\n | \"observer\"\n | \"event\"\n | \"boot\"\n | \"port-emit\"\n | \"sub-cleanup\"\n | \"discard\"\n | \"identity-drop\"\n | \"provide\";\n\n/** Context handed to an `OnError` sink alongside the error itself. */\nexport interface RuntimeErrorContext {\n readonly phase: RuntimeErrorPhase;\n /**\n * The provider key a `\"provide\"` report is about — set when a `release` threw\n * (the run is over; the throw has nowhere else to go). Absent on the acquire\n * report, which also rejects `ready` with a `ProvideFailedError` that names it.\n */\n readonly provider?: string;\n}\n\n/**\n * Sink for runtime failures that have no caller to reject at. Configured via\n * `run(machine, { onError })`. Should be total — a throw inside the sink is\n * itself surfaced via the default sink, so it can never re-introduce a silent\n * failure.\n */\nexport type OnError = (error: unknown, context: RuntimeErrorContext) => void;\n\n// === Supervision: declared policy for a reducer throw ===\n//\n// A throw inside the pure `update` is a synchronous throw (the reentrancy brand\n// makes a reducer provably synchronous), catchable in the dispatch loop — the\n// seam Akka supervisor strategies / Erlang-OTP supervision trees occupy: \"let it\n// crash\" becomes CONFIG. Every strategy routes the failure to `onError` with\n// `phase: \"reduce\"` FIRST (invariant 6), then differs in what happens next:\n//\n// - `stop` — halt (SAFE DEFAULT). State is NOT advanced; the dispatch\n// promise rejects; every subsequent dispatch rejects. Never a\n// silent resume.\n// - `escalate`— surface + propagate: the dispatch promise rejects so the\n// failure bubbles to a parent supervisor. The runtime stays live.\n// - `restart` — re-init from a host-provided last-known-good state and keep\n// folding. The core owns no snapshot logic — the host supplies\n// `rehydrate()`, the core installs its result and continues.\n\n/** The three declared reducer-throw supervision strategies. */\nexport type SupervisionStrategy = \"stop\" | \"escalate\" | \"restart\";\n\n/**\n * Declared supervision policy for a reducer (`update`) throw, at\n * `run(machine, { supervision })`. The bare-string shorthands (`\"stop\"` /\n * `\"escalate\"`) are accepted for the two strategies that need no host data;\n * `restart` MUST be the object form because it carries the `rehydrate` callback,\n * which MUST return a valid `S` synchronously (the reducer is synchronous, so\n * recovery is too — no suspension across the single-writer slot).\n */\nexport type Supervision<S, M extends { type: string }> =\n | \"stop\"\n | \"escalate\"\n | { readonly strategy: \"stop\" }\n | { readonly strategy: \"escalate\" }\n | {\n readonly strategy: \"restart\";\n /**\n * Host-provided rehydration to last-known-good state. Invoked when the\n * reducer throws; its return value becomes the new state and the transition\n * continues from there. Receives the pre-throw `state`, the `msg` that\n * triggered the throw, and the thrown `error` so the host can route by\n * cause.\n */\n readonly rehydrate: (state: S, msg: M, error: unknown) => S;\n };\n\n/**\n * Raised by `idle()` when the quiescence wait hits its iteration cap without the\n * dispatch tail stabilizing — `idle()` REJECTS rather than silently resolving,\n * so a livelocking machine surfaces instead of masquerading as quiescent.\n * Mechanizes invariant 6 at the runtime layer, the role `PortNameCollisionError`\n * plays for invariant 7.\n */\nexport class QuiescenceTimeoutError extends Error {\n override readonly name = \"QuiescenceTimeoutError\";\n readonly _tag = \"QuiescenceTimeoutError\" as const;\n constructor(public readonly iterations: number) {\n super(\n `@demlik/tea: idle() did not reach quiescence after ${iterations} ` +\n `iterations — the dispatch tail kept advancing. The machine is ` +\n `likely livelocking (an interpret handler enqueues a follow-up Msg ` +\n `that enqueues another, without end). Bound the follow-up chain in ` +\n `the reducer, or stop the runtime.`,\n );\n }\n}\n\n/**\n * Raised by `driveToDone` when the drive ends on a State its `failed` predicate\n * marks as a failure. Carries that final State so the caller reads the failure\n * off the Model the machine owns — never off a message string. A rejection, not\n * a resolve, so a failed run cannot be mistaken for a finished one at the\n * caller boundary (invariant 6).\n */\nexport class DriveFailedError<S> extends Error {\n override readonly name = \"DriveFailedError\";\n readonly _tag = \"DriveFailedError\" as const;\n constructor(public readonly state: S) {\n super(\n `@demlik/tea: driveToDone ended on a failed State — the run reached a ` +\n `terminal State the \\`failed\\` predicate marks as a failure. Read ` +\n `\\`error.state\\` for the final Model.`,\n );\n }\n}\n\n/**\n * Raised by `driveToDone` when `start`'s follow-up chain quiesces on a State\n * that is neither terminal nor `failed` AND nothing in the runtime can still\n * transition it — no live Sub (manual or dep-keyed), no in-flight Cmd. Waiting\n * past that point is not the Sub-driven contract, it is a leak: no transition is\n * coming, so the drive would hang with the runtime alive and `stop()` never\n * reached. The rejection carries the stalled State on `error.state`, sibling to\n * `DriveFailedError`, so the caller reads where the machine parked off the\n * Model rather than off a message string (invariant 6).\n *\n * A machine that CAN still move — a Sub that will deliver the terminal Msg after\n * the dispatch quiesces — is not stalled and the drive keeps waiting; this names\n * only the case where the runtime itself can prove nothing is coming.\n */\nexport class DriveStalledError<S> extends Error {\n override readonly name = \"DriveStalledError\";\n readonly _tag = \"DriveStalledError\" as const;\n constructor(public readonly state: S) {\n super(\n `@demlik/tea: driveToDone stalled — the start chain quiesced on a State ` +\n `that is neither terminal nor failed, with no live Sub and no Cmd in ` +\n `flight to move it further. Read \\`error.state\\` for the State it ` +\n `parked on; if a later transition was expected, the machine needs a ` +\n `Sub (or a Cmd) that delivers it.`,\n );\n }\n}\n\n/**\n * Base of the LOSSY-BUT-LEGAL teardown facts: work the host discarded by letting\n * go of a runtime that still had something outstanding. Reported under\n * `phase: \"discard\"`, never raised.\n *\n * It exists so \"is this fatal?\" has ONE definition — `error instanceof\n * RuntimeDiscardNotice` — that the default sink can ask about any error from any\n * site. The phase cannot answer it: a report site attaches the phase, so a\n * consumer sink that throws while handling a `\"discard\"` report carries that\n * phase into the sink-failure path, and a phase-keyed warn branch would swallow\n * the sink's own defect. Sub-classing is how a new teardown fact opts into the\n * warn-only treatment; nothing else can.\n */\nexport abstract class RuntimeDiscardNotice extends Error {}\n\n/**\n * Reported to the `OnError` sink under `phase: \"discard\"` when `stop()` is\n * called while `interpret` handlers are still awaiting. The host is dropping\n * its only handle on that work: `stop()` drains the tail, but the listeners,\n * observers and event handlers that would have consumed the resulting\n * transitions are gone, so the Cmds' results reach nobody.\n *\n * The motivating shape is `@demlik/tea/react`'s `useMachine`, which memoizes on\n * `[machine, ctx, store]` — a ctx re-derived mid-flight replaces the runtime,\n * and the in-flight mutation's response arrives for a runtime the UI no longer\n * renders, silently rewinding the visible state. Never a throw: tearing a\n * runtime down mid-flight is legal (a navigation does it every time), so this\n * is surfaced as data, not raised. Mechanizes invariant 6 (no silent failures)\n * at the teardown seam, the role `QuiescenceTimeoutError` plays for `idle()`.\n */\nexport class RuntimeDiscardedError extends RuntimeDiscardNotice {\n override readonly name = \"RuntimeDiscardedError\";\n readonly _tag = \"RuntimeDiscardedError\" as const;\n constructor(public readonly pendingCmds: number) {\n super(\n `@demlik/tea: runtime stopped with ${pendingCmds} Cmd(s) in flight — ` +\n `their results will reach no listener. In React this is usually a ` +\n `ctx-identity change rebuilding useMachine's runtime mid-flight: ` +\n `stabilize the ctx (useMemo / useState) so the runtime outlives the ` +\n `Cmds it started. An intentional teardown (unmount, navigation) can ` +\n `silence this with a run({ onError }) sink that ignores ` +\n `phase: \"discard\".`,\n );\n }\n}\n\n/**\n * Reported to the `OnError` sink under `phase: \"identity-drop\"` when the\n * `Identity` filter drops a message addressed to a different instance.\n *\n * The drop itself is the feature — it is what lets a reducer stop repeating\n * `if (msg.runId !== state.runId) return`. What was missing is that it was\n * INVISIBLE: the dispatch resolved exactly like an applied one, so a reusable\n * Durable Object serving run A and then run B lost every run-B message and\n * reported success to each caller. The comment claiming \"the one observable\n * enforcement point\" described this notice before it existed.\n *\n * Never fatal (`RuntimeDiscardNotice`): a mis-addressed message is a normal\n * consequence of instance reuse, not a defect. A host that wants to act on it\n * — a metric, a 409 to the caller, a re-route — reads `phase: \"identity-drop\"`\n * in its own sink.\n */\nexport class IdentityDropNotice extends RuntimeDiscardNotice {\n override readonly name = \"IdentityDropNotice\";\n readonly _tag = \"IdentityDropNotice\" as const;\n constructor(public readonly msgType: string) {\n super(\n `@demlik/tea: Msg \"${msgType}\" was addressed to a different instance ` +\n `than this state owns and was dropped before \\`update\\` ran — the ` +\n `machine's \\`identity\\` filter working as declared. If this Msg was ` +\n `meant for THIS instance, its \\`ofMsg\\` projection disagrees with ` +\n `\\`ofState\\`; if the instance is being reused across runs, route the ` +\n `message to the run that owns it.`,\n );\n }\n}\n\n/**\n * Reported to the `OnError` sink under `phase: \"discard\"` when `stop()`'s wait\n * for async teardown work hits `disposeTimeoutMs`.\n *\n * `stop()` awaits the disposals it started so `await runtime.stop()` can mean\n * \"safe to evict\". A `release` that never settles must not turn that guarantee\n * into a host that never shuts down, so the wait is bounded and expiry is\n * REPORTED rather than silently tolerated — the resource is genuinely still\n * open at that point, and only the host can decide what that costs.\n */\nexport class DisposeTimeoutNotice extends RuntimeDiscardNotice {\n override readonly name = \"DisposeTimeoutNotice\";\n readonly _tag = \"DisposeTimeoutNotice\" as const;\n constructor(\n public readonly pendingDisposals: number,\n public readonly timeoutMs: number,\n ) {\n super(\n `@demlik/tea: stop() gave up waiting for ${pendingDisposals} async ` +\n `teardown(s) after ${timeoutMs}ms — the resources they release may ` +\n `still be open. Make \\`release\\` / the Sub cleanup settle (bound its ` +\n `own IO), or raise run({ disposeTimeoutMs }).`,\n );\n }\n}\n\n/**\n * The rejection of a dispatch that arrived DURING `stop()`'s drain — an in-flight\n * interpret handler's follow-up Msg, a detached handler's terminal Msg, or a Sub\n * that is still live because subs are torn down only after the drain. The stop\n * barrier is absolute (the Msg is refused, never folded), so this names the loss.\n *\n * It is the SECOND witness of `RuntimeDiscardedError`'s fact, and it is why the\n * drain window is a distinct runtime state rather than a plain `stopped` flag:\n * a Msg refused inside the window was discarded BY the teardown, while the same\n * refusal after `stop()` has returned is a consumer dispatching into a runtime it\n * already retired — a real error, and still loud (`phase: \"follow-up\"`, or the\n * caller's own rejection). The distinction is the state at refusal time, never\n * the message text.\n */\nexport class DispatchDiscardedError extends RuntimeDiscardNotice {\n override readonly name = \"DispatchDiscardedError\";\n readonly _tag = \"DispatchDiscardedError\" as const;\n constructor(public readonly msgType: string) {\n super(\n `@demlik/tea: Msg \"${msgType}\" arrived while the runtime was stopping ` +\n `and was discarded — stop() refuses new work so the drain terminates. ` +\n `It is the result of a Cmd that outlived its runtime; keep the runtime ` +\n `alive until the Cmd settles (in React: stabilize useMachine's ctx) if ` +\n `the transition matters.`,\n );\n }\n}\n\n/**\n * Define a typed port. `name` is metadata (devtools / debug logs); port identity\n * is by reference. Each definePort call must use a unique `name` — a second call\n * with the same name throws `PortNameCollisionError`. Use ports for \"data leaving\n * the runtime selectively\" (cursor announcements, DOM-mutation broadcasts,\n * telemetry) that should NOT be folded into State. Strengthens invariant 7.\n */\nexport function definePort<T>(name: string): Port<T> {\n // HMR skip — Vite / dev servers re-import the module on hot reload, which\n // would otherwise false-positive on every definePort across reloads. The\n // try/catch is load-bearing for service-worker bundles: Vite polyfills\n // `import.meta.url` via `document.baseURI`, which throws ReferenceError in\n // an MV3 service worker. A throw here would abort SW install (Chrome\n // surfaces it as \"registration failed status 15\"). Catching it = \"no HMR\n // detected\" = the collision check applies, which is the correct SW\n // behavior (SWs reload via chrome.runtime.reload, not module HMR).\n let isHmr = false;\n try {\n const meta = import.meta as { hot?: unknown };\n isHmr = meta?.hot !== undefined && meta?.hot !== null;\n } catch {\n isHmr = false;\n }\n if (!isHmr && definedPortNames.has(name)) {\n throw new PortNameCollisionError(name);\n }\n definedPortNames.add(name);\n return { __brand: \"port\", name } as Port<T>;\n}\n\n// === Store: pluggable persistence adapter ===\n//\n// `load()` returns `unknown` because storage genuinely doesn't know `S` —\n// chrome.storage returns whatever JSON lives at the key, DurableObjectStorage\n// returns whatever bytes were serialized. Casting raw storage to `S` at the\n// adapter boundary is the exact `as S` move forbidden by invariant 8\n// everywhere else in the substrate. `load()` returning `unknown` makes the\n// substrate stop pretending.\n//\n// `migrate(raw)` is the boundary parse. Returns `S` on a recognized shape —\n// the substrate passes it to `init` as `loaded`. Returns `null` on any\n// unrecognized shape — the substrate passes `null` to `init`, fresh-boot\n// path. Must NOT throw: if a future shape is unrecognizable, returning\n// `null` boots clean from a known-good path. Throwing here would\n// indistinguishably collapse \"storage corruption\" and \"schema migration not\n// yet written\" — both are runtime decisions, not panics.\n//\n// Strengthens invariant 8 (the boundary parses; the core trusts) — the\n// substrate now enforces the parse instead of relying on every adapter\n// remembering to.\nexport interface Store<S> {\n load(): Promise<unknown>;\n save(state: S): Promise<void>;\n migrate(raw: unknown): S | null;\n}\n\n// === FencedStore: the same seam, with a second writer refused ===\n//\n// `Store.save` is unconditional, so two live processes pointed at one\n// `agent.json` both drive the run to done and neither can learn it raced (#143).\n// Atomicity of one write (fileStore's temp + rename) is not exclusion between\n// two writers.\n//\n// The fix is an OPTIONAL widening, never a change to `Store<S>` itself: the\n// stable-root interface is implemented by four in-repo adapters and any number\n// of external ones, and none of them breaks here. A store that can fence says so\n// with `fenced: true` and adds two methods beside — NOT overrides of `load` and\n// `save`, because a `load` returning `{ raw, version }` is still assignable to\n// `Promise<unknown>` and would hand every version-blind caller a wrapper blob its\n// `migrate` cannot read. Two names keep the two contracts apart.\n//\n// `version` is opaque to the substrate: a monotone number the store mints. The\n// runtime only ever hands back the one it was given, so a store is free to\n// define it as a file stamp, a DO storage cell, or an in-process counter.\nexport interface FencedRead {\n /** Raw bytes at the key, the `Store.load` contract unchanged. */\n readonly raw: unknown;\n /** The version those bytes were written at. A never-written key reads `0`. */\n readonly version: number;\n}\n\n/**\n * A `Store<S>` that can refuse a second live writer.\n *\n * `run` fences automatically when it is handed one of these: it reads the\n * version at boot and compare-and-swaps on every save, so a second process that\n * started from the same version is refused at its first write with a\n * {@link StoreConflictError}. Hand `run` a plain `Store<S>` and it stays exactly\n * as it was — the last writer wins, and single-writer is your precondition to\n * keep (see `docs/explanation/durability-model.md`).\n *\n * Fencing is opt-in at 0.x: every shipped factory that can fence takes an\n * explicit `{ fenced: true }` and returns this type; the unfenced call is\n * byte-for-byte the old behaviour.\n */\nexport interface FencedStore<S> extends Store<S> {\n /** Discriminant — the one thing {@link isFencedStore} reads. */\n readonly fenced: true;\n /** `load`, plus the version those bytes carry. */\n loadFenced(): Promise<FencedRead>;\n /**\n * Compare-and-swap save. Writes `state` only if the stored version is still\n * `expectedVersion`, and resolves with the NEW version to swap on next time.\n * Throws {@link StoreConflictError} when it is not.\n */\n saveFenced(state: S, expectedVersion: number): Promise<number>;\n}\n\n/** Narrow a `Store<S>` to a {@link FencedStore} — what `run` uses to decide. */\nexport function isFencedStore<S>(store: Store<S>): store is FencedStore<S> {\n return \"fenced\" in store && store.fenced === true;\n}\n\n/**\n * Thrown when a fenced save finds a version other than the one it expected —\n * another live writer has this run.\n *\n * A throw, not a settled failure Msg (ADR 0017, following ADR 0011): a second\n * claimant is a contract breach of the single-writer promise, not a state this\n * run can fold and continue from. There is no correct way for the loser to\n * carry on, so it stops where it stands.\n */\nexport class StoreConflictError extends Error {\n override readonly name = \"StoreConflictError\";\n readonly _tag = \"store_conflict\" as const;\n constructor(\n readonly expectedVersion: number,\n readonly actualVersion: number,\n ) {\n super(\n `@demlik/tea: store conflict — expected version ${expectedVersion}, ` +\n `found ${actualVersion}. Another process has written this state; ` +\n `this run is no longer the single writer and has stopped.`,\n );\n }\n}\n\n// === Schema-derived migrate: single-source the durable State ===\n//\n// The boundary parse `migrate(raw)` is two jobs glued together:\n// 1. STRUCTURAL VALIDATION — \"is this the current shape?\" 100% derivable\n// from the State type, pure boilerplate, the part that drifts when a\n// field is added to a variant but the hand-written parser isn't updated.\n// 2. VERSION MIGRATION — \"upgrade an OLD shape to the current one\" (default a\n// missing field, drop a dead one, remap a removed enum). Genuine logic.\n// Encodes decisions about how past rows map forward. NOT derivable.\n//\n// `schemaMigrate` derives job 1 from a schema and isolates job 2 in a thin,\n// explicit `upcast` run BEFORE the parse. When the State type is itself\n// `Schema<S>`-inferred (`type S = SchemaOutput<typeof schema>`), the type and\n// the validator are the SAME declaration — you cannot add a field to the type\n// without it being in the schema, so the parse always enforces the current\n// shape. The `as S` an adapter would otherwise write on `safeParse().data` is\n// deleted: the schema's output IS `S`.\n//\n// The kernel stays library-agnostic — `Schema<S>` is the minimal Standard-\n// Schema-shaped surface (`safeParse`) that both zod 3 and zod 4 satisfy. No\n// validator is imported here; the consumer supplies one.\n//\n// Strengthens invariant 8 (the boundary parses; the core trusts) and invariant\n// 1 (state is a value — one declaration sources both type and parser).\nexport interface Schema<S> {\n safeParse(raw: unknown): { success: true; data: S } | { success: false };\n}\n\n/**\n * Build a `Store.migrate` from a schema (job 1) and an optional thin `upcast`\n * (job 2). `upcast` maps a recognized-but-OLD raw shape forward into the shape\n * the schema validates; it defaults to identity (no version migration yet).\n *\n * Never throws — a shape the schema rejects returns `null`, the substrate's\n * fresh-boot path, per the `Store.migrate` contract. An `upcast` that itself\n * throws on a corrupt blob is caught and collapses to `null` (same posture).\n */\nexport function schemaMigrate<S>(\n schema: Schema<S>,\n upcast: (raw: unknown) => unknown = (raw) => raw,\n): (raw: unknown) => S | null {\n return (raw: unknown): S | null => {\n let migrated: unknown;\n try {\n migrated = upcast(raw);\n } catch {\n return null;\n }\n const parsed = schema.safeParse(migrated);\n return parsed.success ? parsed.data : null;\n };\n}\n\n// === DispatchSettle: how far a dispatch awaits ===\n//\n// The default is the SAFE one, `\"quiescent\"` — `dispatch` resolves only once the\n// entire transitive follow-up chain has drained (the same drain `idle()`\n// performs). Were the default one transition, an `interpret` follow-up Msg would\n// enqueue a fresh transition fire-and-forget relative to the original\n// `dispatch`, resolving \"early\". The rare single-step case opts in with `\"once\"`\n// (or the `dispatchOnce` convenience).\nexport type DispatchSettle = \"quiescent\" | \"once\";\n\n// === RuntimeRef<M>: typed sibling-runtime handle ===\n//\n// Exposes only the inbox of a Runtime — `dispatch` / `dispatchOnce`. Use it as\n// the field type when one runtime holds a *sibling* (composition by reduction\n// across orthogonal lifecycles — invariant 5): the holder learns the Msg shape\n// it can send, nothing about the referenced runtime's State/Cmd/Sub/Ctx/\n// observers/Port fanout. `Runtime<S, M>` extends `RuntimeRef<M>` structurally.\nexport interface RuntimeRef<M extends { type: string }> {\n /**\n * Put a Msg in the runtime's inbox and resolve once processed. Runs to\n * QUIESCENCE by default: settles only after the dispatched Msg AND every\n * transitive interpret follow-up has drained. Pass `{ settle: \"once\" }` (or\n * call `dispatchOnce`) for the single-step case.\n *\n * Rejection ordering: the ONE dispatched transition's own failure surfaces\n * first, here. If it succeeds but the follow-up chain never stabilizes, the\n * quiescent drain rejects with `QuiescenceTimeoutError`. Follow-up Msg\n * rejections themselves route to the `onError` sink, never here.\n */\n dispatch(msg: M, opts?: { readonly settle?: DispatchSettle }): Promise<void>;\n /**\n * Dispatch `msg` and resolve after exactly ONE transition's effects settle,\n * WITHOUT draining the follow-up chain — equivalent to\n * `dispatch(msg, { settle: \"once\" })`. Prefer plain `dispatch` unless you will\n * `await runtime.idle()` yourself; the un-awaited follow-up chain is the\n * footgun the quiescent default removed.\n */\n dispatchOnce(msg: M): Promise<void>;\n}\n\n// === BootingRuntime: handle returned SYNCHRONOUSLY from run() ===\n//\n// `run()` returns a `BootingRuntime<S, M>` the instant it is called, while boot\n// is still in flight. It exposes exactly the surface TOTAL before boot: queue a\n// dispatch, subscribe, observe, wire a Port, stop. What you may NOT do is read\n// State (`getState`) or wait for quiescence (`idle`) — those need the initial\n// State to exist, and are the difference between a BootingRuntime and a\n// `Runtime`, enforced at the type level so \"read State before boot\" is a COMPILE\n// error, not a runtime throw.\n//\n// `subscribe` is the React-shaped change notifier (zero-arg, paired with\n// `getState()`). `observe` is the devtools-shaped trace hook — `(msg, state)`\n// for every APPLIED transition; boot is delivered via `onBoot` instead, so\n// `observe`'s `msg` is total (never `null`). `on(type, handler)` is the SEMANTIC\n// event channel: only the public, `type`-narrowed events a machine projects,\n// never its PRIVATE Msg vocabulary. `E` defaults to `never` (no projector → `on`\n// uncallable).\nexport interface BootingRuntime<\n S,\n M extends { type: string },\n E extends { type: string } = never,\n> extends RuntimeRef<M> {\n dispatch(msg: M, opts?: { readonly settle?: DispatchSettle }): Promise<void>;\n dispatchOnce(msg: M): Promise<void>;\n /**\n * Register a zero-arg change notifier, fired for every applied transition\n * with the fold's State already committed — `getState()` inside the listener\n * reads it, not the State before. A `dispatch` issued from the listener is\n * SCHEDULED onto the serial tail behind the fold that fired it, never folded\n * re-entrantly and never discarded, so it needs no `setTimeout(fn, 0)`\n * deferral; two listeners issuing in order fold in that order.\n */\n subscribe(listener: () => void): () => void;\n /**\n * Register a `(msg, state)` trace hook, fired for every applied transition\n * with the fold's committed State. A `dispatch` issued from the observer is\n * SCHEDULED onto the serial tail behind the fold that fired it, never folded\n * re-entrantly and never discarded, so it needs no `setTimeout(fn, 0)`\n * deferral; two listeners issuing in order fold in that order.\n */\n observe(observer: (msg: M, state: S) => void): () => void;\n /**\n * Subscribe to the INITIAL State — the boot transition. Fires exactly once:\n * immediately if boot already completed (so a late subscriber never misses\n * it), otherwise on the boot fanout. Returns a cleanup (a no-op once fired).\n */\n onBoot(handler: (state: S) => void): () => void;\n /**\n * Subscribe to a SEMANTIC event of `type`. The handler receives exactly the\n * `E` member whose `type` matches `K`, so a consumer never touches another\n * event's shape and never references the machine's PRIVATE Msg names. Multiple\n * handlers per type; fanout is synchronous and throw-isolated. Fires only when\n * the machine's `events` projector (wired on `run`) emits that type.\n */\n on<K extends E[\"type\"]>(\n type: K,\n handler: (event: Extract<E, { type: K }>) => void,\n ): () => void;\n /**\n * Subscribe to a typed Port. Multiple listeners per port; fanout is synchronous\n * and isolated. Ports are for \"data leaving the runtime selectively\" (see\n * `definePort`) — distinct from `observe` (every transition) and State.\n */\n subscribePort<T>(port: Port<T>, listener: (value: T) => void): () => void;\n /**\n * Emit a value on a Port from OUTSIDE an interpret handler — same synchronous\n * fanout as `ctx.emit`. The canonical use is `observe`-driven emission (one\n * runtime publishing a state-derived signal another subscribes to via\n * `subscribePort`) without spawning a \"tell the outside world\" Cmd per\n * transition.\n */\n emitPort<T>(port: Port<T>, value: T): void;\n /**\n * Resolves to the booted `Runtime<S, M>` after boot completes (or rejects with\n * the boot error). This is the ONLY way to obtain a `Runtime` — and a\n * `Runtime` is the only handle whose `getState()` is total. Awaiting `ready` is\n * the single gate between \"boot in flight\" and \"State exists\":\n *\n * ```ts\n * const runtime = await run(machine, opts).ready;\n * runtime.getState(); // total — never throws-before-boot\n * ```\n *\n * Idempotent — the same settled promise, resolving to the same `Runtime`, comes\n * back on every read. Expresses canon §2.3 (boot is a named, awaitable moment).\n */\n ready: Promise<Runtime<S, M, E>>;\n stop(): Promise<void>;\n}\n\n// === Runtime: the BOOTED handle `ready` resolves to ===\n//\n// A `BootingRuntime<S, M>` whose boot has completed. It adds the two members\n// only meaningful once the initial State exists — `getState()` (total) and\n// `idle()` (quiescence) — and narrows `ready` to resolve to itself. You never\n// construct one directly; you obtain it via `await bootingRuntime.ready`, which\n// makes \"read State before boot\" unrepresentable rather than merely discouraged.\nexport interface Runtime<\n S,\n M extends { type: string },\n E extends { type: string } = never,\n> extends BootingRuntime<S, M, E> {\n /**\n * The current State. TOTAL — never throws. Obtaining a `Runtime` requires\n * awaiting `ready`, which only resolves AFTER boot has run `init` and set the\n * initial State.\n */\n getState(): S;\n /** Resolves to this same `Runtime` once boot completes. Idempotent. */\n ready: Promise<Runtime<S, M, E>>;\n /**\n * Resolves once the runtime has reached QUIESCENCE — every dispatched Msg AND\n * every transitive interpret follow-up has been processed, with no further step\n * pending on the tail. Since plain `dispatch` already runs to quiescence, this\n * is mainly for follow-ups left by a `dispatchOnce` single step, or a chain\n * kicked off by a Sub / boot `init` cmds with no `dispatch` to await.\n *\n * Idempotent and re-entrant-safe. Tail rejections are NOT surfaced here (a\n * failing dispatch surfaces on its OWN promise; follow-up rejections route to\n * `onError`). The one rejection `idle()` produces is `QuiescenceTimeoutError`\n * on hitting the iteration cap — so a livelock stays distinguishable from a\n * genuine quiesce (invariant 6). A poll is still correct when waiting on an\n * EXTERNAL event the runtime cannot enqueue itself.\n */\n idle(): Promise<void>;\n /**\n * The terminal State of the run, or `undefined` while in flight — \"terminal\"\n * per the `terminal` predicate passed to `run()` (no predicate → never\n * terminal → always `undefined`). The first-class result read: the run's\n * product off the State the machine already owns, NOT scraped off the `observe`\n * firehose by matching an internal Msg name. Total — never throws.\n */\n result(): S | undefined;\n /**\n * Resolves with the terminal State the first time the run reaches one (per the\n * `terminal` predicate). If ALREADY terminal, resolves immediately; otherwise\n * on the transition that first makes `terminal` hold. The awaitable companion\n * to `result()`. With no predicate this never resolves. Idempotent and\n * multi-caller safe.\n */\n done(): Promise<S>;\n}\n\n// === defineMachine: identity-typed pass-through ===\n//\n// Overloads enforce exactly one `update` shape per call so consumers see a\n// concrete type, not the internal union. Runtime is identity — `run` branches on\n// the structural shape of `update` (Reducer = record of functions; Transitions =\n// record of records) when dispatching, so overload resolution picks the right\n// branch by value shape. Strengthens invariant 2 (record forms have no\n// fall-through default) and invariant 7 (the variant set is load-bearing).\n\n// === `types`-form overloads — Model and Msg named once, as values ===\n//\n// `S` and `M` cannot be INFERRED from `update`: every cell there is\n// contextually typed BY them, so the only inference site is the one the author\n// writes. Before `types` that site was the explicit type-argument list, which\n// made a five-slot positional signature (`defineMachine<Model, Msg, typeof\n// lookup | typeof audit, never, NoCtx>`) plus a hand-spelled `Settled<typeof\n// lookup>` union the entry price of writing a machine (#190).\n//\n// `types` moves that one site into the object, as values:\n//\n// defineMachine({\n// types: { model: {} as Model, msg: {} as Msg },\n// cmds: [lookup, audit],\n// …\n// })\n//\n// and everything else is derived exactly as it already was — `C` and the\n// settled half of `M` from `cmds`, and each interpret handler's `ctx` from its\n// own Cmd's requirements (`Interpret` already intersects `RequirementsOf` onto\n// the cell's `ctx`, so a `Cmd.define`d effect types its handler with no\n// `types.ctx` at all). The shape is XState v5's `setup({ types })` in tea's\n// vocabulary; the keys are `model`, `msg`, `cmd`, `sub`, `ctx` — the words this\n// library already uses for those five slots.\n//\n// `NoInfer` around the WHOLE machine body is what makes the one site the only\n// site: `init`'s return and every cell's `SyncReturn<S, C>` are otherwise\n// competing inference sites, and a candidate from either widens the Model past\n// what `types.model` declared (a bare `[{ n: 0 }, []]` infers `{ n: number }`\n// and wins over the branded Model). Wrapping the body — rather than each `S` /\n// `M` / `C` / `Ctx` occurrence inside it — is load-bearing: `NoInfer<X>` reads\n// as a contextual type for a nested function's PARAMETERS either way, but only\n// the outer form keeps the freshness of an object literal a nested function\n// RETURNS, and every cell returns one.\n//\n// The one shape that still needs help is a zero-parameter `init` returning a\n// fresh state literal on a DISCRIMINATED Model: with no parameter the function\n// is not context-sensitive, so it is checked before `S` is fixed and\n// `{ type: \"idle\" }` widens to `{ type: string }`. Take `loaded` (which the\n// rehydrate contract wants named anyway) or name the initial state as a const.\n//\n// `types.cmd` / `types.sub` carry the hand-written unions — a machine that\n// predates `Cmd.define` has no `cmds` list to derive `C` from, and `U` has no\n// value-level source at all now that the body infers nothing. Both are OPTIONAL\n// and both default to the cmdless / subless marker, so a pure machine names\n// neither.\n//\n// Two overloads, not four: `update`'s Reducer-vs-Transitions split stays the\n// union `Machine.update` already carries, because the concrete form the caller\n// sees comes off the RETURN type, which is identical either way. Splitting it\n// here instead cost the `types` calls their contextual typing — with four\n// candidate signatures over one context-sensitive object literal, resolution\n// settled on a later overload and every cell fell to `any`.\n\n/**\n * The `types` option: the slots of a machine's shape that no value in the\n * object can imply, declared once as phantom values (`{} as Model`).\n *\n * `model` and `msg` are always named. `cmd` is named only by a machine whose\n * Cmds are hand-written records rather than `Cmd.define` constructors listed\n * under `cmds`; `sub` only by one whose Sub union `subscriptions` does not\n * imply; `ctx` only by one whose handlers read a `Ctx` slice no Cmd's\n * `requirements` declares.\n */\nexport type MachineTypes<\n S,\n M extends { type: string },\n C extends Cmd,\n U extends Sub,\n Ctx,\n> = {\n readonly model: S;\n readonly msg: M;\n readonly cmd?: C;\n readonly sub?: U;\n readonly ctx?: Ctx;\n};\n\n// `types` + `cmds` — `C` and the settled half of `M` derive from the defs.\nexport function defineMachine<\n S,\n M extends { type: string },\n D extends AnyCmdDef,\n U extends Sub = Sub<never>,\n Ctx = unknown,\n>(\n m: NoInfer<Omit<Machine<S, M | Settled<D>, CmdOf<D>, U, Ctx>, \"cmds\">> & {\n readonly types: MachineTypes<S, M, Cmd<never>, U, Ctx>;\n readonly cmds: readonly D[];\n },\n): Machine<S, M | Settled<D>, CmdOf<D>, U, Ctx>;\n// `types` without `cmds` — `C` comes from `types.cmd`.\nexport function defineMachine<\n S,\n M extends { type: string },\n C extends Cmd = Cmd<never>,\n U extends Sub = Sub<never>,\n Ctx = unknown,\n>(\n m: NoInfer<Machine<S, M, C, U, Ctx>> & {\n readonly types: MachineTypes<S, M, C, U, Ctx>;\n },\n): Machine<S, M, C, U, Ctx>;\n\n// `cmds`-form overloads — the machine names its typed Cmd constructors\n// (`Cmd.define`) and the effect half of its shape is DERIVED (ADR 0014): `C` is\n// the union of the values the defs build, and `M` is the user's own Msg union\n// plus every def's `Settled` pair (`<name>_ok` / `<name>_err`). The user never\n// spells `fetch_ok` in `M`; the `Reducer` mapped type still demands its cell.\n// `D` is a UNION of defs (not a tuple), so `cmds: [fetch, save]` infers\n// `typeof fetch | typeof save` and an explicit `defineMachine<S, M, typeof fetch\n// | typeof save, U, Ctx>` reads the same way. Declared first: a def has no\n// `type` field, so a Cmd union never satisfies `D extends AnyCmdDef`, and a\n// def never satisfies `C extends Cmd` — the two families cannot cross-match.\nexport function defineMachine<\n S,\n M extends { type: string },\n D extends AnyCmdDef,\n U extends Sub,\n Ctx,\n>(\n m: Omit<Machine<S, M | Settled<D>, CmdOf<D>, U, Ctx>, \"update\" | \"cmds\"> & {\n readonly cmds: readonly D[];\n update: [S] extends [{ type: string }]\n ? Transitions<S, M | Settled<D>, CmdOf<D>>\n : never;\n },\n): Machine<S, M | Settled<D>, CmdOf<D>, U, Ctx>;\nexport function defineMachine<\n S,\n M extends { type: string },\n D extends AnyCmdDef,\n U extends Sub,\n Ctx,\n>(\n m: Omit<Machine<S, M | Settled<D>, CmdOf<D>, U, Ctx>, \"update\" | \"cmds\"> & {\n readonly cmds: readonly D[];\n update: Reducer<S, M | Settled<D>, CmdOf<D>>;\n },\n): Machine<S, M | Settled<D>, CmdOf<D>, U, Ctx>;\n// Transitions-form overload — 2D table keyed by State.type then Msg.type.\n// Declared before the reducer form (more specific). The S constraint is a\n// conditional (`S extends { type: string } ? Transitions<...> : never`) not a\n// generic-parameter constraint, so `S` stays unconstrained at the signature and\n// the public `Parameters<typeof defineMachine<NonDiscriminatedS, ...>>` pattern\n// skips this overload (update becomes `never`) instead of failing.\nexport function defineMachine<\n S,\n M extends { type: string },\n C extends Cmd,\n U extends Sub,\n Ctx,\n>(\n m: Omit<Machine<S, M, C, U, Ctx>, \"update\"> & {\n // `[S]` tuple-wrap disables distributive conditional behavior — see\n // the comment on `Machine.update` for why distribution is wrong here.\n update: [S] extends [{ type: string }] ? Transitions<S, M, C> : never;\n },\n): Machine<S, M, C, U, Ctx>;\n// Reducer-form overload — flat record keyed by Msg.type.\nexport function defineMachine<\n S,\n M extends { type: string },\n C extends Cmd,\n U extends Sub,\n Ctx,\n>(\n m: Omit<Machine<S, M, C, U, Ctx>, \"update\"> & {\n update: Reducer<S, M, C>;\n },\n): Machine<S, M, C, U, Ctx>;\n// Implementation signature — accepts both via the union on `Machine.update`.\nexport function defineMachine<\n S,\n M extends { type: string },\n C extends Cmd,\n U extends Sub,\n Ctx,\n>(m: Machine<S, M, C, U, Ctx>): Machine<S, M, C, U, Ctx> {\n // Tag the update form ONCE, here at the typed construction boundary, so no\n // downstream reader re-derives it structurally. Non-enumerable so it does not\n // serialize, show up in `Object.keys`, or collide with a Msg.type key.\n // Idempotent under re-wrap (`defineMachine(defineMachine(m))`).\n if (m.__form === undefined) {\n Object.defineProperty(m, \"__form\", {\n value: detectUpdateForm(m.update as object),\n enumerable: false,\n writable: false,\n configurable: true,\n });\n }\n return m;\n}\n\n// === asReducer: the validated minting path for a reducer ===\n//\n// Turns a raw record of handlers into a branded `Reducer<S, M, C>`. The\n// parameter type's every cell returns the non-thenable `SyncReturn<S, C>`, so\n// the reentrancy guard fires HERE, at construction: an `async` cell returns\n// `Promise<...>`, not assignable to `SyncReturn`, and `tsc` rejects it. PURE —\n// identity at runtime (the brand is phantom). `defineMachine` brands its\n// `update` internally the same way, so this exists for the standalone `const\n// update = asReducer<...>({ ... })` form.\nexport function asReducer<S, M extends { type: string }, C extends Cmd>(\n reducer: Reducer<S, M, C>,\n): Branded<Reducer<S, M, C>> {\n return reducer as Branded<Reducer<S, M, C>>;\n}\n\n// === CtxArg<Ctx>: the `ctx` field of `run`'s opts, conditionally optional ===\n//\n// A PURE machine reads nothing from `ctx` (its `Ctx` is `NoCtx` /\n// `Record<string, never>` / `unknown`); forcing `ctx: {}` is ceremony for a\n// value the type already pins as empty. So `ctx` is CONDITIONALLY optional: when\n// `{}` satisfies `Ctx` it may be OMITTED (defaulted to `{}`), so a pure reducer\n// runs as `run(machine)`; when `Ctx` carries a field a handler reads, `ctx` stays\n// REQUIRED. `[Record<never, never>] extends [Ctx]` reads as \"is `{}` assignable\n// to `Ctx`\" — true for the context-free shapes, false for `{ db: … }`; the\n// tuple-wrap disables distributive conditional behavior.\nexport type CtxArg<Ctx> = [Record<never, never>] extends [Ctx]\n ? { ctx?: Ctx }\n : { ctx: Ctx };\n\n// === ScopedCtxArg<Ctx>: `run`'s `ctx` field — the object, or the graph ===\n//\n// `CtxArg<Ctx>` widened by exactly one alternative: a `provide({ … })` graph\n// that BUILDS a `Ctx`, which `run` acquires at boot and releases at `stop()`.\n// The requirement is the same `Ctx` either way — only who assembles it moves.\n// Kept separate from `CtxArg` on purpose: the other `CtxArg` sites (`replay`'s\n// seed, `defineAgent`'s options) hand their `ctx` to a PURE fold, and a fold has\n// no boot to acquire in and no terminal to release at, so widening them would\n// promise a lifetime nothing there could honour.\n/**\n * `run`'s `ctx` field: the `Ctx` object, or a `provide` graph that builds one.\n * Conditionally optional exactly like {@link CtxArg} — a machine that reads\n * nothing from `ctx` may omit it.\n */\nexport type ScopedCtxArg<Ctx> = [Record<never, never>] extends [Ctx]\n ? { ctx?: Ctx | Provided<Ctx> }\n : { ctx: Ctx | Provided<Ctx> };\n\n// === replay: pure unit-test helper ===\n//\n// Composes `init(loaded ?? null, ctx)` then `update(state, msg)` for each msg.\n// Returns the final state plus the cmds that *would* have been emitted and the\n// subs that *would* have been desired at the final state. It does NOT call any\n// `interpret[type]` handler, does NOT touch `Store`, and does NOT start any\n// subscription. `subscriptions` IS called to derive `subs` — that lets tests\n// assert what would be wired up without actually wiring it.\n//\n// Dep-keyed Subs are reported in `depSubs`: for each `machine.subs` entry\n// active at the FINAL state (its `deps` non-null), the entry's `index` and the\n// derived `id` (`structuralHash(deps)`) — so a test can assert \"the deadline +\n// checkpoint + bridge dep-subs are armed in `running`\" without wiring any\n// source. Same intent as `subs` for the manual path: assert the desired set\n// purely. `source` is NEVER called (replay starts no subscription).\nexport function replay<\n S,\n M extends { type: string },\n C extends Cmd,\n U extends Sub,\n Ctx,\n>(\n machine: Machine<S, M, C, U, Ctx>,\n opts: { msgs: readonly M[]; ctx: Ctx; loaded?: S | null },\n): {\n state: S;\n cmds: C[];\n subs: U[];\n depSubs: { index: number; id: string }[];\n} {\n // Coerce undefined → null so `replay` with `loaded: undefined` calls\n // `init(null, ctx)`.\n const loaded = opts.loaded ?? null;\n const [initialState, initCmds] = machine.init(loaded, opts.ctx);\n\n if (loaded !== null && initCmds.length > 0) {\n throw new Error(\n \"TEA contract violation: machine.init must return [state, []] (no Cmds) \" +\n \"when `loaded` is non-null. Init's rehydrate branch is a pure state \" +\n \"passthrough — the migration/parse boundary, not the boot-effect hook.\\n\\n\" +\n \"Routes for boot effects:\\n\" +\n \" - Stateless infrastructure (e.g. chrome.alarms ensure) → host module \" +\n \"top level, outside TEA.\\n\" +\n \" - State-conditional resume (e.g. re-attach a session) → a `boot` Msg \" +\n \"dispatched once from the host after `run(...)` returns, handled in update.\\n\\n\" +\n \"See .patterns/tea/tea-invariants.md (Invariant 2).\",\n );\n }\n\n // `replay` and `foldMsgs` share ONE internal fold (`foldUpdates`), keyed on\n // `formOf` — the same reader `run` uses — so all three agree on the\n // reducer-vs-transitions form by construction.\n const { state, cmds: foldedCmds } = foldUpdates<S, M, C>(\n machine,\n initialState,\n opts.msgs,\n );\n const cmds: C[] = [...initCmds, ...foldedCmds];\n\n const subs: U[] = machine.subscriptions\n ? [...machine.subscriptions(state)]\n : [];\n\n // The dep-keyed desired set at the final state — `deps` only, never `source`.\n const depSubs: { index: number; id: string }[] = [];\n if (machine.subs) {\n for (const [index, entry] of machine.subs.entries()) {\n const deps = entry.deps(state);\n // Same gate the runtime reconciles on (`depsInactive`), not a second\n // spelling of it — a `deps` returning `undefined` means inactive here too.\n if (!depsInactive(deps))\n depSubs.push({ index, id: structuralHash(deps) });\n }\n }\n\n return { state, cmds, subs, depSubs };\n}\n\n// === wrapDetached: the typed Cmd→Msg edge for a detached interpret handler ===\n//\n// Adapts an `InterpretDetached<C, Allowed, Ctx>` — a handler that detaches its\n// long-running work (`ctx.waitUntil(...)`) and fires its TERMINAL Msg through\n// the kernel-injected `dispatch` — into a plain `Interpret` cell that drops into\n// the `interpret` dictionary unchanged. The point is the NARROWING: `Allowed`\n// is the subset of the Msg union this Cmd is permitted to produce, and the\n// `dispatch` the handler sees is typed `(msg: Allowed) => void`. A wrong /\n// typo'd terminal Msg from the detached site then fails to compile (rung 2),\n// where today it reaches for a host-wired `ctx.dispatch` typed to the full\n// union and compiles silently (rung 5 — the allowed set on a comment).\n//\n// `Allowed extends M` is the constraint that makes this SOUND at the kernel:\n// the kernel injects the WIDE `dispatch: (msg: M) => void`, the handler only\n// ever calls it with `Allowed` values (its own narrowed signature enforces\n// that), and every `Allowed` is a valid `M`. So passing the wide dispatch into\n// the narrow-expecting handler is type-correct in one direction (the values the\n// handler produces are all `M`) — the narrowing constrains the AUTHOR, not the\n// kernel. No `as` on data: the only widen is the function reference itself\n// (`dispatch` accepting `M` is usable where one accepting `Allowed` is wanted\n// because `Allowed extends M` — contravariant parameter, sound here because the\n// handler never sees a non-`Allowed` value), expressed by the explicit\n// `Allowed`/`M` generic relation, not a cast.\n//\n// Opt-in / additive: a leaf handler that resolves on its own keeps returning\n// `Promise<M | void>` and never touches `wrapDetached`. Only the detached sites\n// adopt it. The wrapped result is structurally a plain cell, so the `interpret`\n// map type is unchanged.\n//\n// Strengthens invariant 3 (effects are data — the detached effect's terminal\n// result feeds back as a Msg, now a TYPED edge) and invariant 7 (identity is\n// explicit — a Cmd's allowed result-Msg set is load-bearing at the type level).\nexport function wrapDetached<\n C extends Cmd,\n M extends { type: string },\n Allowed extends M,\n Ctx,\n>(\n handler: InterpretDetached<C, Allowed, Ctx>,\n): (\n cmd: C,\n ctx: Ctx & PortEmitter,\n dispatch?: (msg: M) => void,\n) => Promise<void> {\n // The injected `dispatch` accepts the full `M`. The handler's signature only\n // lets it call `dispatch` with `Allowed` (⊆ M) values, so handing it the\n // wide fn is sound: `(msg: M) => void` is callable wherever\n // `(msg: Allowed) => void` is wanted, and every value the handler passes is a\n // valid `M`. No data cast — the relation is carried by `Allowed extends M`.\n //\n // `dispatch` is OPTIONAL on the signature to match the `Interpret` cell type\n // (additive — see `Interpret`). The kernel ALWAYS passes it from\n // `runInterpret`; a detached handler invoked WITHOUT a dispatch (only a\n // mis-wired direct caller could do this) has no way to fire its terminal Msg,\n // so we fail loudly (rung 4) rather than silently dropping the seam's result.\n return (cmd, ctx, dispatch) => {\n if (dispatch === undefined) {\n throw new Error(\n \"@demlik/tea: a wrapDetached handler was invoked without the injected dispatch. \" +\n \"The kernel always supplies it; call the handler through the runtime, not directly.\",\n );\n }\n return handler(cmd, ctx, dispatch);\n };\n}\n\n// === tryApplyCell / tryFoldMsgs: refusal as DATA, not as a throw ===\n//\n// `applyCell` and `foldMsgs` throw `NoCellError` when a Msg has no cell. That\n// is right for the runtime — `run`'s dispatch loop wants the throw so the\n// error sink and supervision see it. It is wrong for a caller that drives a\n// machine itself and treats \"this Msg does not apply here\" as an ORDINARY\n// answer: an interactive tool offering the next move, a validator replaying a\n// persisted log. Those callers were writing\n// `try { applyCell(...) } catch (e) { if (e instanceof NoCellError) ... }`\n// around every step — control flow through the exception channel, and a `catch`\n// wide enough to swallow a genuine bug thrown from inside a cell.\n//\n// So: the same operations with the refusal in the return type. The idiom is\n// `better-result`, exactly as `tryInterpret` below uses it — the package's one\n// runtime dependency, already the house Railway spelling.\n//\n// PLACEMENT: these live here and not in `pure/core` because `pure/core` is the\n// runtime-free leaf and must import NOTHING — `better-result` included (see its\n// header). The pure half of the work is the shared `lookupCell` primitive,\n// which DOES live there; these are the `Result` skins over it. `applyCell` and\n// `tryApplyCell` therefore select the same cell by construction, not by two\n// copies of the form-branching agreeing by luck.\n//\n// NOT a general try/catch: a cell that THROWS from inside its own body is a bug\n// in the machine, and it propagates. Only the ABSENCE of a cell is data here.\n\n/**\n * `applyCell`, with \"no handler for this Msg\" moved into the return type\n * instead of a throw.\n *\n * `Ok` carries the handler's `[nextState, cmds]` verbatim; `Err` carries the same\n * `NoCellError` (msg.type + state name + accepted set) `applyCell` would have\n * thrown — both read one `lookupCell`, so neither can under-report. Dispatch\n * inside `run` keeps using the throwing `applyCell` — this is for callers that\n * step a machine themselves.\n */\nexport function tryApplyCell<S, M extends { type: string }, C extends Cmd>(\n machine: { update: object; __form?: UpdateForm },\n state: S,\n msg: M,\n): Result<readonly [S, readonly C[]], NoCellError> {\n const found = lookupCell<S, M, C>(machine, state, msg);\n if (found.cell === undefined) {\n return Result.err(\n new NoCellError(msg.type, found.stateName, found.acceptedTypes),\n );\n }\n return Result.ok(found.cell(state, msg));\n}\n\n/**\n * The refusal `tryFoldMsgs` reports: WHICH msg in the log had no handler, where.\n *\n * A plain record, not a new `Error` subclass — it is a `Result` payload, never\n * thrown, and the actual error is the existing `NoCellError` it carries. The\n * package's thrown-error idiom (`class extends Error` + `_tag`, pinned by\n * `error-idiom.test.ts`) applies to errors raised at the runtime edge; this one\n * is never raised, so adding a class would state a promise it does not make.\n */\nexport interface FoldRefusal<M> {\n /** Index into the `msgs` array the fold was given. */\n readonly index: number;\n /** The offending Msg itself — so the caller can print it, not just point. */\n readonly msg: M;\n /** The underlying cell-lookup failure: msg.type + state name + accepted set. */\n readonly error: NoCellError;\n}\n\n/**\n * `foldMsgs`, with the \"no handler for this Msg\" case in the return type,\n * INCLUDING which message failed.\n *\n * The motivating use is \"this persisted log does not replay — tell the user\n * where\". A bare `Result<S, NoCellError>` cannot: the error names the msg.type\n * and the state, but a log usually contains that type many times, so the\n * INDEX is the load-bearing fact. The fold stops at the first refusal (state\n * past that point is not defined) and returns it.\n *\n * Shares `foldMsgs`' dev-mode discipline: `deepFreeze` the input state,\n * `assertPureResult` the handler's return. Both compile out of production.\n */\nexport function tryFoldMsgs<S, M extends { type: string }, C extends Cmd>(\n machine: { update: object; __form?: UpdateForm },\n base: S,\n msgs: readonly M[],\n): Result<S, FoldRefusal<M>> {\n let state = base;\n for (const [index, msg] of msgs.entries()) {\n if (__DEV__) deepFreeze(state);\n const stepped = tryApplyCell<S, M, C>(machine, state, msg);\n if (Result.isError(stepped)) {\n return Result.err({ index, msg, error: stepped.error });\n }\n if (__DEV__) assertPureResult(stepped.value, msg.type);\n state = stepped.value[0];\n }\n return Result.ok(state);\n}\n\n// === settle: the typed interpret cell for a `Cmd.define`d effect ===\n//\n// `tryInterpret`'s successor for a typed Cmd (ADR 0014 §2). The handler body\n// returns `Result<Ok, E>` with BOTH channels inferred from the def — `Ok` is\n// what the `ok` schema parses, `E` is the declared `_tag` union — and this\n// maps the two arms onto the minted Msgs: `Ok` → `def.ok(cmd, value)`, `Err` →\n// `def.err(cmd, error)`. The `Result` lives here, in the helper, and never\n// enters the kernel contract: the cell still resolves to a plain Msg\n// (`Interpret` keeps returning `Promise<M | void>`), and `run`'s interpret edge\n// then parses the `_ok` value against the schema and stamps `at`.\n//\n// NOT a try/catch: a `work` that THROWS is a bug in the handler, and it\n// propagates to the error sink like any other interpret throw. A failure the\n// caller has a next move for is an `Err` with one of the declared tags —\n// that is the whole point of naming them (0011).\nexport function settle<D extends AnyCmdDef, Ctx>(\n def: D,\n work: (\n cmd: CmdOf<D>,\n ctx: Ctx & RequirementsOf<CmdOf<D>> & PortEmitter,\n ) => Promise<Result<OkOf<D>, ErrOf<D>>>,\n): (\n cmd: CmdOf<D>,\n ctx: Ctx & RequirementsOf<CmdOf<D>> & PortEmitter,\n) => Promise<Settled<D>> {\n // `AnyCmdDef` is the declaration-erased view the runtime reads; the two\n // builders live on the full `CmdDef`, which every `D` structurally is.\n const builders = def as unknown as {\n readonly ok: (cmd: CmdOf<D>, value: OkOf<D>) => Settled<D>;\n readonly err: (cmd: CmdOf<D>, error: ErrOf<D>) => Settled<D>;\n };\n return async (cmd, ctx) => {\n const result = await work(cmd, ctx);\n return result.match({\n ok: (value) => builders.ok(cmd, value),\n err: (error) => builders.err(cmd, error),\n });\n };\n}\n\n// === tryInterpret: Railway sugar over `Result.tryPromise` ===\n//\n// Wraps a fallible `(cmd, ctx) => Promise<Ok>` into a handler for\n// `interpret[type]`: on success resolves `onOk(value, cmd)`, on rejection\n// `onErr(error, cmd)`. It NEVER rejects (assuming `onOk`/`onErr` are total).\n//\n// We use the `{try, catch: (e) => e}` form (not the one-arg thunk) so the\n// original error passes through untouched — the one-arg form wraps errors in\n// `UnhandledException`, which would break `instanceof` checks inside `onErr`.\nexport function tryInterpret<C extends Cmd, Ok, M, Ctx>(\n work: (cmd: C, ctx: Ctx) => Promise<Ok>,\n onOk: (value: Ok, cmd: C) => M,\n onErr: (error: unknown, cmd: C) => M,\n): (cmd: C, ctx: Ctx) => Promise<M> {\n return async (cmd, ctx) => {\n const result = await Result.tryPromise({\n try: () => work(cmd, ctx),\n catch: (error: unknown): unknown => error,\n });\n return result.match({\n ok: (value) => onOk(value, cmd),\n err: (error) => onErr(error, cmd),\n });\n };\n}\n","/**\n * @demlik/tea runtime — `run`: boot + the serial dispatch loop. The pure helpers\n * that compose against a machine without running it (`replay`, `tryInterpret`)\n * live in `./runtime-types`.\n */\n\nimport type { Provided, Scope } from \"./provide\";\nimport { isProvided } from \"./provide\";\nimport type {\n Dispose,\n Interpret,\n Machine,\n Port,\n PortEmitter,\n RequiredCtx,\n Sub,\n} from \"./pure/core\";\nimport {\n applyCellChecked,\n type Cmd,\n cmdEdge,\n cmdEdgeOver,\n depsInactive,\n detachWork,\n structuralHash,\n} from \"./pure/core\";\nimport type {\n BootingRuntime,\n DispatchSettle,\n FencedStore,\n OnError,\n Runtime,\n RuntimeErrorContext,\n RuntimeErrorPhase,\n ScopedCtxArg,\n Store,\n Supervision,\n} from \"./runtime-types\";\nimport {\n DispatchDiscardedError,\n DisposeTimeoutNotice,\n DriveFailedError,\n DriveStalledError,\n IdentityDropNotice,\n isFencedStore,\n QuiescenceTimeoutError,\n RuntimeDiscardedError,\n RuntimeDiscardNotice,\n SubIdCollisionError,\n} from \"./runtime-types\";\n\n// Default `onError` sink: re-throw on a fresh macrotask so the failure reaches\n// the host's global error handler instead of vanishing — surface, not swallow\n// (invariant 6).\n//\n// A `RuntimeDiscardNotice` is NOT a failure of the runtime's own contract — a\n// host tearing a runtime down with Cmds in flight (a React ctx-identity change,\n// a navigation) is legal, merely lossy. Rethrowing it would make every\n// unmount-during-fetch an uncaught error for consumers who never configured a\n// sink, so the default WARNS: loud enough that the silent discard #365 describes\n// cannot happen again, never fatal. A configured `onError` sees `\"discard\"` like\n// any other phase and can route or ignore it.\n//\n// The branch keys on the ERROR CLASS, never on `context.phase`: the phase is\n// attached by the report site, and `reportError` hands a THROWING consumer sink's\n// own error back here with the phase it was handling — so a phase-keyed branch\n// would warn away a broken sink and re-create the very silent failure this\n// mechanism exists to remove. The class is the one thing a sink's own defect\n// cannot forge.\nfunction defaultOnError(error: unknown, _context: RuntimeErrorContext): void {\n if (error instanceof RuntimeDiscardNotice) {\n console.warn(error);\n return;\n }\n setTimeout(() => {\n throw error;\n }, 0);\n}\n\n// Normalize `Supervision` (bare string or object) so the dispatch loop branches\n// on `.strategy` once. Default `stop`. Derived from `Supervision` — the object\n// arms are exactly its non-string members, so the restart `rehydrate` payload\n// has a single source of truth.\ntype NormalizedSupervision<S, M extends { type: string }> = Extract<\n Supervision<S, M>,\n object\n>;\n\nfunction normalizeSupervision<S, M extends { type: string }>(\n supervision: Supervision<S, M> | undefined,\n): NormalizedSupervision<S, M> {\n if (supervision === undefined) return { strategy: \"stop\" };\n if (typeof supervision === \"string\") return { strategy: supervision };\n return supervision;\n}\n\n// === liveWork: \"can anything still transition me without a dispatch?\" ===\n//\n// The one read `driveToDone` needs that the public `Runtime` does not carry:\n// after `start`'s chain quiesces on a non-terminal State, only a live Sub or an\n// in-flight Cmd can still enqueue a transition; with neither, waiting is a leak\n// (#68). Module-private and symbol-keyed so it reaches no export (the export map\n// is the contract — MAINTAINING.md), yet enumerable so it survives the spread a\n// wrapper does over the handle.\nconst liveWork: unique symbol = Symbol(\"demlik-tea.liveWork\");\n\n/** The runtime's own sources of a caller-less transition, counted. */\ninterface LiveWork {\n /** Live Subs — manual (`subscriptions`) plus dep-keyed (`subs`). */\n readonly subs: number;\n /** Interpret handlers currently awaiting. */\n readonly cmds: number;\n}\n\ninterface LiveWorkProbe {\n readonly [liveWork]: () => LiveWork;\n}\n\n// === run ===\n//\n// Returns a `BootingRuntime<S, M>` synchronously; boot runs as the FIRST entry\n// on the serial dispatch tail, awaited implicitly by every public method.\n//\n// Save-then-effects ordering is structural: every transition mutates state,\n// awaits `store.save(newState)`, then reconciles subscriptions, then runs\n// `interpret` for emitted cmds, then fires external listeners. A throw in any\n// effect phase leaves the persisted state ahead of the host's belief about\n// what executed — the Railway discipline (`tryInterpret` in handlers) makes\n// that safe in practice.\nexport function run<\n S,\n M extends { type: string },\n C extends Cmd,\n U extends Sub,\n Ctx,\n E extends { type: string } = never,\n>(\n machine: Machine<S, M, C, U, Ctx>,\n // `Ctx & RequiredCtx<C>`: the machine's own ctx PLUS every typed Cmd's `R`\n // (ADR 0014 §3). A machine whose Cmds need `{ http }` cannot be run without\n // it — the missing dependency is a compile error here, not `undefined` in a\n // handler at 3 a.m. `ScopedCtxArg` widens that one field to accept a\n // `provide({ … })` graph in place of the object, and nothing else changes:\n // the requirement is the same type either way, only who builds it differs.\n opts: ScopedCtxArg<Ctx & RequiredCtx<C>> & {\n store?: Store<S>;\n onError?: OnError;\n /**\n * The clock that stamps `at` on a `Cmd.define`d effect's settled Msg at\n * the interpret edge. Defaults to `Date.now`. Inject a fixed one for a\n * deterministic run; a `replay` log carries its own `at`s and never reads\n * this.\n */\n clock?: () => number;\n /**\n * The SEMANTIC event projector. Maps one APPLIED transition `(msg, state)`\n * to zero-or-more public events of `E`; `[]` skips the transition. Maps the\n * machine's PRIVATE Msg vocabulary to NAMED events — the private names never\n * reach `on`'s `E` surface. Omit → `E = never` and `on` is uncallable. PURE.\n */\n events?: (msg: M, state: S) => readonly E[];\n /**\n * Declared policy for a reducer (`update`) throw. Always surfaced via\n * `onError` (`phase: \"reduce\"`); the strategy decides what the runtime does\n * next. Defaults to `\"stop\"`. See `Supervision`.\n */\n supervision?: Supervision<S, M>;\n /**\n * The run-terminality predicate — makes the run's outcome first-class. Fed to\n * `Runtime.result()` and `Runtime.done()`. PURE. Omit → never terminal.\n */\n terminal?: (state: S) => boolean;\n /**\n * How long `stop()` waits for teardown work that returned a Promise (an\n * async `release` in `defineManagedResource`, an async Sub cleanup) before\n * giving up on it. Defaults to 5_000ms.\n *\n * `stop()` awaits those disposals so a host doing\n * `await runtime.stop(); env.evict()` cannot drop the isolate mid-release —\n * the leak the managed-resource battery exists to prevent, relocated to\n * shutdown. The bound is what keeps a release that never settles from\n * hanging the host: on expiry `stop()` reports a `DisposeTimeoutNotice`\n * (warn-only, like every `RuntimeDiscardNotice`) and resolves anyway,\n * because `stop()` resolving is a contract.\n */\n disposeTimeoutMs?: number;\n /**\n * Iteration cap for `idle()`'s quiescence wait. Defaults to 100_000. Test\n * seam only. Production code must not set it.\n *\n * @internal test-only\n */\n __idleCap?: number;\n },\n): BootingRuntime<S, M, E> {\n const { store } = opts;\n // Fencing is a property of the store the caller handed us, never a flag on\n // `run` (#143): a store that can refuse a second writer says so, and this is\n // the one place that decides to use it. `fencedVersion` is the version this\n // run last observed — read at boot, advanced by every accepted save. A save\n // that finds a different version throws `StoreConflictError` out of the store,\n // which is exactly the refusal the loser deserves.\n const fenced = store !== undefined && isFencedStore(store) ? store : null;\n let fencedVersion = 0;\n\n // The read half: take the bytes and remember the version they came at, so the\n // first save can swap against it.\n async function readFenced(from: FencedStore<S>): Promise<unknown> {\n const read = await from.loadFenced();\n fencedVersion = read.version;\n return read.raw;\n }\n\n // The one write path. Every `store.save` in this runtime goes through here so\n // the fenced and unfenced stores cannot drift apart at a call site.\n async function persist(next: S): Promise<void> {\n if (fenced) {\n fencedVersion = await fenced.saveFenced(next, fencedVersion);\n return;\n }\n if (store) await store.save(next);\n }\n // A provider graph (`provide({ … })`) handed as `ctx` is not a `ctx` yet — it\n // is the recipe for one, and every `acquire` may be async. So the graph is set\n // aside here and opened as the FIRST thing boot does; `ctx` stands empty until\n // then, and nothing reads it before boot on this path (see the `pendingInitCmds`\n // guard below).\n const provided = isProvided<Ctx & RequiredCtx<C>>(\n opts.ctx as (Ctx & RequiredCtx<C>) | Provided<Ctx & RequiredCtx<C>>,\n )\n ? (opts.ctx as unknown as Provided<Ctx & RequiredCtx<C>>)\n : null;\n // `ctx` is conditionally optional (see `CtxArg`); default the nullish case to\n // `{}` so the augmented-ctx spread and `init(loaded, ctx)` get a value.\n let ctx = (provided ? {} : (opts.ctx ?? {})) as Ctx & RequiredCtx<C>;\n // The graph's teardown, learned when it opens. `stop()` is the one caller.\n let releaseProvided: (() => Promise<void>) | null = null;\n const clock = opts.clock ?? Date.now;\n const idleCap = opts.__idleCap ?? 100_000;\n const disposeTimeoutMs = opts.disposeTimeoutMs ?? 5_000;\n // No projector → `E = never` and `on` is uncallable.\n const projectEvents: (msg: M, state: S) => readonly E[] =\n opts.events ?? (() => []);\n // No predicate → never terminal (`result()` always `undefined`).\n const isTerminal: (state: S) => boolean = opts.terminal ?? (() => false);\n // Absent sink → `defaultOnError` (invariant 6).\n const onError: OnError = opts.onError ?? defaultOnError;\n // A throwing sink routes THAT throw through `defaultOnError` so it can't\n // re-create a silent failure. It arrives with the context the sink was\n // handling, so `defaultOnError` must not decide fatality from the phase — the\n // sink's own error is not the runtime's teardown notice, whatever phase it\n // inherits.\n const reportError = (error: unknown, context: RuntimeErrorContext): void => {\n try {\n onError(error, context);\n } catch (sinkError) {\n defaultOnError(sinkError, context);\n }\n };\n\n // Throw-isolated fanout: run `fn` for every item, routing any throw to the\n // sink under `phase` so one bad consumer never strands its siblings\n // (invariant 6). The single home for that isolation discipline — every\n // synchronous listener/observer/handler fanout goes through here.\n function fanout<T>(\n items: Iterable<T>,\n phase: RuntimeErrorPhase,\n fn: (item: T) => void,\n ): void {\n for (const item of items) {\n try {\n fn(item);\n } catch (err) {\n reportError(err, { phase });\n }\n }\n }\n const supervision = normalizeSupervision<S, M>(opts.supervision);\n\n // `state` is late-initialized inside the boot step (the head of the tail).\n let state: S | undefined;\n let bootError: unknown = null;\n // The dispatch gate. It only ever ADVANCES — `\"open\"` → `\"draining\"` →\n // `\"closed\"` — so the discard window can never re-open under a second `stop()`.\n //\n // \"open\" — normal operation; `enqueueDispatch` accepts.\n // \"draining\" — inside `stop()`, before the tail has settled. New work is\n // still refused (the stop barrier is absolute, and refusing is\n // what makes the drain terminate), but a Msg refused HERE was\n // discarded BY the teardown: it is an in-flight Cmd's follow-up,\n // a detached handler's terminal Msg, or a Sub that is still live\n // because subs are torn down only after the drain. So the\n // rejection is a `DispatchDiscardedError` and it reports under\n // `phase: \"discard\"` — lossy, legal, warn-only.\n // \"closed\" — halted: a `stop` supervision halt, or `stop()` has returned.\n // A dispatch refused here is a consumer using a runtime it\n // already retired — a real error, and it stays loud.\n let gate: \"open\" | \"draining\" | \"closed\" = \"open\";\n // Interpret handlers currently awaiting — \"how many Cmds are in flight?\".\n // Maintained in `runInterpret` (its only writer) and read by `stop()` to make\n // a mid-flight teardown LOUD instead of silent (issue #365). Not a second\n // representation of the serial `tail`: the tail is a promise chain, which\n // cannot be asked synchronously whether it has outstanding work.\n let inFlightCmds = 0;\n\n const subRegistry = new Map<string, Dispose>();\n // Dep-keyed Sub registry. One slot per `machine.subs[i]`, keyed by the entry's\n // array index (its stable identity across reconciles — a dep-keyed Sub has no\n // author-supplied id). `runningId` is the `structuralHash(deps)` of the live\n // source; an absent slot means the entry is currently inactive (its `deps`\n // returned null). The same dispose-on-change / dispose-on-null machinery the\n // manual Sub path uses, with the id DERIVED instead of author-supplied.\n const depSubRegistry = new Map<\n number,\n { runningId: string; dispose: Dispose }\n >();\n const listeners = new Set<() => void>();\n // Observers get (msg, state) for every APPLIED transition (boot goes via `onBoot`).\n const observers = new Set<(msg: M, state: S) => void>();\n // `booted` lets an `onBoot` handler registered AFTER boot fire immediately.\n const bootHandlers = new Set<(state: S) => void>();\n let booted = false;\n // Keyed by event `type`, stored monomorphically (per-type safety at `on`).\n const eventHandlers = new Map<string, Set<(event: E) => void>>();\n // `done()` waiters — the first terminal transition drains them.\n const doneWaiters = new Set<(state: S) => void>();\n\n // Keyed by Port reference (identity is by-reference per Elm); per-port type\n // safety is enforced at the call sites.\n const portRegistry = new Map<Port<unknown>, Set<(value: unknown) => void>>();\n\n // `emit` injected onto ctx: synchronous fanout, no-op on no subscribers,\n // listener throws isolated + routed to the sink (invariant 6).\n function portEmit<T>(port: Port<T>, value: T): void {\n const subscribers = portRegistry.get(port as Port<unknown>);\n if (!subscribers || subscribers.size === 0) return;\n fanout(subscribers, \"port-emit\", (listener) => listener(value));\n }\n\n // The interpret edge over the typed constructors (`Cmd.define`) this machine\n // declared: parses a handler's `_ok` value and stamps `at`; a pass-through\n // for a machine of hand-written Cmds. Applied to every handler's return in\n // `runInterpret`, and handed to the handlers on ctx so a wrapper that\n // composes a base handler inside its own settles through the same edge.\n const settleAtEdge = cmdEdgeOver(machine.cmds ?? [], clock);\n\n // Copied into a fresh object so handlers get a Ctx & PortEmitter without\n // mutating the caller's ctx (which may be shared across runtimes / tests).\n // `Object.assign`, not a spread: `RequiredCtx<C>` is an intersection tsc\n // cannot prove is an object type while `C` is generic, and a spread refuses it.\n //\n // `let`, and rebuilt at boot on the `provide` path: a provider graph's `ctx`\n // does not exist until its `acquire`s have run, and those are async. The bare\n // path builds it here, unchanged and synchronous.\n let augmentedCtx: Ctx & RequiredCtx<C> & PortEmitter = buildAugmentedCtx();\n\n function buildAugmentedCtx(): Ctx & RequiredCtx<C> & PortEmitter {\n return Object.assign({}, ctx, {\n emit: portEmit,\n [cmdEdge]: settleAtEdge,\n [detachWork]: detachInFlight,\n });\n }\n\n // Every step chains onto `tail` — the single concurrency gate.\n let tail: Promise<void> = Promise.resolve();\n\n // Tear down each named sub: run its cleanup (throws isolated + routed to the\n // sink under `\"sub-cleanup\"`), then drop it from the registry regardless of a\n // cleanup throw. The single home for the cleanup-and-delete discipline shared\n // by `reconcileSubs`'s removal pass and `stop()`.\n function stopSubs(ids: Iterable<string>): void {\n for (const id of ids) {\n const cleanup = subRegistry.get(id);\n if (cleanup === undefined) continue;\n try {\n trackDisposal(cleanup());\n } catch (err) {\n reportError(err, { phase: \"sub-cleanup\" });\n }\n subRegistry.delete(id);\n }\n }\n\n // Teardown work that returned a Promise and has not settled. A cleanup /\n // `Dispose` may be async (`defineManagedResource`'s `release` is typed\n // `void | Promise<void>` precisely so a flush can be awaited), and the\n // reconcile pass CANNOT await it — reconcile runs inside the synchronous\n // transition path (invariant 2). So every async disposal is remembered here\n // the moment it starts, wherever it started, and `stop()` drains the set\n // before resolving: `await runtime.stop()` then means \"teardown is done\", which\n // is the only reading a host evicting an isolate can act on.\n //\n // The rejection is attached HERE, once, so a failing teardown reaches the sink\n // under `\"sub-cleanup\"` (the same phase a synchronous cleanup throw uses)\n // instead of a `console.warn` at each battery, and can never become an\n // unhandled rejection.\n const pendingDisposals = new Set<Promise<void>>();\n\n function trackDisposal(result: void | Promise<void>): void {\n if (!(result instanceof Promise)) return;\n const settling: Promise<void> = result\n .catch((err) => {\n reportError(err, { phase: \"sub-cleanup\" });\n })\n .finally(() => {\n pendingDisposals.delete(settling);\n });\n pendingDisposals.add(settling);\n }\n\n /**\n * Wait for the disposals started so far, bounded by `disposeTimeoutMs`. On\n * expiry report a `DisposeTimeoutNotice` and return anyway — `stop()` resolves\n * regardless (contract), and a release that never settles must not become a\n * host that never shuts down. Warn-only, like every `RuntimeDiscardNotice`:\n * the host asked for this teardown, the loss is legal, and it is now visible.\n */\n async function drainDisposals(): Promise<void> {\n if (pendingDisposals.size === 0) return;\n const outstanding = [...pendingDisposals];\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n const outcome = await Promise.race([\n Promise.all(outstanding).then(() => \"settled\" as const),\n new Promise<\"timeout\">((resolve) => {\n timer = setTimeout(() => resolve(\"timeout\"), disposeTimeoutMs);\n }),\n ]);\n if (outcome === \"timeout\") {\n reportError(\n new DisposeTimeoutNotice(outstanding.length, disposeTimeoutMs),\n { phase: \"discard\" },\n );\n }\n } finally {\n if (timer !== undefined) clearTimeout(timer);\n }\n }\n\n // Dispose each named dep-keyed slot: run its `Dispose` (throws isolated +\n // routed to the sink under `\"sub-cleanup\"`, exactly as `stopSubs` does for the\n // manual path), then drop the slot regardless of a throw. The single home for\n // the dispose-and-delete discipline shared by `reconcileDepSubs`'s teardown /\n // re-arm passes and `stop()`.\n function disposeDepSubs(indices: Iterable<number>): void {\n for (const index of indices) {\n const running = depSubRegistry.get(index);\n if (running === undefined) continue;\n try {\n trackDisposal(running.dispose());\n } catch (err) {\n reportError(err, { phase: \"sub-cleanup\" });\n }\n depSubRegistry.delete(index);\n }\n }\n\n /**\n * Reconcile the dep-keyed Subs (`machine.subs`) against `state`. Runs as the\n * first pass of `reconcileSubs`, sharing the dispose-on-change /\n * dispose-on-null machinery with the manual Sub path. For each entry:\n *\n * - `deps(state)` is nullish (`depsInactive`) → the Sub is inactive in this\n * state; dispose it if it was running.\n * - otherwise → `id = structuralHash(deps)`; if no source is running for\n * this entry, or the running id differs (re-arm), dispose the old source\n * and run `source(state, dispatch, ctx)` to open a fresh one (the entry\n * re-derives its own typed slice from `state`).\n * - Unchanged id → leave the source running (the no-churn case).\n *\n * Throws are collected and returned rather than thrown here (same contract as\n * the manual path) so one bad entry doesn't strand the others. That covers\n * `deps` and the hash, not just `source`: `deps` is user code on exactly the\n * same footing, and an unguarded throw there stranded every LATER entry AND\n * the manual `subscriptions` aggregate, which is only reached after this loop.\n * A machine that declares no `subs` returns immediately — the pass is inert.\n */\n function reconcileDepSubs(): unknown {\n let firstError: unknown = null;\n const subs = machine.subs;\n if (!subs) return firstError;\n for (const [i, entry] of subs.entries()) {\n // `deps` + `structuralHash` in ONE guarded step: both are pure user-data\n // reads whose failure means \"this entry's slice is unknowable\", and the\n // recovery is identical — remember the error, leave the slot untouched,\n // keep reconciling the siblings.\n let deps: unknown;\n let id: string;\n try {\n deps = entry.deps(state as S);\n if (depsInactive(deps)) {\n // Inactive in this state — tear down if running.\n disposeDepSubs([i]);\n continue;\n }\n id = structuralHash(deps);\n } catch (err) {\n if (firstError === null) firstError = err;\n continue;\n }\n\n const running = depSubRegistry.get(i);\n if (running !== undefined && running.runningId === id) {\n // No-churn case: same deps → leave the source running.\n continue;\n }\n // Re-arm (id changed) or first arm — dispose the stale source first.\n disposeDepSubs([i]);\n try {\n // `dispatchUnawaited`, never the raw `enqueueDispatch`: a source's\n // dispatch has no caller to reject at, and the gate rejects during\n // teardown — handing it the raw promise-returning form turned every\n // Sub that fired while `stop()` drained into an unhandled rejection\n // that bypassed `onError` entirely.\n const dispose = entry.source(state as S, dispatchUnawaited, ctx);\n depSubRegistry.set(i, { runningId: id, dispose });\n } catch (err) {\n if (firstError === null) firstError = err;\n // Do NOT register; continue so other dep-keyed sources still arm.\n }\n }\n return firstError;\n }\n\n /**\n * Reconcile subscriptions against `state`, after every save. Same id old+new →\n * leave running; removed id → cleanup (throws isolated, routed to the sink);\n * new id → start (throw remembered and re-thrown after the loop so all other\n * new subs still register).\n */\n function reconcileSubs(): void {\n // Dep-keyed pass FIRST, then the manual aggregate — ONE reconcile pass over\n // both paths. Its start error is remembered (it happened first) and thrown\n // after the manual pass so a bad dep-keyed source never strands the manual\n // subs, and vice versa.\n const depError = reconcileDepSubs();\n if (!machine.subscriptions) {\n if (depError !== null) throw depError;\n return;\n }\n const desired = machine.subscriptions(state as S);\n const desiredIds = new Set<string>();\n\n // Collision assert: within one desired set, two subs sharing an id but\n // declaring different types is a silent bug class. (Same id across\n // transitions is the no-churn case and MUST NOT throw.)\n const desiredTypeById = new Map<string, string>();\n for (const sub of desired) {\n const existing = desiredTypeById.get(sub.id);\n if (existing !== undefined && existing !== sub.type) {\n throw new SubIdCollisionError(sub.id, existing, sub.type);\n }\n desiredTypeById.set(sub.id, sub.type);\n }\n\n // Removals first — anything in the registry not in `desired` should stop.\n for (const sub of desired) desiredIds.add(sub.id);\n stopSubs([...subRegistry.keys()].filter((id) => !desiredIds.has(id)));\n\n // Additions — anything in `desired` not in the registry should start.\n let firstStartError: unknown = depError;\n for (const sub of desired) {\n if (subRegistry.has(sub.id)) continue;\n const handler = machine.subscribe?.[sub.type as U[\"type\"]];\n if (!handler) {\n // No handler for this sub type — programmer error; skip.\n continue;\n }\n try {\n // Same reasoning as the dep-keyed source above: a subscribe handler's\n // dispatch is unawaited by construction, so it gets the wrapped form.\n const cleanup = handler(\n sub as Extract<U, { type: U[\"type\"] }>,\n ctx,\n dispatchUnawaited,\n );\n subRegistry.set(sub.id, cleanup);\n } catch (err) {\n if (firstStartError === null) firstStartError = err;\n // Do NOT register; continue to next sub so other starts still run.\n }\n }\n if (firstStartError !== null) throw firstStartError;\n }\n\n // `interpret` is optional when `C extends Cmd<never>`; default a missing map to\n // `{}` — the per-cmd `if (!handler) continue` preserves invariant-6 forward\n // progress for a miswired consumer.\n const interpretMap: Interpret<M, C, Ctx> =\n (machine as { interpret?: Interpret<M, C, Ctx> }).interpret ??\n ({} as Interpret<M, C, Ctx>);\n\n // The ONE `(msg) => void` handed to every producer that cannot await its own\n // dispatch: a detached interpret handler's `ctx.waitUntil(...)` tail, a\n // dep-keyed Sub's `source`, a `subscribe[type]` handler. Same serial-tail\n // enqueue every other dispatch uses (`enqueueDispatch` chains on `tail`),\n // wrapped so the rejection — which has no caller, the original dispatcher\n // having already resolved — routes to the sink with the phase DERIVED from\n // the error class (`reportUndelivered`).\n //\n // Handing any of those sites the raw `enqueueDispatch` is the defect this\n // shape exists to prevent: its promise REJECTS whenever the gate is shut, so\n // a Sub that fires during `stop()`'s drain produced an unhandled rejection\n // that reached the host's global handler while `onError` saw nothing. A\n // handler authored via `wrapDetached` receives a NARROWED view of this fn\n // (only its declared result-Msg set); a plain leaf handler ignores it.\n const dispatchUnawaited = (msg: M): void => {\n enqueueDispatch(msg).catch(reportUndelivered);\n };\n\n /**\n * Report a re-dispatch that nobody can await. The phase is DERIVED from the\n * rejection the gate produced, so the two call sites cannot drift: a\n * `DispatchDiscardedError` means the teardown refused the Msg (`\"discard\"` —\n * warn-only), anything else is a genuine failure of the follow-up itself\n * (`\"follow-up\"` — the default sink rethrows it).\n */\n function reportUndelivered(error: unknown): void {\n reportError(error, {\n phase: error instanceof DispatchDiscardedError ? \"discard\" : \"follow-up\",\n });\n }\n\n /**\n * Count an interpret handler's work as in flight for exactly the lifetime of\n * its promise. The ONE writer of `inFlightCmds`, so \"how many Cmds are\n * outstanding?\" has a single definition; `finally`-balanced, so a rejecting\n * handler can never strand the count above zero. A handler that throws\n * SYNCHRONOUSLY never reaches here, which is correct — it was never in\n * flight.\n */\n function trackInFlight<T>(work: T | Promise<T>): Promise<T> {\n inFlightCmds++;\n return Promise.resolve(work).finally(() => {\n inFlightCmds--;\n });\n }\n\n /**\n * Enlist work a handler will NOT return — the `detachWork` seam on ctx.\n *\n * A handler that fans out inside its own Cmd (ADR 0018) returns before its\n * effect finishes, so the promise `trackInFlight` would have counted never\n * reaches `runInterpret`. Handing it here puts it back on BOTH accountings a\n * returned promise had: `trackInFlight`, so `stop()` still reports it as\n * discarded work, and the serial `tail`, so `idle()` drains it rather than\n * calling a run with tools still running quiescent. The tail extension is\n * SYNCHRONOUS, so a `drainToQuiescence` that has already read `tail` sees the\n * reference change and loops again.\n *\n * This is not a second interpret loop and it interleaves nothing:\n * `runInterpret` still runs one handler at a time. It only re-attaches a\n * promise the handler chose to outlive.\n */\n function detachInFlight(work: Promise<unknown>): void {\n const tracked = trackInFlight(work);\n // The rejection has no caller — the handler returned already — so it routes\n // to the sink exactly as an un-awaitable follow-up's does.\n tracked.catch(reportUndelivered);\n tail = tail\n .then(async () => {\n await tracked;\n })\n .catch(() => {});\n }\n\n /**\n * Run `interpret` for each emitted cmd. A returned follow-up Msg is enqueued\n * onto the tail (NOT dispatched re-entrantly). The first error stops further\n * handlers in this transition.\n *\n * THIS LOOP IS SERIAL BY RULING, NOT BY OVERSIGHT (ADR 0018). It interprets a\n * transition's Cmds one at a time and never interleaves two handlers, so the\n * Msgs it enqueues fold in Cmd-EMISSION order and a replayed log reproduces\n * the same fold — invariant 2's serializability, which time-travel and\n * durable replay are built on. Making this concurrent was proposed (#163,\n * because `toolConcurrency` reads like a parallelism knob) and REJECTED:\n * overlap here would fold settle Msgs in completion order and re-specify\n * first-error semantics and `inFlightCmds` for every machine, including the\n * consumers who never asked for it. Wall-clock overlap belongs INSIDE one\n * Cmd's handler — fan out there, settle one Msg per item through this edge —\n * never across the Cmds of one transition.\n */\n async function runInterpret(cmds: readonly C[]): Promise<void> {\n for (const cmd of cmds) {\n const handler = interpretMap[cmd.type as C[\"type\"]];\n if (!handler) continue;\n const returned = await trackInFlight(\n handler(\n cmd as Extract<C, { type: C[\"type\"] }>,\n // The handler's cell demands `Ctx & RequirementsOf<its Cmd>`; the runtime\n // holds `Ctx & RequiredCtx<C>` — the intersection over EVERY Cmd, so\n // a superset of any one cell's slice. The widening is sound by\n // construction; `tsc` cannot see through the generic `C` to prove it.\n augmentedCtx as Parameters<typeof handler>[1],\n dispatchUnawaited,\n ),\n );\n const follow = settleAtEdge(cmd, returned);\n if (follow !== undefined && follow !== null) {\n // The follow-up's rejection has no caller (the original dispatcher\n // resolved), so route it to the sink (invariant 6); name a failure Msg\n // via `tryInterpret` to fold it back into state.\n enqueueDispatch(follow as M).catch(reportUndelivered);\n }\n }\n }\n\n // Throws isolated so one bad listener does not strand the others.\n function fireListeners(): void {\n fanout(listeners, \"listener\", (listener) => listener());\n }\n\n // After `fireListeners` so observers see what subscribers see. APPLIED\n // transitions only — `msg` is total (boot routes to `fireBoot`).\n function fireObservers(msg: M): void {\n if (observers.size === 0 || state === undefined) return;\n const snapshot = state;\n fanout(observers, \"observer\", (observer) => observer(msg, snapshot));\n }\n\n // Project the transition to semantic events and fan each to its `on(...)`\n // handlers; a throw in the projector OR a handler is isolated.\n function fireEvents(msg: M): void {\n if (eventHandlers.size === 0 || state === undefined) return;\n let events: readonly E[];\n try {\n events = projectEvents(msg, state);\n } catch (err) {\n reportError(err, { phase: \"event\" });\n return;\n }\n for (const event of events) {\n const bucket = eventHandlers.get(event.type);\n if (bucket === undefined) continue;\n fanout(bucket, \"event\", (handler) => handler(event));\n }\n }\n\n // Fire every `onBoot` handler with the initial State ONCE and flip `booted`.\n function fireBoot(): void {\n booted = true;\n if (bootHandlers.size === 0 || state === undefined) return;\n const snapshot = state;\n fanout(bootHandlers, \"boot\", (handler) => handler(snapshot));\n }\n\n // Resolve every parked `done()` waiter iff the just-folded State is terminal —\n // so `done()` settles on the same transition `result()` first returns it.\n function settleDoneWaiters(): void {\n if (doneWaiters.size === 0 || state === undefined) return;\n if (!isTerminal(state)) return;\n const snapshot = state;\n const parked = [...doneWaiters];\n doneWaiters.clear();\n for (const resolve of parked) resolve(snapshot);\n }\n\n // The post-transition commit tail: install state, then save → reconcile subs →\n // interpret → fire fanout → settle done-waiters. Save-before-effects is the\n // hard ordering; tests pin it. The normal transition and the `restart`\n // supervision branch both end here.\n async function commit(next: S, msg: M, cmds: readonly C[]): Promise<void> {\n state = next;\n await persist(next);\n reconcileSubs();\n await runInterpret(cmds);\n fireListeners();\n fireObservers(msg);\n fireEvents(msg);\n settleDoneWaiters();\n }\n\n /**\n * Instance-identity filter: is this message addressed to a DIFFERENT instance\n * than the one this state owns? When the machine declares an `identity`, a\n * `true` here drops the message before `update` runs, so the reducer never\n * sees a foreign-instance message and no cell needs a\n * `msg.runId !== state.runId` guard.\n *\n * A message with no identity (`ofMsg` → undefined) is identity-agnostic and\n * always proceeds. `ofState` → undefined means this instance has no identity\n * to defend yet (an `idle` state before any run is established), so an\n * addressed message there is identity-ESTABLISHING, not foreign. Drop only\n * when both identities are present and differ.\n *\n * Pure and synchronous; a throw is the caller's to supervise (see\n * `stepDispatch`).\n */\n function isMisaddressed(msg: M, current: S): boolean {\n if (machine.identity === undefined) return false;\n const addressed = machine.identity.ofMsg(msg);\n if (addressed === undefined) return false;\n const own = machine.identity.ofState(current);\n if (own === undefined) return false;\n return structuralHash(addressed) !== structuralHash(own);\n }\n\n /**\n * One full transition: update → save → reconcile subs → interpret → fire.\n * Save-before-effects is the hard ordering; tests pin it. A `save` throw\n * propagates after the in-memory `state` is advanced; reconcile/interpret\n * throws after `save` has succeeded.\n */\n async function stepDispatch(msg: M): Promise<void> {\n if (state === undefined) {\n throw new Error(\"@demlik/tea: runtime not booted\");\n }\n // The identity filter and the reducer are ONE synchronous user-code step,\n // and they are protected as one. The projections used to run above this\n // `try`, so a throwing `ofMsg` / `ofState` was neither reported nor\n // supervised while an identical throw one line later was both — and since\n // `structuralHash` throws on a bigint or a non-plain value, a snowflake-style\n // run id put EVERY dispatch on that unprotected path.\n //\n // The reentrancy brand guarantees this whole step cannot suspend, so a throw\n // here is clean with `state` still pre-transition; it routes to the declared\n // supervision strategy under `phase: \"reduce\"` — the transition's own\n // synchronous code failed, whichever half of it that was. Folding goes\n // through `applyCellChecked` — the single dev-checked\n // reducer-vs-transitions primitive `foldUpdates` also folds through (see\n // `pure/core.ts`).\n let next: S;\n let cmds: readonly C[];\n try {\n if (isMisaddressed(msg, state)) {\n // The drop advances nothing: no save, no reconcile, no interpret, no\n // listener/observer/event fire, no done-waiter settle — and it RESOLVES\n // the dispatch, because a mis-addressed message is not the caller's\n // error. That is exactly why it must be reported: without this the\n // caller cannot tell \"applied\" from \"silently discarded\", and a reusable\n // Durable Object serving run A then run B lost run B while reporting\n // success. `IdentityDropNotice` is a `RuntimeDiscardNotice` — warn by\n // default, never fatal (invariant 6: the enforcement point is\n // observable, which is what makes it ONE point).\n reportError(new IdentityDropNotice(msg.type), {\n phase: \"identity-drop\",\n });\n return;\n }\n [next, cmds] = applyCellChecked<S, M, C>(machine, state, msg);\n } catch (reduceError) {\n // Invariant 6 — surface the failure as data FIRST, for every strategy.\n reportError(reduceError, { phase: \"reduce\" });\n switch (supervision.strategy) {\n case \"restart\": {\n // Host supplies last-known-good state; core installs it and KEEPS\n // FOLDING from there with no cmds (the throwing reduce produced none).\n // A throw inside `rehydrate` is NOT caught — it surfaces to the caller.\n await commit(supervision.rehydrate(state, msg, reduceError), msg, []);\n return;\n }\n case \"escalate\":\n // Surface + propagate; the runtime stays live for a parent supervisor.\n throw reduceError;\n default:\n // `stop` (safe default): halt. State is NOT advanced; propagate so THIS\n // dispatch also rejects — the halt is observable, never a silent resume.\n gate = \"closed\";\n throw reduceError;\n }\n }\n await commit(next, msg, cmds);\n }\n\n // Boot has two phases. With NO store, `loaded = null` without an await — run\n // `init(null, ctx)` IMMEDIATELY so `getState()` is observable synchronously\n // (what `useSyncExternalStore` consumers need to render the first commit\n // without a flicker). The async remainder runs in `stepBootEffects` as the\n // first tail entry. With a store we cannot `init` synchronously (we'd invent a\n // loaded value), so the full path runs there; `store.load` throws propagate\n // via the boot promise.\n //\n // A provider graph defers that synchronous init too: `init` reads `ctx`, and\n // on this path `ctx` does not exist until the graph has been acquired. Nothing\n // is lost — `getState()` lives on `Runtime`, which is only reachable through\n // `await ready`, so a deferred init is invisible at the type level.\n let pendingInitCmds: readonly C[] = [];\n if (!store && !provided) {\n const [initialState, initCmds] = machine.init(null, ctx);\n state = initialState;\n pendingInitCmds = initCmds;\n }\n\n async function stepBootEffects(): Promise<void> {\n if (provided) {\n // Acquire the whole graph before anything can read `ctx`. A failure has\n // already unwound whatever it acquired (see `provide`) and arrives as a\n // typed `ProvideFailedError` — reported under `\"provide\"` so a host with a\n // sink sees it, then rethrown so it rejects `ready` like any boot failure\n // rather than escaping as an uncaught throw.\n let scope: Scope<Ctx & RequiredCtx<C>>;\n try {\n scope = await provided.open((error, provider) => {\n reportError(error, { phase: \"provide\", provider });\n });\n } catch (error) {\n reportError(error, { phase: \"provide\" });\n throw error;\n }\n ctx = scope.ctx;\n releaseProvided = scope.release;\n augmentedCtx = buildAugmentedCtx();\n if (!store) {\n const [initialState, initCmds] = machine.init(null, ctx);\n state = initialState;\n pendingInitCmds = initCmds;\n }\n }\n // The graph is acquired from here on, so every remaining boot step is inside\n // its lifetime — a `store.load` / `migrate` / interpret throw releases it\n // before rejecting `ready`, exactly as `open()` unwinds its own acquire half.\n // Otherwise a host that awaits `ready` and rethrows (the shape\n // `docs/how-to/scope-a-resource-across-a-run.md` §3 shows) leaks every\n // provider until someone calls `stop()`. `releaseAll` is idempotent, so the\n // `stop()` that follows such a rejection is a no-op, never a double release.\n try {\n await bootAfterProvide();\n } catch (error) {\n if (releaseProvided) await releaseProvided();\n throw error;\n }\n }\n\n async function bootAfterProvide(): Promise<void> {\n if (store) {\n // Boundary parse (invariant 8): `store.load()` returns `unknown`;\n // `store.migrate(raw)` is the required parse — `S` on recognized shape,\n // `null` on unrecognized (boots fresh). `migrate` MUST NOT throw; if it\n // does we surface via the boot promise (same as a `load` throw).\n // A fenced store reads its version in the same breath as its bytes, and\n // the boot save below is a compare-and-swap like every other. Note which\n // run loses: reading here means a LATER starter reads the current version\n // and swaps cleanly, so it takes the fence and the older live writer is\n // refused at ITS next save. Only a true race — both booting off the same\n // version before either wrote — is refused HERE, before any effect fires.\n const raw = fenced ? await readFenced(fenced) : await store.load();\n const parsed = store.migrate(raw);\n const [initialState, initCmds] = machine.init(parsed, ctx);\n state = initialState;\n pendingInitCmds = initCmds;\n await persist(state);\n }\n reconcileSubs();\n await runInterpret(pendingInitCmds);\n fireListeners();\n // Boot has no applied Msg — deliver the initial State via `onBoot`, not\n // `observe`, and project no semantic event.\n fireBoot();\n // A rehydrated boot can land terminal — settle any pre-boot `done()` waiter.\n settleDoneWaiters();\n }\n\n /**\n * Enqueue a dispatch on the tail — the single gate re-entrant interpret /\n * subscribe calls also go through. Rejects when the gate is not open (with a\n * `DispatchDiscardedError` while `stop()` drains, a plain stopped Error once it\n * has), boot failed, or the reducer / save / sub start / interpret throws.\n */\n function enqueueDispatch(msg: M): Promise<void> {\n if (gate !== \"open\") {\n // The gate's state at refusal time IS the classification — the report\n // sites read the error class, never the message.\n return Promise.reject(\n gate === \"draining\"\n ? new DispatchDiscardedError(msg.type)\n : new Error(\"@demlik/tea: runtime stopped\"),\n );\n }\n const next = tail.then(() => {\n if (bootError !== null) throw bootError;\n return stepDispatch(msg);\n });\n // Swallow the rejection on the tail so one failing dispatch does NOT poison\n // every subsequent one. The original `next` still rejects for the caller.\n tail = next.catch(() => {});\n return next;\n }\n\n /**\n * Drain the serial tail to quiescence. Every interpret follow-up calls\n * `enqueueDispatch`, which reassigns `tail` SYNCHRONOUSLY before the parent\n * step resolves, so awaiting the current `tail` and re-reading it catches every\n * transitively enqueued follow-up; loop until the reference is stable. Bounded\n * by `idleCap` — on cap REJECT with `QuiescenceTimeoutError` (never a silent\n * resolve), keeping a livelock distinguishable from quiescence (invariant 6).\n */\n async function drainToQuiescence(): Promise<void> {\n for (let i = 0; i < idleCap; i++) {\n const observed = tail;\n await observed;\n if (tail === observed) return;\n }\n throw new QuiescenceTimeoutError(idleCap);\n }\n\n /**\n * The public `dispatch`: run-to-quiescence by default. Await the Msg's OWN\n * transition first (so a reducer / save / interpret throw on THIS Msg surfaces\n * before any drain), then — unless `{ settle: \"once\" }` — drain the transitive\n * follow-up chain.\n */\n async function dispatchToQuiescence(\n msg: M,\n opts?: { readonly settle?: DispatchSettle },\n ): Promise<void> {\n await enqueueDispatch(msg);\n if (opts?.settle === \"once\") return;\n await drainToQuiescence();\n }\n\n // `bootPromise` is the un-swallowed promise `runtime.ready` chains off (so\n // callers see the boot error directly); `tail` gets the swallowed branch so a\n // boot failure does NOT poison every subsequent dispatch's chain (each surfaces\n // `bootError` in `enqueueDispatch`).\n const bootPromise = stepBootEffects();\n tail = bootPromise.catch((err) => {\n bootError = err;\n });\n\n // `ready` chains off `bootPromise` so a failed boot never hands out a `Runtime`\n // (keeping `getState()` total). The `runtime` forward reference resolves at\n // `.then` time, after the literal below initializes. Idempotent.\n const readyPromise: Promise<Runtime<S, M, E>> = bootPromise.then(\n () => runtime,\n );\n\n const runtime: Runtime<S, M, E> & LiveWorkProbe = {\n [liveWork]: () => ({\n subs: subRegistry.size + depSubRegistry.size,\n cmds: inFlightCmds,\n }),\n dispatch: dispatchToQuiescence,\n dispatchOnce: enqueueDispatch,\n getState(): S {\n // TOTAL. A `Runtime` is only obtainable by awaiting `ready`, which resolves\n // AFTER boot set `state`; a failed boot rejects `ready`, so no `Runtime` is\n // handed out then. The cast encodes that invariant.\n return state as S;\n },\n subscribe(listener: () => void): () => void {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n observe(observer: (msg: M, state: S) => void): () => void {\n observers.add(observer);\n return () => {\n observers.delete(observer);\n };\n },\n onBoot(handler: (state: S) => void): () => void {\n // Already booted → fire immediately (cleanup is a no-op) so a late\n // subscriber never misses the one-shot boot.\n if (booted && state !== undefined) {\n const snapshot = state;\n fanout([handler], \"boot\", (h) => h(snapshot));\n return () => {};\n }\n bootHandlers.add(handler);\n return () => {\n bootHandlers.delete(handler);\n };\n },\n on<K extends E[\"type\"]>(\n type: K,\n handler: (event: Extract<E, { type: K }>) => void,\n ): () => void {\n // Monomorphic registry; per-type narrowing lives at THIS call site, and\n // `fireEvents` only routes an event to its own bucket, so the erased call\n // is sound.\n let bucket = eventHandlers.get(type);\n if (bucket === undefined) {\n bucket = new Set<(event: E) => void>();\n eventHandlers.set(type, bucket);\n }\n const erased = handler as (event: E) => void;\n bucket.add(erased);\n return () => {\n const set = eventHandlers.get(type);\n if (set === undefined) return;\n set.delete(erased);\n if (set.size === 0) eventHandlers.delete(type);\n };\n },\n subscribePort<T>(port: Port<T>, listener: (value: T) => void): () => void {\n const key = port as Port<unknown>;\n let bucket = portRegistry.get(key);\n if (!bucket) {\n bucket = new Set<(value: unknown) => void>();\n portRegistry.set(key, bucket);\n }\n // Bucket stores `(value: unknown) => void`; per-port type safety at this site.\n const erased = listener as (value: unknown) => void;\n bucket.add(erased);\n return () => {\n const set = portRegistry.get(key);\n if (!set) return;\n set.delete(erased);\n if (set.size === 0) portRegistry.delete(key);\n };\n },\n emitPort<T>(port: Port<T>, value: T): void {\n // Lets `observe`-driven Port emission work without a per-transition Cmd.\n portEmit(port, value);\n },\n ready: readyPromise,\n idle(): Promise<void> {\n return drainToQuiescence();\n },\n result(): S | undefined {\n // TOTAL. No predicate → `isTerminal` is `() => false`, so a non-terminating\n // machine reads `undefined` forever.\n const current = state as S;\n return isTerminal(current) ? current : undefined;\n },\n done(): Promise<S> {\n // Already terminal → resolve at once (never parks, so it can't miss the\n // terminal transition). Otherwise park a resolver for `settleDoneWaiters`.\n const current = state as S;\n if (isTerminal(current)) return Promise.resolve(current);\n return new Promise<S>((resolve) => {\n doneWaiters.add(resolve);\n });\n },\n async stop(): Promise<void> {\n // Open the discard window unless the gate is already `\"closed\"` (a\n // supervision halt, or a redundant second `stop()`): the gate only\n // advances, so a Msg refused after a halt or after `stop()` returned stays\n // a loud error rather than being re-labelled a teardown discard.\n if (gate === \"open\") gate = \"draining\";\n // Report BEFORE the drain: after `await tail` the count is zero by\n // construction, and the fact worth surfacing is what was outstanding at\n // the moment the host let go. `stop()` drains, but every consumer of the\n // resulting transitions (listeners, observers, event handlers) is being\n // torn down with it, so those Cmds' results reach nobody (issue #365).\n if (inFlightCmds > 0) {\n reportError(new RuntimeDiscardedError(inFlightCmds), {\n phase: \"discard\",\n });\n }\n // Drain in-flight work. Tail rejections were swallowed at enqueue time, so\n // this await always resolves. The drain TERMINATES because the gate refuses\n // the follow-ups those handlers return — allowing them in instead would let\n // a handler chain extend the tail without end.\n await tail;\n // The barrier is now absolute: everything that was in flight has settled,\n // so a dispatch from here on is a consumer using a retired runtime.\n gate = \"closed\";\n // Run every active sub cleanup; throws isolated and routed to the sink.\n stopSubs([...subRegistry.keys()]);\n // Dispose every live dep-keyed source too (same throw-isolation).\n disposeDepSubs([...depSubRegistry.keys()]);\n // …then WAIT for the teardown work that is still settling — the ones\n // above, plus any async cleanup a mid-run reconcile started. `stop()`\n // resolving has to mean \"teardown is done\", or a host doing\n // `await stop(); env.evict()` drops the isolate mid-release and re-creates\n // the exact leak the managed-resource battery exists to prevent. Bounded\n // by `disposeTimeoutMs` so a release that never settles cannot hold the\n // host open (see `drainDisposals`).\n await drainDisposals();\n // Flush final state. A save throw here does not reject `stop()` (contract:\n // resolves regardless) but IS loss of the last write, so route it to the\n // sink rather than swallowing it (invariant 6).\n if (store && state !== undefined && bootError === null) {\n try {\n await persist(state);\n } catch (error) {\n reportError(error, { phase: \"stop-save\" });\n }\n }\n // LAST: release the provider graph. Every terminal a run has funnels\n // through here — `driveToDone` calls `stop()` in a `finally`, so done,\n // failed and cancelled all reach it — and it runs after the final save\n // because a provider may be the very thing that save wrote through.\n // Idempotent inside the scope, so a second `stop()` cannot double-free.\n if (releaseProvided) await releaseProvided();\n },\n };\n\n return runtime;\n}\n\n/**\n * Is the runtime provably out of ways to transition on its own? True only when\n * the handle carries the `liveWork` read and it counts zero live Subs and zero\n * in-flight Cmds. A handle without the read (a wrapper that rebuilt the object\n * without spreading it) cannot be proven stalled, so the drive keeps waiting —\n * the pre-#68 contract, never a false stall.\n */\nfunction isStalled(runtime: object): boolean {\n const probe = (runtime as Partial<LiveWorkProbe>)[liveWork];\n if (probe === undefined) return false;\n const live = probe();\n return live.subs === 0 && live.cmds === 0;\n}\n\n/**\n * The outside-in stop, as a PAIR. A signal is only cancellation if something can\n * turn \"aborted\" into a transition this machine understands, and the kernel has\n * no built-in cancel Msg any more than it has a built-in terminal set — so the\n * `signal` and the `cancel` that reads it are one option, present together or\n * absent together. A discriminated union rather than two optional fields, on the\n * same reasoning as `AgentCompactionConfig`: a signal with no `cancel` is a stop\n * button wired to nothing, and that is a state worth making unrepresentable\n * rather than checking for.\n */\ntype DriveCancellation<S, M> =\n | {\n readonly signal?: undefined;\n readonly cancel?: undefined;\n }\n | {\n /**\n * Abort the run through this signal. On abort the drive dispatches\n * `cancel`'s Msg and resolves on the State that lands — it does NOT reject,\n * and a cancellation is never a `DriveFailedError`. Already aborted when\n * the drive is called → the cancel Msg goes in place of `start`, so the\n * run ends without the start's effects ever firing.\n */\n readonly signal: AbortSignal;\n /**\n * The Msg that settles this machine as cancelled, chosen off the current\n * State exactly as `start` is. PURE. It must land a State `isTerminal`\n * holds for — the drive resolves on the terminal predicate, not on the\n * abort — and that State should be DURABLE, or a reload resumes the run\n * its caller stopped.\n */\n readonly cancel: (state: S) => M;\n };\n\n/** Options for `driveToDone`. */\nexport type DriveToDoneOptions<\n S,\n M extends { type: string } = never,\n> = DriveCancellation<S, M> & {\n /**\n * Marks a terminal State as a FAILURE. A State this holds for ends the drive\n * like any terminal one — the runtime is stopped — but the drive REJECTS with\n * `DriveFailedError` carrying it instead of resolving. A failed State is\n * terminal by definition; it need not also satisfy `isTerminal`. Omit → the\n * drive never rejects on State, only on a runtime error.\n */\n readonly failed?: (state: S) => boolean;\n};\n\n/**\n * Drive a machine from `start` to its terminal State in one call, then tear the\n * runtime down. The one-shot shape every \"run this machine to done\" test and\n * caller boundary otherwise hand-wires as six steps — `await ready`, `observe`,\n * park a promise, `dispatch(start)`, `getState()`, `stop()` — with the observer\n * leak and the forgotten `stop` those six steps invite.\n *\n * Takes the handle `run()` returns (a `Runtime` extends it, so a booted one is\n * accepted too), awaits `ready`, dispatches `start`, and resolves with the first\n * State for which `isTerminal` holds. A machine that boots already terminal (a\n * rehydrated finished run) resolves on its boot State and `start` is never\n * dispatched — a finished run has nothing to set in motion. `start` may be a\n * function of the boot State instead of a Msg: a machine rehydrated MID-run\n * needs its resume Msg, not its start Msg, and only the boot State says which\n * (the agent's `agent_boot` vs `agent_start` is the case in point). The\n * observer is detached and `stop()` awaited on EVERY exit: resolve, `failed`,\n * a stall, a boot or dispatch throw, the quiescence cap.\n *\n * Rejections are typed, never silent:\n * - `DriveFailedError<S>` when `opts.failed` marks the final State — the State\n * rides on `error.state`.\n * - `DriveStalledError<S>` when `start`'s follow-up chain quiesces on a State\n * that is neither terminal nor `failed` and the runtime has no live Sub and\n * no Cmd in flight — nothing inside it can deliver another transition, so\n * waiting would be a hang with the runtime leaked. The stalled State rides\n * on `error.state`. A machine that CAN still move is not stalled: a live Sub\n * (manual or dep-keyed) that delivers the terminal Msg after the dispatch\n * quiesces keeps the drive waiting, and it resolves on that State. What the\n * runtime cannot see — a dispatch from outside it after quiescence — does\n * not count as live; a machine that depends on one declares it as a Sub.\n * - `QuiescenceTimeoutError` when `start`'s follow-up chain never settles —\n * the SAME cap `dispatch` and `idle()` already reject on (invariant 6), not a\n * second clock. A livelocking machine surfaces as its own failure class.\n * - the boot error, or whatever `dispatch(start)` rejects with, otherwise.\n *\n * `isTerminal` is caller-supplied, exactly as `run()`'s `terminal` option is —\n * the kernel has no built-in terminal-set concept and this does not add one.\n *\n * Cancellation is the same story: `{ signal, cancel }` stops the drive from\n * outside, and it settles the run rather than escaping it. On abort the drive\n * dispatches `cancel`'s Msg and RESOLVES on the terminal State that transition\n * lands — no rejection, no `DriveFailedError`, no `AbortError`. That is the whole\n * point of routing a stop through the Model: the outcome is durable, so a killed\n * process resumes reading a run that ended instead of restarting one someone\n * stopped. A cancel that THROWS is the one abort that rejects: it lands\n * no State, so its error is what the drive has to report — and that holds\n * whether the `cancel` function throws synchronously or the fold it produced\n * throws later, since both leave the run with no State to settle on. A State the\n * caller's `failed` predicate marks rejects on an abort exit exactly as it does\n * anywhere else. In-flight effects are not recalled — a promise cannot be cancelled —\n * so they settle to their own end and `stop()` drains them as it always did;\n * keeping their results off the public channels is the machine's own business.\n * Omit the pair and every path here behaves exactly as it did before.\n *\n * @param handle the handle `run(machine, opts)` returned.\n * @param start the Msg that sets the run in motion, or a function choosing\n * it off the boot State. PURE.\n * @param isTerminal the terminal predicate over the machine's State. PURE.\n * @param opts an optional `failed` predicate and an optional\n * `{ signal, cancel }` pair (see {@link DriveToDoneOptions}).\n */\nexport async function driveToDone<\n S,\n M extends { type: string },\n E extends { type: string } = never,\n>(\n handle: BootingRuntime<S, M, E>,\n start: M | ((booted: S) => M),\n isTerminal: (state: S) => boolean,\n opts: DriveToDoneOptions<S, M> = {},\n): Promise<S> {\n const failed = opts.failed ?? (() => false);\n const settles = (state: S): boolean => isTerminal(state) || failed(state);\n let detach: (() => void) | undefined;\n let unlisten: (() => void) | undefined;\n try {\n const runtime = await handle.ready;\n // A run that rehydrated already terminal has nothing to start: resolve on\n // the boot State without dispatching, so `start`'s Cmds are never left in\n // flight for `stop()` to discard. Read BEFORE the signal so a run that\n // already ended keeps the outcome it ended on — an abort arriving after the\n // fact does not restate a finished run as cancelled.\n const booted = runtime.getState();\n // The one exit check every branch below shares: a State the caller's\n // `failed` predicate marks rejects, wherever the drive reached it.\n const outcome = (state: S): S => {\n if (failed(state)) throw new DriveFailedError(state);\n return state;\n };\n if (settles(booted)) return outcome(booted);\n // Attach BEFORE dispatching so a terminal transition landing inside the\n // start dispatch is caught.\n const terminal = new Promise<S>((resolve) => {\n detach = runtime.observe((_msg, state) => {\n if (settles(state)) resolve(state);\n });\n });\n // An abort mid-run enqueues the cancel Msg on the SAME serial tail every\n // other dispatch uses, so it lands between transitions rather than inside\n // one. Work already enqueued when the abort arrives still folds; work the\n // machine would have enqueued after it does not, because the cancelled State\n // is terminal and its verbs stop emitting. `dispatchOnce` (not `dispatch`)\n // because the cancel has no follow-up chain to drain. Its rejection is NOT\n // swallowed: only the cancel fold can land the terminal State on an abort,\n // so a cancel that throws leaves `terminal` with nothing to resolve it and\n // the drive would park forever (#170). `cancelFailed` carries that rejection\n // into whichever race the branch below awaits.\n let cancelFailed: Promise<never> | undefined;\n if (opts.signal !== undefined) {\n const { signal, cancel } = opts;\n let onCancelError!: (error: unknown) => void;\n cancelFailed = new Promise<never>((_resolve, reject) => {\n onCancelError = reject;\n });\n // The try covers the SYNCHRONOUS call site too, not just the dispatch it\n // returns: a caller-supplied `cancel` that throws before it ever produces\n // a Msg would otherwise escape this listener, and a listener's throw goes\n // nowhere — no caller frame to catch it, `terminal` still unresolved, the\n // drive parked exactly as #170 described (#174). Both throws are the same\n // fact — the cancel fold could not land a State — so both take the one\n // route out through `onCancelError`.\n const onAbort = () => {\n try {\n runtime.dispatchOnce(cancel(runtime.getState())).catch(onCancelError);\n } catch (error) {\n onCancelError(error);\n }\n };\n // Already aborted → cancel INSTEAD of starting, so `start`'s effects (a\n // model call, for the agent) never fire at all.\n if (signal.aborted) {\n onAbort();\n return outcome(await Promise.race([terminal, cancelFailed]));\n }\n signal.addEventListener(\"abort\", onAbort, { once: true });\n unlisten = () => signal.removeEventListener(\"abort\", onAbort);\n }\n // The race lets a dispatch rejection (reducer / interpret throw, the\n // quiescence cap) surface here instead of floating as an unhandled rejection\n // while the terminal await parks forever.\n const msg = typeof start === \"function\" ? start(booted) : start;\n const started = runtime.dispatch(msg).then(() => {\n // Quiesced. A settling State already went through the observer, so\n // `terminal` is resolved; otherwise the wait is legitimate only while the\n // runtime itself can still transition. With no live Sub and no Cmd in\n // flight nothing is coming, and the wait becomes the hang #68 names.\n const parked = runtime.getState();\n if (!settles(parked) && isStalled(runtime)) {\n throw new DriveStalledError(parked);\n }\n return terminal;\n });\n // `cancelFailed` rides the race for the mid-run abort: `started` cannot\n // carry the cancel's rejection, having usually resolved long before the\n // abort arrives.\n const racers: Promise<S>[] = [terminal, started];\n if (cancelFailed !== undefined) racers.push(cancelFailed);\n return outcome(await Promise.race(racers));\n } finally {\n detach?.();\n // The abort listener outlives this call unless it is removed: a signal a\n // caller reuses across runs would otherwise accumulate one dispatch per run\n // it has already finished.\n unlisten?.();\n // `stop()` resolves by contract, so awaiting it here cannot mask the error\n // a rejecting branch above is carrying.\n await handle.stop();\n }\n}\n","// ---------------------------------------------------------------------------\n// SubscribeHandler<S, M, Ctx> — the structural shape of a single entry in\n// `Machine.subscribe`. Pulled out as a named type so factory return types\n// in this subpath can match the substrate's expected `subscribe` cell shape\n// without re-deriving it from `Machine`'s mapped type.\n//\n// A Sub factory in this subpath returns a `SubscribeHandler<S, M, Ctx>` —\n// the same `(sub, ctx, dispatch) => cleanup` shape the substrate expects in\n// `machine.subscribe[type]`. Callers assign the factory's return value\n// directly to a subscribe cell:\n//\n// subscribe: {\n// \"audit-idle\": fromPort(\n// (ctx) => ctx.auditRuntime,\n// auditIdlePort,\n// (idle) => ({ type: \"audit:idle\", idle }),\n// ),\n// }\n//\n// The factory absorbs the lifecycle (subscribe + cleanup); the caller keeps\n// the intent (which port, which msg). Strengthens invariant 9 (the surface\n// for cross-cutting Sub topologies is named, small, and exported from one\n// subpath instead of redrawn at every call site).\n// ---------------------------------------------------------------------------\n\nimport type { Sub } from \"../index\";\n\nexport type SubscribeHandler<S extends Sub, M, Ctx> = (\n sub: S,\n ctx: Ctx,\n dispatch: (msg: M) => void,\n) => () => void;\n\n// ---------------------------------------------------------------------------\n// dispatchIfPresent — the null-drop dispatch idiom every Sub factory in this\n// subpath (and the chrome/node factories) shares. A factory's callback maps a\n// platform event to `M | null`; `null` is the explicit \"drop this emission\"\n// signal — the event fired but the caller decided it isn't interesting given\n// current state, so no dispatch is made and the listener stays armed. Hoisted\n// here so the one drop-on-null rule lives once instead of re-inlined as\n// `const msg = fn(...); if (msg !== null) dispatch(msg);` at every listener.\n// ---------------------------------------------------------------------------\n\nexport function dispatchIfPresent<M>(\n dispatch: (msg: M) => void,\n msg: M | null,\n): void {\n if (msg !== null) dispatch(msg);\n}\n","// ---------------------------------------------------------------------------\n// defineListener — listener-as-resource. The kernel primitive that turns an\n// imperative `add`/`remove` listener pair into a substrate-owned Sub whose\n// cleanup is MANDATORY and DERIVED — a forgotten or no-op disposer is\n// unrepresentable.\n//\n// The leak it kills: every author who wires a raw listener hand-rolls the SAME\n// skeleton —\n//\n// return (sub, _ctx, dispatch) => {\n// const listener = (e) => { const m = msgFn(e, sub); if (m !== null) dispatch(m); };\n// target.addListener(listener);\n// return () => target.removeListener(listener); // ← author-driven\n// };\n//\n// — and each re-write can SILENTLY LEAK two ways the type system never sees:\n//\n// 1. The disposer is a no-op (`return () => {}`) — the listener stays armed\n// forever. Nothing forces the returned cleanup to undo the add.\n// 2. The disposer calls `remove` with a DIFFERENT function than `add`\n// received (a fresh closure, a re-bound `this`) — the original listener\n// is never removed; it leaks while a phantom remove succeeds silently.\n//\n// `fromBroadcastChannel`, `fromEventTarget`, and every host-side bridge\n// hand-roll this skeleton today. They happen to be correct — but the\n// correctness is convention (rung 5), not structure. `defineListener` moves it\n// to rung 1: the listener the substrate builds is the SAME reference handed to\n// both `add` and `remove`, and the cleanup IS `() => remove(thatListener, ...)`.\n// You cannot write a no-op disposer because you do not write the disposer at\n// all.\n//\n// Shape:\n//\n// // Args is the tuple chrome invokes the listener with — here a single\n// // [Alarm]. The substrate builds ONE listener of this exact native shape.\n// const fromChromeAlarm = defineListener<[chrome.alarms.Alarm], S>({\n// add: (l) => chrome.alarms.onAlarm.addListener(l),\n// remove: (l) => chrome.alarms.onAlarm.removeListener(l),\n// });\n//\n// // ...then at the subscribe cell, supply the Msg projection:\n// subscribe: { tick: fromChromeAlarm<M>((sub, alarm) => ({ type: \"tick\", ... })) }\n//\n// - `add`/`remove` receive `(listener, sub, ctx)`. The `listener` is the\n// EXACT function the substrate built; pass it straight to the platform's\n// addListener/removeListener — NO wrapper. A wrapper inside `add` would\n// break reference identity (the platform stores the wrapper, but the\n// substrate hands `remove` the unwrapped listener → silent leak). Carrying\n// the platform's native `Args` tuple on the listener is what lets it be\n// registered directly. `sub`/`ctx` let the target be pulled from `ctx` or\n// keyed on the `sub` (the `getTarget()`-from-ctx shape fromPort needs).\n//\n// - `msgFn(sub, ...args) => M | null` — the universal drop-on-null filter\n// every factory in this subpath carries. `null` drops the dispatch; the\n// listener stays armed. `sub` is first (always present); the platform args\n// follow in their native order.\n//\n// Generalizes the `from*` pattern: a closure-owned disposer makes a forgotten\n// cleanup a syntax error, and this brings it to every host/satellite.\n//\n// Strengthens invariant 4 (external events enter as Subs; the lifecycle —\n// add on subscribe, remove on cleanup — is owned by the substrate, never the\n// author) and invariant 6 (no silent looseness: a leaked listener is a silent\n// failure, and this primitive removes the way to write one).\n// ---------------------------------------------------------------------------\n\nimport type { Sub } from \"../index\";\nimport { dispatchIfPresent, type SubscribeHandler } from \"./types\";\n\n/**\n * The imperative listener target, expressed as the `add`/`remove` pair the\n * substrate pairs into a reconciled resource. Both halves receive the SAME\n * `listener` reference — the substrate builds it once — so `remove` can never\n * be handed a different function than `add` saw.\n *\n * `add`/`remove` also receive `(sub, ctx)` so the target may be resolved from\n * `ctx` (a runtime, a port, a DOM node looked up lazily) or keyed on the Sub\n * (an alarm name, a channel name). Resolving the target inside `add` and\n * closing over nothing but the listener keeps a target swap from leaking the\n * old target's listener — same rationale as `fromEventTarget`'s captured\n * target.\n *\n * `Args` is the tuple the platform invokes the listener with — `[Alarm]` for\n * `chrome.alarms.onAlarm`, `[message, sender, sendResponse]` for\n * `chrome.runtime.onMessage`, `[changes, areaName]` for\n * `chrome.storage.onChanged`. The substrate builds ONE function of this exact\n * shape and threads the IDENTICAL reference to both `add` and `remove` — so a\n * platform that matches `removeListener` by reference (every chrome surface)\n * removes exactly what it added. A consumer that wrapped the listener inside\n * `add` would break reference identity (leak #2 above); carrying the native\n * `Args` on the listener itself removes the need for any wrapper.\n */\nexport interface ListenerTarget<\n Args extends readonly unknown[],\n S extends Sub,\n Ctx,\n> {\n add: (listener: (...args: Args) => void, sub: S, ctx: Ctx) => void;\n remove: (listener: (...args: Args) => void, sub: S, ctx: Ctx) => void;\n}\n\n/**\n * Build a listener-backed Sub factory whose cleanup is mandatory and derived.\n *\n * `Args`, `S`, `Ctx` are fixed when the target is defined — they describe the\n * one listener topology this factory owns (the platform arg tuple, which Sub\n * shape it filters on, what context resolves it). `M` is supplied at the\n * subscribe cell because the same listener feeds different Msgs in different\n * machines. Pinning `S` here (rather than at the `msgFn` step) lets\n * `add`/`remove` read the concrete Sub's fields — `sub.alarmName`,\n * `sub.channel` — with NO cast at the substrate edge: the narrowing happens in\n * author-land where the Sub shape is in scope.\n *\n * The returned function is a `SubscribeHandler` factory in the exact shape of\n * every other Sub factory in `src/subs/`: supply the `msgFn` projection, get a\n * `(sub, ctx, dispatch) => cleanup` handler assignable to `machine.subscribe`.\n * The cleanup the author NEVER writes is `() => remove(listener, sub, ctx)`,\n * with `listener` the identical reference passed to `add`.\n */\nexport function defineListener<\n Args extends readonly unknown[],\n S extends Sub = Sub,\n Ctx = unknown,\n>(\n target: ListenerTarget<Args, S, Ctx>,\n): <M>(\n msgFn: (sub: S, ...args: Args) => M | null,\n) => SubscribeHandler<S, M, Ctx> {\n return <M>(\n msgFn: (sub: S, ...args: Args) => M | null,\n ): SubscribeHandler<S, M, Ctx> => {\n return (sub, ctx, dispatch) => {\n const listener = (...args: Args): void => {\n dispatchIfPresent(dispatch, msgFn(sub, ...args));\n };\n // ONE listener, identical reference to both halves — chrome's\n // removeListener matches by reference, so this removes exactly what\n // add registered. No wrapper, no WeakMap, no reference drift.\n target.add(listener, sub, ctx);\n return () => {\n target.remove(listener, sub, ctx);\n };\n };\n };\n}\n","// ---------------------------------------------------------------------------\n// fromBroadcastChannel — universal `BroadcastChannel`-shaped Sub factory.\n//\n// `BroadcastChannel` is a same-origin pub/sub primitive available in\n// every modern browser context (window, worker, service worker) AND in\n// Cloudflare Workers (with origin scoped to the worker isolate). The\n// constructor opens the channel; the `message` event fires whenever\n// another participant on the same channel name posts a message; the\n// `close()` method releases the OS resource.\n//\n// The factory carries `channelName` on the Sub itself (not in the\n// closure) so the same factory instance handles every BroadcastChannel\n// Sub in a machine — one Sub per channel, named by id, sharing the\n// factory's lifecycle code. Renaming a channel requires a new Sub.id\n// (the reconcile pass otherwise leaves the existing channel open).\n//\n// `msgFn` returns `M | null` — same drop-on-null pattern as\n// `fromEventTarget`. The MessageEvent's `data` is `unknown` from the\n// platform's perspective; the caller decides whether the payload is a\n// recognizable shape, and returns `null` to drop unknown messages\n// without polluting the reducer with parse-discard cells.\n//\n// Cleanup calls `channel.close()`, which removes the listener AND\n// releases the channel reference — `removeEventListener` alone would\n// leak the BroadcastChannel handle. The pair is intentional.\n// ---------------------------------------------------------------------------\n\nimport type { Sub } from \"../index\";\nimport type {\n MinimalBroadcastChannelCtor,\n MinimalMessageEvent,\n} from \"./platform\";\nimport { dispatchIfPresent, type SubscribeHandler } from \"./types\";\n\ntype BroadcastSubData = { channelName: string };\n\ndeclare const BroadcastChannel: MinimalBroadcastChannelCtor;\n\nexport function fromBroadcastChannel<S extends Sub & BroadcastSubData, M>(\n msgFn: (event: MinimalMessageEvent, sub: S) => M | null,\n): SubscribeHandler<S, M, unknown> {\n return (sub, _ctx, dispatch) => {\n const channel = new BroadcastChannel(sub.channelName);\n const listener = (event: MinimalMessageEvent): void => {\n dispatchIfPresent(dispatch, msgFn(event, sub));\n };\n channel.addEventListener(\"message\", listener);\n return () => {\n channel.removeEventListener(\"message\", listener);\n channel.close();\n };\n };\n}\n","// ---------------------------------------------------------------------------\n// fromEventSource — universal `EventSource` (server-sent events) Sub\n// factory.\n//\n// SSE is the asymmetric streaming protocol used by the agent log /\n// audit log pipelines: HTTP-shaped open, server pushes events forever,\n// client receives until close. `EventSource` is the standard browser\n// API; the constructor opens the connection, `message` fires per\n// server-pushed event, `error` fires on disconnect or non-2xx, `open`\n// fires once on initial handshake, `close()` tears the connection\n// down.\n//\n// Three callbacks because three observable events ARE three concerns\n// the caller routinely cares about:\n//\n// - `onMessage(data, sub)` — required. The SSE payload's `data` field\n// is `string` from the platform; the caller decides parse + Msg\n// shape. Returns `M | null`; null drops the dispatch.\n//\n// - `onError(event, sub)` — optional. SSE's `error` event fires both\n// on transient network drops (the browser auto-reconnects) AND on\n// permanent failures. Most consumers want to surface ONE of these\n// as a Msg (e.g. \"stream-disconnected\") without folding both into\n// `onMessage`'s discriminant. Omitting the callback drops error\n// events silently.\n//\n// - `onOpen(sub)` — optional. The connection's initial handshake\n// succeeded. Useful for \"show 'connected' indicator\" Msgs. Omitting\n// drops open events silently. NOT fired on auto-reconnect by every\n// browser implementation — treat the event as best-effort.\n//\n// `url` lives on the Sub itself (`EventSourceSubData`). Same id +\n// different url = the substrate's reconcile pass leaves the existing\n// connection alone (the URL change is silent). Changing the URL\n// requires a new Sub.id.\n//\n// Cleanup is `close()` + `removeEventListener` for all three —\n// belt-and-suspenders against EventSource implementations that\n// dispatch events into already-closed sources.\n// ---------------------------------------------------------------------------\n\nimport type { Sub } from \"../index\";\nimport type {\n MinimalEvent,\n MinimalEventSourceCtor,\n MinimalMessageEvent,\n} from \"./platform\";\nimport { dispatchIfPresent, type SubscribeHandler } from \"./types\";\n\ntype EventSourceSubData = { url: string };\n\ndeclare const EventSource: MinimalEventSourceCtor;\n\nexport interface EventSourceFactoryOpts<S, M> {\n onMessage: (data: string, sub: S) => M | null;\n onError?: (event: MinimalEvent, sub: S) => M | null;\n onOpen?: (sub: S) => M | null;\n}\n\nexport function fromEventSource<S extends Sub & EventSourceSubData, M>(\n opts: EventSourceFactoryOpts<S, M>,\n): SubscribeHandler<S, M, unknown> {\n return (sub, _ctx, dispatch) => {\n const source = new EventSource(sub.url);\n\n const messageListener = (event: MinimalMessageEvent): void => {\n // The SSE `data` payload is a string per the platform contract.\n // Cast at the boundary: callers express `(data: string) => M | null`\n // and never see `unknown` flowing in from the platform global.\n dispatchIfPresent(dispatch, opts.onMessage(event.data as string, sub));\n };\n source.addEventListener(\"message\", messageListener);\n\n const onError = opts.onError;\n const errorListener = onError\n ? (event: MinimalEvent): void => {\n dispatchIfPresent(dispatch, onError(event, sub));\n }\n : undefined;\n if (errorListener) source.addEventListener(\"error\", errorListener);\n\n const onOpen = opts.onOpen;\n const openListener = onOpen\n ? (): void => {\n dispatchIfPresent(dispatch, onOpen(sub));\n }\n : undefined;\n if (openListener) source.addEventListener(\"open\", openListener);\n\n return () => {\n source.removeEventListener(\"message\", messageListener);\n if (errorListener) source.removeEventListener(\"error\", errorListener);\n if (openListener) source.removeEventListener(\"open\", openListener);\n source.close();\n };\n };\n}\n","// ---------------------------------------------------------------------------\n// fromEventTarget — universal addEventListener/removeEventListener Sub\n// factory over any `EventTarget` (DOM nodes, `window`, `document`,\n// `BroadcastChannel`, `MessagePort`, `Worker`, `ServiceWorker`, etc.).\n//\n// Two non-obvious shape choices:\n//\n// - `getTarget: () => EventTarget` is a thunk, not a direct value. The\n// factory MUST work in environments where the target is not available\n// at module-load time — service workers run before any `document`\n// exists; some targets are constructed lazily from `ctx`. Deferring\n// the lookup to subscribe time also means a state-driven swap of the\n// target requires only a new Sub.id; the factory pulls the current\n// target on subscribe.\n//\n// - `msgFn` may return `null` — that emission is *dropped*. The event\n// fired, the factory called `msgFn`, but the caller decided \"this\n// event is not interesting given current state.\" No dispatch is made;\n// the listener stays armed for the next event. This is the explicit\n// filter point at the Sub boundary — the alternative (filtering inside\n// the reducer via a noop cell) costs a transition + reconcile pass per\n// filtered event.\n//\n// Cleanup uses the SAME `getTarget()` instance captured at subscribe time\n// so a target swap mid-Sub doesn't leak the listener on the old target.\n// We close over the resolved target rather than calling `getTarget()`\n// again at cleanup — the alternative (re-resolving) is the cause of\n// silent listener leaks in long-lived runtimes.\n// ---------------------------------------------------------------------------\n\nimport type { Sub } from \"../index\";\nimport type { MinimalEvent, MinimalEventTarget } from \"./platform\";\nimport { dispatchIfPresent, type SubscribeHandler } from \"./types\";\n\nexport function fromEventTarget<S extends Sub, M>(\n getTarget: () => MinimalEventTarget,\n eventName: string,\n msgFn: (event: MinimalEvent, sub: S) => M | null,\n): SubscribeHandler<S, M, unknown> {\n return (sub, _ctx, dispatch) => {\n const target = getTarget();\n const listener = (event: MinimalEvent): void => {\n dispatchIfPresent(dispatch, msgFn(event, sub));\n };\n target.addEventListener(eventName, listener);\n return () => {\n target.removeEventListener(eventName, listener);\n };\n };\n}\n","// ---------------------------------------------------------------------------\n// fromInterval — universal `setInterval`-shaped Sub factory.\n//\n// The recurring shape at every `subscribe[type]` cell that wraps a periodic\n// timer is the same five lines: `setInterval` the dispatch, return a\n// `clearInterval` cleanup. The factory absorbs both halves of the lifecycle\n// (subscribe + cleanup); the caller keeps the intent — which Sub variant,\n// which Msg to dispatch.\n//\n// Timing data (`intervalMs`) lives on the Sub itself, not in the closure.\n// The substrate already reconciles Subs by id on every transition; carrying\n// the period on the Sub means a `subscriptions(state)` function that\n// returns `{ id, type, intervalMs: 30_000 }` in one state and the same id\n// with `intervalMs: 60_000` later... will NOT re-wire the interval (the id\n// is unchanged, the reconcile pass leaves it running). That's a tradeoff\n// the substrate's reconcile contract pins, not this factory — if you want\n// the interval to change, change the Sub's id too.\n//\n// Strengthens invariant 9 (named, small surface) and invariant 2 (the Sub\n// carries the data; the lifecycle is in the factory; the reducer never\n// sees the timer).\n// ---------------------------------------------------------------------------\n\nimport type { Sub } from \"../index\";\nimport type { SubscribeHandler } from \"./types\";\n\ntype IntervalSubData = { intervalMs: number };\n\nexport function fromInterval<S extends Sub & IntervalSubData, M>(\n msgFn: (sub: S) => M,\n): SubscribeHandler<S, M, unknown> {\n return (sub, _ctx, dispatch) => {\n const handle = setInterval(() => {\n dispatch(msgFn(sub));\n }, sub.intervalMs);\n return () => {\n clearInterval(handle);\n };\n };\n}\n","// ---------------------------------------------------------------------------\n// fromPort — universal `Runtime.subscribePort`-shaped Sub factory.\n//\n// The canonical cross-runtime coordination pattern in @demlik/tea: one\n// runtime emits to a typed Port; another runtime's machine declares an\n// `audit-idle`-shaped Sub whose subscribe handler attaches to the\n// publisher's Port. The recurring 4-line shape at every such cell:\n//\n// \"audit-idle\": (_sub, ctx, dispatch) =>\n// ctx.auditRuntime.subscribePort(auditIdlePort, (value) => {\n// dispatch(buildMsg(value));\n// });\n//\n// The factory absorbs the cleanup-returning subscribePort call AND the\n// dispatch-on-emit wiring. The caller keeps the three pieces of intent:\n//\n// 1. `selectRuntime(ctx)` — which sibling Runtime publishes the Port.\n// This is a selector (not a direct ctx.auditRuntime reference) so\n// the factory does NOT pin the ctx shape — any machine whose ctx\n// exposes some Runtime<...> reference is compatible by selecting it.\n// A direct `Runtime` parameter would have made the factory shape\n// depend on having that Runtime in scope at machine-definition\n// time, which is a worse match for the \"ctx is the boundary\"\n// contract this substrate already commits to.\n//\n// 2. `port: Port<T>` — the typed channel itself. Identity is by\n// reference (the substrate enforces unique names at definePort\n// time); pass the same `Port<T>` value the publisher emits to.\n//\n// 3. `msgFn(value, sub) => M | null` — the value-to-Msg mapping, with\n// drop-on-null semantics matching every other factory in this\n// subpath. The published value's type `T` flows through to `msgFn`'s\n// first param so the caller never re-asserts the payload shape.\n//\n// Strengthens invariant 9 (the cross-runtime Port topology is named at\n// one factory site instead of redrawn at every subscribe cell).\n// ---------------------------------------------------------------------------\n\nimport type { Port, Runtime, Sub } from \"../index\";\nimport { dispatchIfPresent, type SubscribeHandler } from \"./types\";\n\n// `RS` / `RM` carry the sibling Runtime's concrete State and Msg through the\n// selector: a caller that selects a `Runtime<AuditState, AuditMsg>` keeps that\n// type at the seam instead of collapsing it to `Runtime<unknown, {type:string}>`.\n// They default to the prior broad pair so existing call sites that select a\n// less-specific Runtime still compile — the factory still only ever calls\n// `subscribePort`, so it does not read RS/RM, but the boundary no longer\n// hardcodes the widest type when the caller knows a narrower one.\nexport function fromPort<\n S extends Sub,\n M,\n Ctx,\n T,\n RS = unknown,\n RM extends { type: string } = { type: string },\n>(\n selectRuntime: (ctx: Ctx) => Runtime<RS, RM>,\n port: Port<T>,\n msgFn: (value: T, sub: S) => M | null,\n): SubscribeHandler<S, M, Ctx> {\n return (sub, ctx, dispatch) => {\n const runtime = selectRuntime(ctx);\n return runtime.subscribePort(port, (value) => {\n dispatchIfPresent(dispatch, msgFn(value, sub));\n });\n };\n}\n","// ---------------------------------------------------------------------------\n// fromReconnectingWebSocket — a `WebSocket` Sub factory that survives drops.\n//\n// `fromWebSocket` is the SSE-sibling ONE-SHOT factory: its cleanup `close()`s\n// the socket and it never re-opens on an unexpected drop (issue #188). That is\n// the right shape for a connection the caller manages, but any tea client over\n// an unreliable transport — games, presence, collab — needs the connection to\n// recover transparently, without a page reload. Rather than re-roll a backoff\n// loop in every consumer (vortex's `ReconnectingSocket` is the proven shape,\n// services/vortex/src/reconnecting-socket.ts), this is the reconnecting variant\n// folded into the substrate's Sub surface.\n//\n// The reconnect contract, mirroring vortex's wrapper:\n//\n// - On an UNEXPECTED close (`onclose` the substrate didn't initiate) it\n// re-opens after a CAPPED exponential backoff: `min(base * 2^attempt, max)`.\n// A successful handshake resets `attempt` to 0, so the next drop retries\n// fast again.\n//\n// - A CALLER-INITIATED close (the Sub's cleanup, e.g. the machine\n// transitioned the Sub away) suppresses reconnect: handlers are detached\n// BEFORE `close(1000)` so the teardown can't fire `onClose` or schedule a\n// reconnect. After cleanup the factory never re-opens.\n//\n// - `connect` and `schedule` are INJECTABLE (defaulting to the global\n// `WebSocket` and `setTimeout`/`clearTimeout`), the test seam that lets the\n// reconnect/backoff behavior be unit-tested with a fake socket + a manual\n// clock — no DOM, no real network, no timers — exactly as vortex's wrapper\n// is tested.\n//\n// Callback contract (same `M | null` \"null drops the dispatch\" shape as\n// `fromWebSocket`, plus one reconnect-specific hook):\n//\n// - `onMessage(data, sub)` — required. Raw `unknown` frame; the caller parses.\n// - `onOpen(sub)` — optional. Fires on EVERY successful handshake — the first\n// open AND every reconnect — so a \"connected\" indicator stays accurate.\n// - `onError(event, sub)` — optional. The `error` event; `close` still drives\n// the reconnect (one path), so this is purely a notification.\n// - `onClose(code, reason, sub)` — optional. Fires on every close the\n// substrate observes (a drop that will be retried, too) — NOT on the\n// caller's own teardown, whose handlers are detached first.\n// - `onReconnect(attempt, sub)` — optional. Fires when a RE-open (any open\n// after the first) succeeds, carrying the 1-based reconnect count. This is\n// the resync hook: the place to dispatch a \"re-fetch the authoritative\n// snapshot, discard predicted state\" Msg after the transport recovered.\n//\n// Like `fromWebSocket`, `wsUrl` lives on the Sub (`WebSocketSubData`); every\n// reconnect reads `sub.wsUrl` afresh, so a reconcile that re-subscribes with a\n// new url reconnects to the new endpoint.\n// ---------------------------------------------------------------------------\n\nimport type { Sub } from \"../index\";\nimport type { WebSocketSubData } from \"./from-web-socket\";\nimport type {\n MinimalEvent,\n MinimalWebSocket,\n MinimalWebSocketCtor,\n} from \"./platform\";\nimport { dispatchIfPresent, type SubscribeHandler } from \"./types\";\n\ndeclare const WebSocket: MinimalWebSocketCtor;\n\n/** Cancels a scheduled reconnect timer (the inverse of `schedule`). */\nexport type CancelTimer = () => void;\n\nexport interface ReconnectingWebSocketFactoryOpts<S, M> {\n onMessage: (data: unknown, sub: S) => M | null;\n onOpen?: (sub: S) => M | null;\n onError?: (event: MinimalEvent, sub: S) => M | null;\n onClose?: (code: number, reason: string, sub: S) => M | null;\n /**\n * Fires when a reconnection (any open after the first) succeeds, carrying the\n * 1-based reconnect count — the resync hook. Omitting drops reconnect events\n * silently.\n */\n onReconnect?: (attempt: number, sub: S) => M | null;\n /** First backoff delay in ms (doubles each failed attempt). Default 250. */\n backoffBaseMs?: number;\n /** Backoff ceiling in ms. Default 5000. */\n backoffMaxMs?: number;\n /** Inject the socket constructor (defaults to the global `WebSocket`); the test seam. */\n connect?: (url: string) => MinimalWebSocket;\n /** Inject the timer (defaults to `setTimeout`/`clearTimeout`); the test seam. */\n schedule?: (fn: () => void, ms: number) => CancelTimer;\n}\n\nconst defaultConnect = (url: string): MinimalWebSocket => new WebSocket(url);\n\nconst defaultSchedule = (fn: () => void, ms: number): CancelTimer => {\n const handle = setTimeout(fn, ms);\n return () => clearTimeout(handle);\n};\n\nexport function fromReconnectingWebSocket<S extends Sub & WebSocketSubData, M>(\n opts: ReconnectingWebSocketFactoryOpts<S, M>,\n): SubscribeHandler<S, M, unknown> {\n const backoffBaseMs = opts.backoffBaseMs ?? 250;\n const backoffMaxMs = opts.backoffMaxMs ?? 5000;\n const connect = opts.connect ?? defaultConnect;\n const schedule = opts.schedule ?? defaultSchedule;\n\n const { onMessage, onOpen, onError, onClose, onReconnect } = opts;\n\n return (sub, _ctx, dispatch) => {\n let ws: MinimalWebSocket | null = null;\n let attempt = 0;\n let opened = false;\n let closedByCaller = false;\n let cancelReconnect: CancelTimer | null = null;\n\n const emit = (msg: M | null): void => dispatchIfPresent(dispatch, msg);\n\n const handleClose = (code: number, reason: string): void => {\n ws = null;\n if (onClose) emit(onClose(code, reason, sub));\n // A teardown the substrate initiated detaches handlers first, so this\n // path only runs for an UNEXPECTED close — reconnect with capped backoff.\n if (closedByCaller) return;\n const delay = Math.min(backoffBaseMs * 2 ** attempt, backoffMaxMs);\n attempt += 1;\n cancelReconnect = schedule(() => {\n cancelReconnect = null;\n if (!closedByCaller) open();\n }, delay);\n };\n\n function open(): void {\n const socket = connect(sub.wsUrl);\n ws = socket;\n\n socket.onopen = (): void => {\n // `opened` BEFORE this open marks it a reconnect; `attempt` is the\n // pending count for the drop that triggered it (1-based once we reset).\n const reconnected = opened;\n const reconnectCount = attempt;\n attempt = 0;\n opened = true;\n if (onOpen) emit(onOpen(sub));\n if (reconnected && onReconnect) emit(onReconnect(reconnectCount, sub));\n };\n\n socket.onmessage = (event): void => {\n emit(onMessage(event.data, sub));\n };\n\n // `error` precedes `close`; let `close` drive the reconnect so there is\n // one path. The handler is still wired (as a no-op when the caller didn't\n // supply `onError`) so a platform error event has a sink.\n socket.onerror = onError\n ? (event): void => emit(onError(event, sub))\n : (): void => {};\n\n socket.onclose = (event): void => {\n handleClose(event.code, event.reason);\n };\n }\n\n open();\n\n return () => {\n // Deliberate teardown: cancel any pending reconnect, detach handlers so\n // the cleanup `close()` can't fire `onClose` or schedule a reconnect,\n // then close the live socket. After this the factory never re-opens.\n closedByCaller = true;\n if (cancelReconnect !== null) {\n cancelReconnect();\n cancelReconnect = null;\n }\n const socket = ws;\n ws = null;\n if (socket !== null) {\n socket.onopen = null;\n socket.onmessage = null;\n socket.onerror = null;\n socket.onclose = null;\n // 1000 = \"normal closure\" per RFC 6455 §7.4.1.\n socket.close(1000);\n }\n };\n };\n}\n","// ---------------------------------------------------------------------------\n// fromTimeout — universal `setTimeout`-shaped Sub factory.\n//\n// Same lifecycle shape as `fromInterval` minus the recurrence: the\n// scheduled callback fires once, the cleanup is `clearTimeout`. Two\n// observable consequences worth pinning explicitly:\n//\n// 1. The Sub stays in the desired set until the caller removes it from\n// `subscriptions(state)`. The substrate's reconcile pass does NOT\n// auto-remove a Sub on cleanup — the timer fires, the callback\n// dispatches its Msg, and if the Sub is still present on the next\n// transition's desired set, the factory will... NOT re-fire. The\n// timer handle is captured per-subscribe call; after it fires, the\n// handle is exhausted. Adding the same Sub a second time (via a new\n// id) is the only way to re-arm.\n//\n// 2. Cleanup before the timer fires cancels the pending dispatch. This\n// is the \"cancel on state exit\" pattern: model the timeout as a Sub\n// whose `subscriptions(state)` returns it only in the state where the\n// timeout should be armed. When the state changes, the substrate's\n// reconcile drops the Sub and the factory's cleanup fires before the\n// timer does.\n//\n// Like `fromInterval`, the delay lives on the Sub (`delayMs`) — same id\n// means same scheduled timeout; changing the delay requires a new id.\n// ---------------------------------------------------------------------------\n\nimport type { Sub } from \"../index\";\nimport type { SubscribeHandler } from \"./types\";\n\ntype TimeoutSubData = { delayMs: number };\n\nexport function fromTimeout<S extends Sub & TimeoutSubData, M>(\n msgFn: (sub: S) => M,\n): SubscribeHandler<S, M, unknown> {\n return (sub, _ctx, dispatch) => {\n const handle = setTimeout(() => {\n dispatch(msgFn(sub));\n }, sub.delayMs);\n return () => {\n clearTimeout(handle);\n };\n };\n}\n","// ---------------------------------------------------------------------------\n// fromWebSocket — universal `WebSocket` Sub factory. The symmetric sibling\n// of `fromEventSource`.\n//\n// WebSocket is the bidirectional streaming protocol used wherever the\n// server pushes events AND the client pushes commands on the same\n// connection. The constructor opens the connection, `onopen` fires once\n// on handshake, `onmessage` fires per server-pushed frame, `onerror`\n// fires on transient or permanent failure, `onclose` fires once on\n// teardown carrying `code` + `reason`. `close(code)` initiates a clean\n// shutdown from the client side.\n//\n// Four callbacks because four observable events ARE four concerns the\n// caller routinely cares about. The Sub's `wsUrl` lives on the Sub itself\n// (`WebSocketSubData`) — same id + different `wsUrl` is silent under the\n// reconcile pass, identical to `fromEventSource`'s `url` contract.\n//\n// - `onMessage(data, sub)` — required. The platform delivers `data` as\n// `string | Blob | ArrayBuffer` depending on `binaryType` and the\n// server's frame type. The factory does NOT bake in a parse contract:\n// the callback receives the raw `unknown` and decides parse + Msg\n// shape. Returns `M | null`; null drops the dispatch.\n//\n// - `onOpen(sub)` — optional. Connection handshake succeeded. Useful\n// for \"show 'connected' indicator\" Msgs. Omitting drops open events\n// silently.\n//\n// - `onError(event, sub)` — optional. WebSocket's `error` event fires\n// on transient drops AND permanent failures; like SSE, most consumers\n// want one Msg (\"connection-errored\") without folding both into\n// `onMessage`'s discriminant. Omitting drops error events silently.\n//\n// - `onClose(code, reason, sub)` — optional. The connection is gone.\n// `code` is the WebSocket close code (1000 = clean, 1006 = abnormal,\n// etc.). `reason` is the server-supplied string (often empty).\n// Omitting drops close events silently.\n//\n// Cleanup is `close(1000)` — the IANA-registered clean-shutdown code.\n// The factory intentionally does NOT bake in registry semantics (e.g.\n// the extension's `ctx.wsRegistry` so `interpret.send_ws` can reach the\n// live socket): that's consumer glue. A consumer that needs the live\n// socket for outbound sends wires it from inside the subscribe handler\n// or keeps a hand-written Sub alongside this factory.\n// ---------------------------------------------------------------------------\n\nimport type { Sub } from \"../index\";\nimport type {\n MinimalCloseEvent,\n MinimalEvent,\n MinimalMessageEvent,\n MinimalWebSocketCtor,\n} from \"./platform\";\nimport { dispatchIfPresent, type SubscribeHandler } from \"./types\";\n\nexport type WebSocketSubData = { wsUrl: string };\n\ndeclare const WebSocket: MinimalWebSocketCtor;\n\nexport interface WebSocketFactoryOpts<S, M> {\n onMessage: (data: unknown, sub: S) => M | null;\n onOpen?: (sub: S) => M | null;\n onError?: (event: MinimalEvent, sub: S) => M | null;\n onClose?: (code: number, reason: string, sub: S) => M | null;\n}\n\nexport function fromWebSocket<S extends Sub & WebSocketSubData, M>(\n opts: WebSocketFactoryOpts<S, M>,\n): SubscribeHandler<S, M, unknown> {\n return (sub, _ctx, dispatch) => {\n const ws = new WebSocket(sub.wsUrl);\n\n ws.onmessage = (event: MinimalMessageEvent): void => {\n // The platform delivers `data` as `unknown` — the factory hands it\n // through untouched and the caller chooses the parse strategy.\n dispatchIfPresent(dispatch, opts.onMessage(event.data, sub));\n };\n\n const onOpen = opts.onOpen;\n if (onOpen) {\n ws.onopen = (): void => {\n dispatchIfPresent(dispatch, onOpen(sub));\n };\n }\n\n const onError = opts.onError;\n if (onError) {\n ws.onerror = (event: MinimalEvent): void => {\n dispatchIfPresent(dispatch, onError(event, sub));\n };\n }\n\n const onClose = opts.onClose;\n if (onClose) {\n ws.onclose = (event: MinimalCloseEvent): void => {\n dispatchIfPresent(dispatch, onClose(event.code, event.reason, sub));\n };\n }\n\n return () => {\n // Detach the lifecycle handlers BEFORE close() so the consumer's\n // `onClose` Msg isn't fired from a teardown the substrate initiated.\n // Mirrors fromEventSource's removeEventListener pass.\n ws.onmessage = null;\n ws.onopen = null;\n ws.onerror = null;\n ws.onclose = null;\n // 1000 = \"normal closure\" per RFC 6455 §7.4.1.\n ws.close(1000);\n };\n };\n}\n","// ---------------------------------------------------------------------------\n// defineManagedResource — a Model-gated resource with a MANDATORY release.\n//\n// foldkit's ManagedResource, ported. The recurring shape: a resource whose\n// lifetime is \"while the machine is in phase X, hold Y open; on leaving X,\n// tear Y down\" — a checkpoint store, a span, a lease, a pooled connection.\n// Rule 9 says that is a Sub the substrate reconciles, NOT a start/end Cmd\n// pair hand-driven across cells. Hand-driving leaks: every transition cell\n// has to remember to end-then-start, and one missed cell leaks the resource\n// forever (the checkpoint-namespace leak this battery was built to kill).\n//\n// The author writes three things — `{ name, acquire, release }` — and gets\n// back a `.sub(key)` to drop into `subscriptions(state)` plus a `.subscribe`\n// handler to drop into the machine's `subscribe` record. The substrate's\n// existing `reconcileSubs` (packages/tea/src/run.ts) does the rest:\n// - sub APPEARS in the desired set → handler runs → `acquire(key, ctx)`.\n// - sub DISAPPEARS (phase left) → cleanup runs → `release(handle)`.\n// - sub KEY changes (id changes) → old cleanup (release) + new acquire.\n// Same reconcile mechanism `fromTransport` rides for open/close — no new\n// kernel hook.\n//\n// THE ACQUIRE-AS-SUCCESS-VALUE DISCIPLINE\n// ----------------------------------------\n// `release` receives ONLY what `acquire` returned (the Handle). Nothing else\n// is in scope. So:\n// - An `acquire` that throws never produces a Handle, so `release` is never\n// called with a half-built resource — an interrupted acquire can't dangle.\n// - Whatever `release` needs to tear down must be captured INTO the Handle\n// by `acquire`. The Handle is the closure over the live resource.\n// `release` is NOT optional in the type. A managed resource without a teardown\n// is just a Cmd (Rule 5); the whole point of this battery is the guaranteed\n// teardown, so the type forces the author to write one.\n//\n// NEUTRAL MECHANISM — no policy. The battery knows `acquire`, `release`,\n// `name`, `key`. It does not know what a checkpoint, a span, or a socket is.\n// Could a reasonable machine want the opposite of any choice here? The only\n// choices are \"release is mandatory\" (yes — that's the contract) and \"release\n// runs on disappear OR key-change\" (yes — that's reconcile semantics, shared\n// with every other Sub). No Cloudflare, no audit domain.\n//\n// Strengthens invariant 4 (external lifecycle owned by the substrate — the\n// acquire/release pair rides reconcileSubs, never hand-driven by a cell) and\n// invariant 6 (no silent looseness — every live resource is a Sub in the\n// desired set, visible in the Sub topology, and an unroutable one throws).\n// ---------------------------------------------------------------------------\n\nimport type { DepKeyedSub, Dispose, Sub, SubId } from \"../index\";\nimport { structuralHash, subId } from \"../index\";\n\n/**\n * The Sub the battery builds. The consumer's `Sub` union includes\n * `ManagedResourceSub<TKey>` directly — the substrate reconciles by `id` and\n * `type` like any other Sub.\n */\nexport interface ManagedResourceSub<TKey> extends Sub<\"managed_resource\"> {\n /** The lifetime key. Stable while the resource should be held; a change\n * retires the old resource (release) and acquires a fresh one. */\n readonly key: TKey;\n}\n\n/**\n * A battery paired with a state-gate. Self-contained: it knows its `name`\n * (for the unique-name assert), how to derive its live Sub from a state\n * (`subFor`), how to handle its own `subscribe`, and whether it `owns` a given\n * Sub id.\n *\n * Generic in the consumer state `S`, the shared lifetime key `TKey`, and the\n * shared `Ctx`. `Handle` is the ONLY thing erased — each battery's handle type\n * differs (a checkpoint saver vs. a tool-call bridge) but never crosses this\n * interface, so a `combineManagedResources` array holds entries of\n * heterogeneous handle types with no cast. The sub type stays\n * `ManagedResourceSub<TKey>` end to end, so the substrate's narrowed Sub flows\n * straight in.\n */\nexport interface GatedManagedResource<S, TKey, Ctx> {\n /** The owning battery's `name`. The combinator asserts these are unique. */\n readonly name: string;\n\n /**\n * Derive this resource's live Sub for a given state: the battery's\n * `.sub(key)` when `when(state)` returns a key, or `null` when it returns\n * `null` (the resource should be torn down in that state).\n */\n readonly subFor: (state: S) => ManagedResourceSub<TKey> | null;\n\n /**\n * This battery's own `.subscribe`. The combinator routes an incoming\n * `managed_resource` Sub to the entry whose `owns(sub)` is true, then calls\n * this.\n */\n readonly subscribe: (\n sub: ManagedResourceSub<TKey>,\n ctx: Ctx,\n dispatch: (msg: never) => void,\n ) => Dispose;\n\n /**\n * Does this entry own the given Sub? `sub.id === subIdFor(sub.key)` encodes\n * the battery `name`, so a match is unambiguous.\n */\n readonly owns: (sub: ManagedResourceSub<TKey>) => boolean;\n}\n\n/**\n * What `combineManagedResources` returns: the single managed-resource\n * `subscribe` handler for the machine's `subscribe` record, and a `subs(state)`\n * builder for `subscriptions(state)`.\n */\nexport interface CombinedManagedResources<S, TKey, Ctx> {\n /**\n * Map every entry through its `when(state)`, drop the `null`s, and build the\n * live Subs. Spread into `subscriptions(state)`. The derived list and the\n * `subscribe` routing share one source — the entries — so they never drift.\n */\n readonly subs: (state: S) => ManagedResourceSub<TKey>[];\n\n /**\n * The SINGLE `subscribe.managed_resource` handler. Routes an incoming Sub to\n * the owning battery by matching `sub.id === battery.subIdFor(sub.key)` (the\n * id encodes the battery `name`). Throws loudly on an unrouted id — a wiring\n * bug, never a silent no-op resource.\n */\n readonly subscribe: (\n sub: ManagedResourceSub<TKey>,\n ctx: Ctx,\n dispatch: (msg: never) => void,\n ) => Dispose;\n}\n\nexport interface DefineManagedResourceOpts<TKey, Handle, Ctx> {\n /**\n * A short, stable name. The Sub id is `managed:${name}:${stringify(key)}`,\n * so two managed resources in one machine never collide and neither\n * collides with a `fromTransport` Sub keyed on the same identity.\n */\n readonly name: string;\n\n /**\n * Build the resource. Runs when the Sub appears in `subscriptions(state)`.\n * The returned Handle is the ONLY thing `release` receives — capture\n * everything teardown needs into it. If `acquire` throws, the substrate's\n * reconcile does NOT register the Sub and `release` is never called (no\n * dangling half-built resource).\n */\n readonly acquire: (key: TKey, ctx: Ctx) => Handle;\n\n /**\n * Tear the resource down. Runs when the Sub leaves the desired set (phase\n * exited) or when its key changes. MANDATORY — the guaranteed teardown is\n * the reason this battery exists.\n *\n * May be sync or async, and an async one is really awaited: the promise is\n * returned to the substrate, which tracks it and drains it inside `stop()`\n * (bounded by `run({ disposeTimeoutMs })`). So `await runtime.stop()` means\n * the release finished — the reading a host evicting an isolate acts on.\n * MID-RUN teardown (a phase exit, a key change) is still fire-and-forget\n * (Rule 2): the reconcile pass is synchronous by construction, so it starts\n * the release and moves on. A rejection is never a Msg — it reaches the\n * runtime's `onError` sink under `phase: \"sub-cleanup\"`.\n */\n readonly release: (handle: Handle) => void | Promise<void>;\n}\n\n/**\n * What the battery returns: a `.sub(key)` builder for `subscriptions`, the\n * `.subscribe` handler for the machine's `subscribe` record, a `.get(key)`\n * accessor so Cmd handlers can reach the live Handle while the resource is\n * held, and a `.subIdFor(key)` for tests.\n */\nexport interface ManagedResourceBattery<TKey, Handle, Ctx> {\n /**\n * Build the Sub for `subscriptions(state)`. The consumer calls this from\n * inside their `subscriptions` cell for the phases where the resource\n * should be live.\n */\n readonly sub: (key: TKey) => ManagedResourceSub<TKey>;\n\n /**\n * Pair this battery with a state-gate, producing a self-contained entry for\n * `combineManagedResources`. `when(state)` returns the resource's KEY when\n * it should be live in that state, or `null` when it should be torn down.\n *\n * Folding \"is it active?\" and \"what key?\" into ONE declaration at the\n * battery's own definition site is the point: a central `subscriptions(state)`\n * list can silently forget to gate a new phase, but a per-resource gate\n * travels with the resource. The combinator derives BOTH the active-sub list\n * and the subscribe routing from these entries, so the two can never disagree.\n *\n * Generic in the consumer's state `S` (each `.gated` call binds its own `S`).\n * The returned entry erases this battery's `Handle` — `combineManagedResources`\n * holds entries of heterogeneous handle types with no cast — while keeping\n * `TKey` and `Ctx` so the substrate's narrowed `ManagedResourceSub<TKey>`\n * flows straight into the entry's `subscribe`.\n */\n readonly gated: <S>(\n when: (state: S) => TKey | null,\n ) => GatedManagedResource<S, TKey, Ctx>;\n\n /**\n * Dep-keyed entry for the machine's `subs` array. `when(state)` returns the\n * resource's KEY when it should be held, or `null` when it should be torn\n * down — the exact gate `.gated` takes, now producing a `DepKeyedSub` the\n * kernel folds directly instead of an entry the `combineManagedResources`\n * router multiplexes.\n *\n * This is the simplification the dep-keyed kernel unlocks: two managed\n * resources used to COLLIDE on the single `subscribe.managed_resource` key\n * (both subs share `type: \"managed_resource\"`), forcing\n * `combineManagedResources` to route by SubId. A dep-keyed Sub has its OWN\n * reconcile slot (its array position), so there is no shared `type` to route\n * — each resource is one `subs` entry, no combinator, no router. `acquire` /\n * `release` still ride the kernel's dispose-on-change / dispose-on-null\n * reconcile, now via the dep-keyed source's `Dispose` instead of the\n * `subscribe` cell's cleanup.\n */\n readonly depKeyed: <S>(\n when: (state: S) => TKey | null,\n ) => DepKeyedSub<S, never, Ctx>;\n\n /**\n * The `subscribe.managed_resource` handler. Drop straight into the\n * machine's `subscribe` record. Runs `acquire` on install, holds the\n * Handle in the battery's handle table, and returns a cleanup that runs\n * `release` (and forgets the Handle) on reconcile-out.\n */\n readonly subscribe: (\n sub: ManagedResourceSub<TKey>,\n ctx: Ctx,\n // The managed resource dispatches no Msgs — acquire/release are pure\n // lifecycle. `dispatch` is accepted to match the substrate's\n // `subscribe[type]` shape and is intentionally unused.\n dispatch: (msg: never) => void,\n ) => Dispose;\n\n /**\n * Accessor for the live Handle, keyed on `key`. Returns `undefined` when\n * the resource is not currently held (no active sub for that key) — the\n * caller decides whether that is an error. A Cmd handler wires its\n * `ctx.getX(key)` through this, so the handler reads the SAME owner the\n * reconciler holds, never a hand-built duplicate.\n */\n readonly get: (key: TKey) => Handle | undefined;\n\n /** Pre-derived subId for `(key)` — handy for tests. */\n readonly subIdFor: (key: TKey) => SubId;\n}\n\n/**\n * Build the battery. One call per managed resource at the machine's host\n * file.\n *\n * @example\n * const checkpointStore = defineManagedResource<RunId, CheckpointSaver, Ctx>({\n * name: \"checkpoint\",\n * acquire: (runId, ctx) =>\n * new CheckpointSaver({ storage: ctx.storage, bucket: ctx.bucket, runId }),\n * release: (saver) => saver.clear(),\n * });\n *\n * // In the machine:\n * subscriptions: (state) =>\n * state.type === \"running\" ? [checkpointStore.sub(state.runId)] : [],\n * subscribe: { managed_resource: checkpointStore.subscribe },\n *\n * // In interpret (read the live handle the reconciler holds):\n * start_graph: async (cmd, ctx) => {\n * const saver = checkpointStore.get(cmd.runId); // same owner, no rebuild\n * ...\n * }\n */\nexport function defineManagedResource<TKey, Handle, Ctx>(\n opts: DefineManagedResourceOpts<TKey, Handle, Ctx>,\n): ManagedResourceBattery<TKey, Handle, Ctx> {\n // Handle table — one live resource per key. Lives in this closure for the\n // lifetime of the battery (the machine's lifetime). Interpret-local; never\n // crosses into reducer state. Same shape as `fromTransport`'s `live` map.\n const held = new Map<string, Handle>();\n\n // Single-sourced on the kernel's `structuralHash`: `\"1\"` (string) and `1`\n // (number) render distinctly, so a key collision can't return/release the\n // wrong held handle; non-JSON keys throw loudly instead of silently returning\n // undefined.\n const keyString = (k: TKey): string => structuralHash(k);\n\n const subIdFor = (key: TKey): SubId =>\n subId(`managed:${opts.name}:${keyString(key)}`);\n\n const subBuilder = (key: TKey): ManagedResourceSub<TKey> => ({\n id: subIdFor(key),\n type: \"managed_resource\",\n key,\n });\n\n const subscribeHandler = (\n sub: ManagedResourceSub<TKey>,\n ctx: Ctx,\n _dispatch: (msg: never) => void,\n ): Dispose => {\n // Acquire. A throw here propagates out of reconcileSubs (the substrate\n // records it and re-throws after the diff pass) and the Sub is NOT\n // registered — so no cleanup runs and `held` stays clean. The\n // acquire-as-success-value discipline: no Handle, no release.\n const handle = opts.acquire(sub.key, ctx);\n const k = keyString(sub.key);\n held.set(k, handle);\n\n // Cleanup runs when the substrate's reconcileSubs leaves the phase OR\n // the key changes. Forget the Handle first so a concurrent `get` after\n // teardown begins sees `undefined`, then release.\n //\n // An async `release` is RETURNED, not swallowed: the substrate tracks the\n // promise and `stop()` awaits it (bounded), so `await runtime.stop()` means\n // the release finished. Attaching a `.catch` here and returning `void` was\n // the defect — a host doing `await stop(); env.evict()` dropped the isolate\n // mid-release, which is the leak this battery exists to prevent, moved to\n // shutdown. A rejection now reaches the runtime's `onError` under\n // `phase: \"sub-cleanup\"` instead of a `console.warn` nobody configured.\n return () => {\n held.delete(k);\n return opts.release(handle);\n };\n };\n\n return {\n sub: subBuilder,\n\n // Pair the battery with a state-gate. `TKey` / `Handle` / `Ctx` are in\n // scope here, so `subFor` builds the fully-typed sub and `subscribe`\n // forwards straight to the battery's own typed `subscribe`. The entry\n // erases ONLY `Handle` for the combinator (`TKey` and `Ctx` stay), so the\n // substrate's narrowed `ManagedResourceSub<TKey>` flows in with no cast.\n gated: <S>(\n when: (state: S) => TKey | null,\n ): GatedManagedResource<S, TKey, Ctx> => ({\n name: opts.name,\n owns: (sub) => sub.id === subIdFor(sub.key),\n subFor: (state) => {\n const key = when(state);\n return key === null ? null : subBuilder(key);\n },\n subscribe: subscribeHandler,\n }),\n\n // Dep-keyed entry. `when` is the gate (the deps = the KEY); the source runs\n // the SAME `acquire` → hold → `release`-on-dispose lifecycle the `subscribe`\n // cell does, now driven by the kernel's dep-keyed reconcile. The Msg type is\n // `never` (a managed resource dispatches nothing); the ignored `_dispatch`\n // matches the source signature.\n depKeyed: <S>(\n when: (state: S) => TKey | null,\n ): DepKeyedSub<S, never, Ctx> => ({\n deps: when,\n source: (state, _dispatch, ctx) => {\n const key = when(state);\n if (key === null) return () => {};\n return subscribeHandler(subBuilder(key), ctx, () => {});\n },\n }),\n\n subscribe: subscribeHandler,\n\n get: (key) => held.get(keyString(key)),\n\n subIdFor,\n };\n}\n\n// ---------------------------------------------------------------------------\n// combineManagedResources — fold N gated batteries into ONE subscribe cell + a\n// derived active-sub list.\n//\n// Two managed resources colliding on the single `subscribe.managed_resource`\n// key forced the machine to hand-roll a router (`if (sub.id === X.subIdFor(...))`).\n// A third copy-pastes another `if`. That router is glue that belongs in the\n// substrate, not the machine. AND the resources' active-phase gating lived in\n// a central `subscriptions(state)` list a new phase could silently forget.\n//\n// This combinator closes both gaps. Each entry carries its OWN gate at its\n// definition site (`battery.gated((s) => active(s) ? key : null)`), and the\n// combinator derives BOTH the active-sub list (`subs`) and the routing\n// (`subscribe`) from the same entries — so they can never disagree, and a new\n// phase that the gate doesn't cover simply produces no sub (no silent leak of\n// the central-list-forgot kind).\n//\n// NEUTRAL MECHANISM — no domain knowledge. The combinator knows `name` (for\n// the unique assert), `owns` (for routing), `subFor` (for the list), and\n// `subscribe` (to forward). It does not know what a checkpoint, a bridge, or a\n// Cloudflare anything is.\n//\n// Strengthens invariant 4 (external lifecycle owned by the substrate — both\n// the list and the routing are derived, never hand-driven) and invariant 6 (no\n// silent looseness — ONE managed-resource cell, and an unrouted id throws\n// loudly instead of silently installing a no-op).\n// ---------------------------------------------------------------------------\nexport function combineManagedResources<S, TKey, Ctx>(\n entries: readonly GatedManagedResource<S, TKey, Ctx>[],\n): CombinedManagedResources<S, TKey, Ctx> {\n // Assert unique names at construction — two batteries with the same `name`\n // collide on Sub id (`managed:${name}:${key}`), so the router could not tell\n // them apart. Throw immediately (mirrors foldkit's `combineSubscriptions` on\n // a duplicate key) rather than mis-route at runtime.\n const seen = new Set<string>();\n for (const entry of entries) {\n if (seen.has(entry.name)) {\n throw new Error(\n `[combineManagedResources] duplicate managed-resource name \"${entry.name}\" — names must be unique (the Sub id encodes the name; two batteries sharing it collide)`,\n );\n }\n seen.add(entry.name);\n }\n\n return {\n subs: (state) => {\n const live: ManagedResourceSub<TKey>[] = [];\n for (const entry of entries) {\n const sub = entry.subFor(state);\n if (sub !== null) live.push(sub);\n }\n return live;\n },\n\n subscribe: (sub, ctx, dispatch) => {\n const owner = entries.find((entry) => entry.owns(sub));\n if (owner === undefined) {\n // No battery owns this managed-resource SubId — a wiring bug. Surface\n // loudly rather than silently install a no-op resource (invariant 6).\n throw new Error(\n `[combineManagedResources] no battery for sub id ${sub.id}`,\n );\n }\n return owner.subscribe(sub, ctx, dispatch);\n },\n };\n}\n","// ---------------------------------------------------------------------------\n// fromTransport — the SEAM battery.\n//\n// At every seam between two TEA-shaped processes (a DO ↔ its hands container,\n// a SW background ↔ a content script, a parent ↔ a child runtime), there is\n// the SAME hand-rolled boilerplate:\n//\n// 1. The inbound message stream — a Sub keyed on a phase, opened when the\n// machine enters the phase, closed when the machine leaves it.\n// 2. A transport-close detector — when the underlying channel drops, a\n// single Msg is dispatched (`*_lost`). NOT a Sub the consumer\n// re-publishes; the lifetime IS the inbound Sub's lifetime.\n// 3. The outbound side — a Cmd whose handler hands a value to the live\n// transport, looked up by an interpret-local handle table keyed on the\n// phase's run-identity.\n//\n// Every hand-rolled seam (`hands-inbound.ts`, `forwardOutbound`, the\n// `client_disconnected` Msg arm, the WS handle map) is the same three\n// pieces with different vocabularies. The battery bakes those three in.\n//\n// What the author writes:\n//\n// 1. The vocabulary (Inbound / Outbound types).\n// 2. ONE call: `fromTransport({ name, openTransport, parseInbound, ... })`.\n//\n// What the author NEVER writes again:\n//\n// - The `Sub` shape, the `subscribe` cell, the `cleanup` Promise dance.\n// - The transport-close → `*_lost` Msg wiring.\n// - The \"find the live socket from inside an interpret handler\" lookup.\n// - The keepalive / heartbeat / sequence-number ceremony (none of those\n// belong in the machine — that's Rule 9: lifetime-bound resources are\n// Subs, not state-machine cells).\n//\n// Host-pluggable: the battery takes a `TransportFactory`, not a concrete\n// WebSocket. A Durable Object passes a workerd `WebSocket` adapter; a worker\n// thread can pass a `MessagePort` adapter; an in-process test can pass a\n// stub. Same battery; three different hosts.\n//\n// Distinct from `fromWebSocket` / `fromReconnectingWebSocket` in this same\n// subpath, which own a CONCRETE `WebSocket` and are inbound-only. This battery\n// is transport-agnostic and duplex: it also owns the outbound handle table, so\n// a Cmd handler can reach the live channel without a hand-written registry.\n//\n// Strengthens invariant 4 (external events / observation enter as Subs;\n// lifecycle owned by the substrate — the inbound stream, the close\n// detection, AND the outbound handle are all owned by the battery's Sub\n// lifecycle, not hand-driven by the consumer's cells).\n// ---------------------------------------------------------------------------\n\nimport type { DepKeyedSub, Sub, SubId } from \"../index\";\nimport { structuralHash, subId } from \"../index\";\n\n/**\n * Duplex transport. The host (DO, worker thread, in-process bus) constructs\n * one from whatever the platform offers. `fromTransport` does not know what\n * a WebSocket is — it knows `send`, `onMessage`, `onClose`.\n */\nexport interface Transport {\n /** Send a string frame. Best-effort; failures are logged at the boundary. */\n send(data: string): void;\n /**\n * Subscribe to inbound frames. Returns a cleanup that removes the listener.\n * The battery wires this in its Sub's subscribe handler; cleanup runs when\n * the phase exits (the substrate's reconcileSubs).\n */\n onMessage(listener: (data: string) => void): () => void;\n /**\n * Subscribe to a one-shot close. Returns a cleanup that removes the\n * listener. The battery dispatches `lostMsg` on close.\n */\n onClose(listener: () => void): () => void;\n /** Close the underlying channel cleanly. Called by the Sub cleanup. */\n close(): void;\n}\n\n/**\n * Factory the consumer wires to a platform-specific transport. The battery\n * passes the runtime-derived key (`runId`, or whatever identity is on the\n * phase) so per-run transports can be addressed.\n */\nexport type TransportFactory<K> = (key: K) => Transport;\n\n/**\n * The Sub the battery builds. The consumer's `Sub` union includes\n * `TransportSub<TKey>` directly — no wrapping needed, the substrate\n * reconciles by `id` and `type` like any other Sub.\n */\nexport interface TransportSub<TKey> extends Sub<\"transport\"> {\n /** The phase / run identity. Stable for the lifetime of the seam. */\n readonly key: TKey;\n}\n\nexport interface FromTransportOpts<TKey, Inbound, Outbound, M, Ctx> {\n /**\n * A short, stable name for this seam. The Sub id is derived from\n * `${name}:${stringify(key)}` so two seams in the same machine (e.g.\n * `hands` + `worker`) never collide.\n */\n readonly name: string;\n\n /**\n * Build the transport. The battery owns the lifetime; the factory is the\n * platform-specific constructor (`new WebSocket(...)` adapter on a DO,\n * `MessagePort` adapter in a worker, in-memory stub in tests).\n */\n readonly openTransport: (key: TKey, ctx: Ctx) => Transport;\n\n /**\n * Parse one inbound frame. The battery hands `unknown` through (boundary\n * parse is the consumer's responsibility per invariant 8). Returning\n * `null` drops the frame silently — useful for frames the seam doesn't\n * recognize at this layer (e.g. transport-level keepalive).\n */\n readonly parseInbound: (raw: string, key: TKey) => Inbound | null;\n\n /**\n * Map a parsed inbound to a domain Msg. Returning `null` drops the\n * dispatch (e.g. a transport-level pong that doesn't change domain state).\n */\n readonly onInbound: (inbound: Inbound, key: TKey) => M | null;\n\n /**\n * The Msg dispatched when the transport closes (peer gone, network\n * dropped, normal close). ONE Msg arm, not a Sub, not a heartbeat-derived\n * deadline — the transport's own close signal is the truth.\n */\n readonly lostMsg: (key: TKey) => M;\n\n /**\n * Serialize an outbound. Called by the Cmd handler the battery wires.\n * Pure data → string at the seam boundary.\n */\n readonly serializeOutbound: (outbound: Outbound) => string;\n}\n\n/**\n * What the battery returns: a Sub builder (for `subscriptions`), the Sub's\n * `subscribe` handler (for `subscribe.transport`), and a `send(key, outbound)`\n * helper the consumer's Cmd handler calls. Plus a `subIdFor` factory the\n * consumer can use when keying related Subs (e.g. a deadline) to the same seam\n * identity.\n */\nexport interface TransportBattery<TKey, Outbound, M, Ctx> {\n /**\n * Build the Sub for `subscriptions(state)`. The consumer calls this from\n * inside their `subscriptions` cell when the seam should be open.\n */\n readonly sub: (key: TKey) => TransportSub<TKey>;\n\n /**\n * The `subscribe.transport` handler. Drop straight into the machine's\n * `subscribe` record — the battery wires inbound + close in one shot.\n */\n readonly subscribe: (\n sub: TransportSub<TKey>,\n ctx: Ctx,\n dispatch: (msg: M) => void,\n ) => () => void;\n\n /**\n * Outbound send. The Cmd handler calls this; the battery's handle table\n * (built when subscribe ran) routes to the live transport. If the seam\n * is closed (no active sub), the send is dropped honestly (logged, not\n * thrown — the reducer already moved past caring, same shape as Rule 2\n * fire-and-forget Cmds).\n */\n readonly send: (key: TKey, outbound: Outbound) => void;\n\n /** Pre-derived subId for `(key)` — handy for deadline Subs keyed to the same seam. */\n readonly subIdFor: (key: TKey) => SubId;\n\n /**\n * Pair this seam with a state-gate, producing a dep-keyed Sub for the\n * machine's `subs` array. `when(state)` returns the seam's KEY when it\n * should be open, or `null` when it should be torn down. The kernel derives\n * the id from `structuralHash(key)` and reconciles the seam's lifetime — so\n * the author neither lists this Sub in a central `subscriptions(state)` nor\n * writes its id. Replaces `subscriptions: (s) => active(s) ? [hands.sub(...)] : []`\n * + `subscribe: { transport: hands.subscribe }` with one `subs` entry.\n *\n * The `source` closes over the battery's own `subscribe` (open inbound +\n * close, wire the handle table) using the same `ctx` the kernel passes every\n * Sub source.\n */\n readonly depKeyed: <S>(\n when: (state: S) => TKey | null,\n ) => DepKeyedSub<S, M, Ctx>;\n}\n\n/**\n * Build the battery. One call per seam at the machine's host file.\n *\n * @example\n * const handsSeam = fromTransport<RunId, HandsInbound, HandsOutbound, Msg, Ctx>({\n * name: \"hands\",\n * openTransport: (runId, ctx) => ctx.openHandsWs(runId),\n * parseInbound: (raw) => parseHandsInbound(JSON.parse(raw)),\n * onInbound: (inbound, runId) => ({ type: \"hands_said\", runId, inbound }),\n * lostMsg: (runId) => ({ type: \"hands_lost\", runId }),\n * serializeOutbound: (out) => JSON.stringify(out),\n * });\n *\n * // In the machine:\n * subscriptions: (state) => state.type === \"auditing\" ? [handsSeam.sub(state.runId)] : [],\n * subscribe: { transport: handsSeam.subscribe },\n *\n * // In interpret:\n * send_hands: async (cmd) => { handsSeam.send(cmd.runId, cmd.outbound); },\n */\nexport function fromTransport<TKey, Inbound, Outbound, M, Ctx>(\n opts: FromTransportOpts<TKey, Inbound, Outbound, M, Ctx>,\n): TransportBattery<TKey, Outbound, M, Ctx> {\n // Handle table — one live transport per key. Lives in this closure for the\n // lifetime of the battery (i.e. the machine's lifetime). Interpret-local;\n // never crosses into reducer state. The same shape as a brain's\n // `pending: Map<callId, deferred>`: imperative handles in a Map keyed on\n // run-identity, not on durable state.\n const live = new Map<string, Transport>();\n\n // Single-sourced on the kernel's `structuralHash`: `\"1\"` (string) and `1`\n // (number) render distinctly, so a key collision can't mis-route an outbound\n // send or overwrite the wrong live transport; non-JSON keys throw loudly.\n const keyString = (k: TKey): string => structuralHash(k);\n\n const subIdFor = (key: TKey): SubId =>\n subId(`${opts.name}:${keyString(key)}`);\n\n const sub = (key: TKey): TransportSub<TKey> => ({\n id: subIdFor(key),\n type: \"transport\",\n key,\n });\n\n const subscribe: TransportBattery<TKey, Outbound, M, Ctx>[\"subscribe\"] = (\n s,\n ctx,\n dispatch,\n ) => {\n // Open the transport. The battery owns the lifetime.\n const t = opts.openTransport(s.key, ctx);\n const k = keyString(s.key);\n\n // ACQUIRE-AS-SUCCESS-VALUE: wire EVERYTHING first, publish to the handle\n // table last. An adapter over an already-CLOSING socket throws while\n // wiring; when `live.set` ran first, that left the transport in the table\n // with NO sub registered — so no cleanup ever ran, `send` wrote into a\n // half-wired seam with no inbound listener, and every subsequent reconcile\n // opened another one: an unbounded leak from one recoverable throw. On the\n // way out we undo exactly what we did (drop the listeners, close the\n // transport) and rethrow, so the substrate records the failure and the\n // battery holds nothing. Same discipline `defineManagedResource` states in\n // its own header — no Handle, no release.\n let offMessage: (() => void) | undefined;\n let offClose: (() => void) | undefined;\n try {\n // Wire inbound. Parse boundary lives here per invariant 8.\n offMessage = t.onMessage((raw) => {\n const parsed = opts.parseInbound(raw, s.key);\n if (parsed === null) return;\n const msg = opts.onInbound(parsed, s.key);\n if (msg === null) return;\n dispatch(msg);\n });\n\n // Wire close. ONE Msg arm — `*_lost`. No heartbeat, no sequence\n // numbers, no \"is the peer still alive\" derivation: the transport's\n // own close IS the liveness signal.\n offClose = t.onClose(() => {\n dispatch(opts.lostMsg(s.key));\n });\n } catch (err) {\n offMessage?.();\n offClose?.();\n try {\n t.close();\n } catch (closeErr) {\n // Boundary log: the wiring failure is the fact worth surfacing, and it\n // is about to be rethrown. A close that also fails must not replace it.\n console.warn(\n `[fromTransport:${opts.name}] close during failed wiring failed`,\n closeErr,\n );\n }\n throw err;\n }\n\n live.set(k, t);\n\n // Cleanup runs when the substrate's reconcileSubs leaves the phase.\n return () => {\n offMessage?.();\n offClose?.();\n live.delete(k);\n try {\n t.close();\n } catch (err) {\n // Boundary log: cleanup-time close failures are fire-and-forget\n // (Rule 2). The reducer is already past caring.\n console.warn(`[fromTransport:${opts.name}] close failed`, err);\n }\n };\n };\n\n return {\n sub,\n subscribe,\n\n send: (key, outbound) => {\n const t = live.get(keyString(key));\n if (t === undefined) {\n // Honest drop. The reducer's Cmd burst can race a `*_lost`\n // transition; the Cmd is fire-and-forget at that point.\n console.warn(\n `[fromTransport:${opts.name}] send dropped — no live transport for key`,\n keyString(key),\n );\n return;\n }\n t.send(opts.serializeOutbound(outbound));\n },\n\n subIdFor,\n\n // Dep-keyed entry: `when` is the gate (the deps slice → the seam key);\n // `source` re-runs `when(state)` to recover the typed key and opens the seam\n // via the battery's own `subscribe`. The kernel only calls `source` when\n // `deps(state)` was non-null, so `when` is non-null here; the key type never\n // escapes the entry (cast-free existential).\n depKeyed: <S>(when: (state: S) => TKey | null): DepKeyedSub<S, M, Ctx> => ({\n deps: when,\n source: (state, dispatch, ctx) => {\n const key = when(state);\n if (key === null) return () => {};\n return subscribe(sub(key), ctx, dispatch);\n },\n }),\n };\n}\n"]}
|