@demlik/tea 0.21.0 → 0.22.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.
Files changed (126) hide show
  1. package/dist/agent/index.d.ts +32 -19
  2. package/dist/agent/index.js +12 -10
  3. package/dist/{chunk-VM7PMFV5.js → chunk-2A5XTKQQ.js} +142 -19
  4. package/dist/chunk-2A5XTKQQ.js.map +1 -0
  5. package/dist/{chunk-EB5OMOXX.js → chunk-7K7SEYCH.js} +16 -15
  6. package/dist/chunk-7K7SEYCH.js.map +1 -0
  7. package/dist/{chunk-GAVLND5C.js → chunk-A3QPMX5M.js} +17 -10
  8. package/dist/chunk-A3QPMX5M.js.map +1 -0
  9. package/dist/{chunk-VHKDUBXC.js → chunk-BVFS3ICC.js} +3 -3
  10. package/dist/{chunk-VHKDUBXC.js.map → chunk-BVFS3ICC.js.map} +1 -1
  11. package/dist/{chunk-4I2LCQKB.js → chunk-CPE5ZQXQ.js} +3 -3
  12. package/dist/{chunk-4I2LCQKB.js.map → chunk-CPE5ZQXQ.js.map} +1 -1
  13. package/dist/chunk-DEAPNMKO.js +11 -0
  14. package/dist/chunk-DEAPNMKO.js.map +1 -0
  15. package/dist/{chunk-BFSZ4L6Y.js → chunk-ETRNSJCR.js} +4 -4
  16. package/dist/{chunk-BFSZ4L6Y.js.map → chunk-ETRNSJCR.js.map} +1 -1
  17. package/dist/chunk-FXWDDNGD.js +98 -0
  18. package/dist/chunk-FXWDDNGD.js.map +1 -0
  19. package/dist/chunk-GFGOQIEC.js +10 -0
  20. package/dist/chunk-GFGOQIEC.js.map +1 -0
  21. package/dist/{chunk-YDF6P74H.js → chunk-IAHEYPYJ.js} +3 -3
  22. package/dist/{chunk-YDF6P74H.js.map → chunk-IAHEYPYJ.js.map} +1 -1
  23. package/dist/{chunk-YCJPLPQQ.js → chunk-J5JNLXO7.js} +3 -3
  24. package/dist/{chunk-YCJPLPQQ.js.map → chunk-J5JNLXO7.js.map} +1 -1
  25. package/dist/{chunk-MBQR3LFW.js → chunk-NFOGYDRS.js} +5 -5
  26. package/dist/{chunk-MBQR3LFW.js.map → chunk-NFOGYDRS.js.map} +1 -1
  27. package/dist/{chunk-Z7IL735U.js → chunk-R2YNDRGL.js} +3 -3
  28. package/dist/{chunk-Z7IL735U.js.map → chunk-R2YNDRGL.js.map} +1 -1
  29. package/dist/{chunk-ZV4WGW74.js → chunk-R5NXOPL2.js} +3 -3
  30. package/dist/{chunk-ZV4WGW74.js.map → chunk-R5NXOPL2.js.map} +1 -1
  31. package/dist/chunk-RMBZ7YH7.js +52 -0
  32. package/dist/chunk-RMBZ7YH7.js.map +1 -0
  33. package/dist/{chunk-HU3Y2AZY.js → chunk-SHXUSTHM.js} +62 -15
  34. package/dist/chunk-SHXUSTHM.js.map +1 -0
  35. package/dist/{chunk-QIE4Y6BK.js → chunk-UGTC33VH.js} +4 -4
  36. package/dist/{chunk-QIE4Y6BK.js.map → chunk-UGTC33VH.js.map} +1 -1
  37. package/dist/{chunk-6NIQIUGR.js → chunk-VH5MYJ2K.js} +4 -4
  38. package/dist/{chunk-6NIQIUGR.js.map → chunk-VH5MYJ2K.js.map} +1 -1
  39. package/dist/{chunk-W6XWI6QE.js → chunk-WZEDIUWR.js} +8 -7
  40. package/dist/chunk-WZEDIUWR.js.map +1 -0
  41. package/dist/{chunk-TMYUDZLE.js → chunk-ZRRET3RP.js} +11 -11
  42. package/dist/chunk-ZRRET3RP.js.map +1 -0
  43. package/dist/{core-BKJW1Kmq.d.ts → core-DNDAEhO2.d.ts} +7 -10
  44. package/dist/devtools/index.d.ts +4 -4
  45. package/dist/do/index.d.ts +98 -35
  46. package/dist/do/index.js +40 -21
  47. package/dist/do/index.js.map +1 -1
  48. package/dist/{drive-loop-Dc6Z8Vbs.d.ts → drive-loop-DlOEv49c.d.ts} +2 -2
  49. package/dist/{durable-effects-CgrLNccA.d.ts → durable-effects-wLWEdy9H.d.ts} +1 -1
  50. package/dist/effect/index.d.ts +52 -26
  51. package/dist/effect/index.js +7 -31
  52. package/dist/effect/index.js.map +1 -1
  53. package/dist/extension/index.d.ts +3 -3
  54. package/dist/extension/index.js +2 -2
  55. package/dist/flow/index.d.ts +13 -13
  56. package/dist/flow/index.js +13 -11
  57. package/dist/flow/index.js.map +1 -1
  58. package/dist/idempotency/index.d.ts +3 -3
  59. package/dist/idempotency/index.js +3 -3
  60. package/dist/{index-1hit3dJ9.d.ts → index-9P1PaXIV.d.ts} +2 -2
  61. package/dist/{index-Cuy1_xTh.d.ts → index-BBLI2WWN.d.ts} +1 -1
  62. package/dist/{index-Z6Uw7C9t.d.ts → index-C1WhBZ6a.d.ts} +4 -5
  63. package/dist/{index-B-VC4qjx.d.ts → index-C92SgNWz.d.ts} +2 -2
  64. package/dist/{index-CYrUWi1c.d.ts → index-CAsUE_d1.d.ts} +4 -4
  65. package/dist/{index-BjwRcjBi.d.ts → index-CO34esWT.d.ts} +2 -2
  66. package/dist/{index-DB8Yn0-K.d.ts → index-COeX9Bmz.d.ts} +11 -9
  67. package/dist/{index-Diyo8WBO.d.ts → index-Cg0QXnzf.d.ts} +2 -2
  68. package/dist/index.d.ts +5 -5
  69. package/dist/index.js +2 -2
  70. package/dist/jev/index.d.ts +8 -8
  71. package/dist/jev/index.js +5 -5
  72. package/dist/laws-DTtCDDlU.d.ts +135 -0
  73. package/dist/loop-DReKGV1X.d.ts +70 -0
  74. package/dist/{machine-BuPTS1QH.d.ts → machine-C0WhOAyB.d.ts} +5 -5
  75. package/dist/machine-viz/index.d.ts +1 -1
  76. package/dist/machine-viz/index.js +2 -2
  77. package/dist/mem/index.d.ts +4 -3
  78. package/dist/mem/index.js +2 -2
  79. package/dist/mem/index.js.map +1 -1
  80. package/dist/node/index.d.ts +57 -9
  81. package/dist/node/index.js +175 -68
  82. package/dist/node/index.js.map +1 -1
  83. package/dist/otel/index.d.ts +28 -12
  84. package/dist/otel/index.js +25 -21
  85. package/dist/otel/index.js.map +1 -1
  86. package/dist/paginate/index.d.ts +4 -4
  87. package/dist/paginate/index.js +5 -5
  88. package/dist/parity/index.d.ts +11 -15
  89. package/dist/parity/index.js +4 -9
  90. package/dist/parity/index.js.map +1 -1
  91. package/dist/pbt/index.d.ts +279 -67
  92. package/dist/pbt/index.js +299 -58
  93. package/dist/pbt/index.js.map +1 -1
  94. package/dist/persistence/index.d.ts +10 -12
  95. package/dist/persistence/index.js +4 -4
  96. package/dist/promise/index.d.ts +95 -13
  97. package/dist/promise/index.js +6 -4
  98. package/dist/react/index.d.ts +34 -22
  99. package/dist/react/index.js +271 -42
  100. package/dist/react/index.js.map +1 -1
  101. package/dist/resilience/index.d.ts +6 -6
  102. package/dist/resilience/index.js +5 -5
  103. package/dist/{run-D0sxbyno.d.ts → run-Cnw4qXj2.d.ts} +86 -17
  104. package/dist/{runtime-types-BPKp2bGo.d.ts → runtime-types-CP-ykwgf.d.ts} +120 -31
  105. package/dist/testing/effect/index.d.ts +162 -9
  106. package/dist/testing/effect/index.js +110 -10
  107. package/dist/testing/effect/index.js.map +1 -1
  108. package/dist/testing/index.d.ts +6 -8
  109. package/dist/testing/index.js +4 -24
  110. package/dist/testing/index.js.map +1 -1
  111. package/dist/testing/promise/index.d.ts +4 -4
  112. package/dist/testing/promise/index.js +5 -5
  113. package/dist/timing/index.d.ts +4 -4
  114. package/dist/timing/index.js +4 -4
  115. package/dist/{types-BiXj7k_k.d.ts → types-S53WDy_h.d.ts} +1 -1
  116. package/dist/work-queue/index.d.ts +4 -4
  117. package/dist/work-queue/index.js +2 -2
  118. package/package.json +18 -18
  119. package/dist/chunk-7Z2IDZ7R.js +0 -34
  120. package/dist/chunk-7Z2IDZ7R.js.map +0 -1
  121. package/dist/chunk-EB5OMOXX.js.map +0 -1
  122. package/dist/chunk-GAVLND5C.js.map +0 -1
  123. package/dist/chunk-HU3Y2AZY.js.map +0 -1
  124. package/dist/chunk-TMYUDZLE.js.map +0 -1
  125. package/dist/chunk-VM7PMFV5.js.map +0 -1
  126. package/dist/chunk-W6XWI6QE.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/pure/core.ts","../src/describe-error.ts","../src/runtime-types.ts"],"names":["acceptedTypes","cell","stateName"],"mappings":"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","file":"chunk-A3QPMX5M.js","sourcesContent":["/**\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 `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 entry\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 the Standard Schema TYPE surface\n * (`import type` from `@standard-schema/spec`), erased at compile time —\n * `Cmd.define` accepts any Standard Schema (zod, Effect Schema through\n * `Schema.toStandardSchemaV1`, …), and it imports no schema library.\n */\n\nimport type { StandardSchemaV1 } from \"@standard-schema/spec\";\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// `Ok` and `E` are carried as PHANTOM type parameters (ADR 0014): the runtime\n// value stays `{ readonly type: T }` — JSON-plain, hashable, replayable — and\n// the two channels ride on optional fields that are never assigned, exactly as\n// `Port.__t` carries its `T`.\n//\n// - `Ok` — the value this Cmd settles with on success. Defaults to `unknown`.\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//\n// A Cmd names no requirements (ADR 0020): which services run it is a fact\n// about the handler that interprets it, not about the journaled Cmd.\n//\n// Both channels are named by `Cmd.define`; a Cmd literal never spells them.\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. `Ok` and `E` are phantom type parameters (ADR 0014): `Ok` is\n * the value this Cmd settles with, and `E` is the `_tag` union it can fail\n * with. A Cmd carries no requirements (ADR 0020) — its handler gets its\n * services from the plain `ctx` handed to `run`.\n */\nexport type Cmd<T extends string = string, Ok = unknown, E = unknown> = {\n readonly type: T;\n /** Phantom — the value this Cmd settles with. Never assigned. */\n readonly __ok?: Ok;\n /** Phantom — the `_tag` union this Cmd can settle with. Never assigned. */\n readonly __e?: E;\n};\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\n// === Outcome: what a `Cmd.define`d handler returns (ADR 0021) ===\n//\n// A handler reports whether the work succeeded and with what; the ENGINE turns\n// that into the Cmd's `<name>_ok` / `<name>_err` Msg. The record is plain and\n// tagged, so the core names no `Result` library and each engine converts its own\n// native result into it at its edge.\n\n/** The result a `Cmd.define`d handler returns: its value, or a declared failure. */\nexport type Outcome<Ok, E> =\n | { readonly _tag: \"Ok\"; readonly value: Ok }\n | { readonly _tag: \"Err\"; readonly error: E };\n\n/**\n * The two builders the Promise engine hands a `Cmd.define`d handler on its\n * ctx: `ok(value)` and `err({ _tag })`, with `err` typed to the def's declared\n * tags.\n */\nexport interface OutcomeHelpers<Ok, E> {\n readonly ok: (value: Ok) => Outcome<Ok, never>;\n readonly err: (error: E) => Outcome<never, E>;\n}\n\n/**\n * Build an {@link Outcome} outside a handler's helpers — in a test that calls a\n * handler directly, or in an adapter converting another result type.\n */\nexport const Outcome = {\n ok: <Ok>(value: Ok): Outcome<Ok, never> => ({ _tag: \"Ok\", value }),\n err: <E>(error: E): Outcome<never, E> => ({ _tag: \"Err\", error }),\n} as const;\n\nfunction isOutcome(value: unknown): value is Outcome<unknown, unknown> {\n if (typeof value !== \"object\" || value === null) return false;\n const tag = (value as { _tag?: unknown })._tag;\n return (\n (tag === \"Ok\" && \"value\" in value) || (tag === \"Err\" && \"error\" in value)\n );\n}\n\n// === Cmd.define: the typed Cmd constructor (ADR 0014 §1, 0015 §1, 0021) ===\n//\n// \"Types on the constructor, data in the record.\" A Cmd built by hand carries\n// no `Ok` and no `E`; 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 Standard\n// Schemas (https://standardschema.dev) — zod passes straight in, Effect Schema\n// through `Schema.toStandardSchemaV1` — and `err` is the `_tag` list a handler\n// may fail with.\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 an `Ok` value the Cmd's `ok`\n * schema rejects. Plain data, so it folds into Model like any settled error;\n * `issues` is the schema'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 a Standard Schema issue list into the JSON-plain `MalformedResult`. */\nexport function malformedResult(\n issues: ReadonlyArray<StandardSchemaV1.Issue>,\n): MalformedResult {\n return {\n _tag: \"malformed_result\",\n issues: issues.map((issue) => ({\n path: (issue.path ?? [])\n .map((segment) =>\n String(typeof segment === \"object\" ? segment.key : segment),\n )\n .join(\".\"),\n message: issue.message,\n })),\n };\n}\n\n/**\n * A schema whose `validate` returned a Promise where the kernel needs an answer\n * now — the `ok` check at the interpret edge, the `args` check in a reducer.\n * A contract breach (ADR 0021 §5): it goes to the error sink.\n */\nexport class AsyncSchemaError extends Error {\n override readonly name = \"AsyncSchemaError\";\n readonly _tag = \"AsyncSchemaError\" as const;\n constructor(\n /** What the schema was checking, e.g. `the \"fetch\" Cmd's ok schema`. */\n public readonly where: string,\n ) {\n super(\n `@demlik/tea: ${where} validated asynchronously. tea checks schemas ` +\n `synchronously, so a schema whose \\`~standard.validate\\` returns a ` +\n `Promise cannot be used here.`,\n );\n }\n}\n\n/**\n * Run a Standard Schema synchronously. Throws {@link AsyncSchemaError} when the\n * schema answers with a Promise; `where` names the check for that message.\n */\nexport function validateSync<T>(\n schema: StandardSchemaV1<unknown, T>,\n value: unknown,\n where: string,\n): StandardSchemaV1.Result<T> {\n const result = schema[\"~standard\"].validate(value);\n if (result instanceof Promise) {\n // Nobody awaits it; keep a late rejection from surfacing as unhandled.\n result.catch(() => {});\n throw new AsyncSchemaError(where);\n }\n return result;\n}\n\n/**\n * A `Cmd.define`d handler failed outside its declared channel: its `Err` carried\n * no `_tag`, or a tag the def does not declare. A contract breach (ADR 0011,\n * 0021 §4): it goes to the error sink, never to `<name>_err`.\n */\nexport class UndeclaredFailureError extends Error {\n override readonly name = \"UndeclaredFailureError\";\n readonly _tag = \"UndeclaredFailureError\" as const;\n constructor(\n public readonly cmdType: string,\n /** The `error` the handler's `Err` carried, verbatim. */\n public readonly failure: unknown,\n /** The tags the def declares. */\n public readonly declared: readonly string[],\n ) {\n super(\n `@demlik/tea: the \"${cmdType}\" handler failed with ${describeTag(failure)}, ` +\n `which its Cmd.define does not declare (declared: ` +\n `${declared.length === 0 ? \"none\" : declared.map((t) => `\"${t}\"`).join(\", \")}). ` +\n `An undeclared failure goes to the error sink, never to \"${cmdType}_err\".`,\n );\n }\n}\n\nfunction describeTag(failure: unknown): string {\n const tag =\n typeof failure === \"object\" && failure !== null\n ? (failure as { _tag?: unknown })._tag\n : undefined;\n return typeof tag === \"string\" ? `_tag \"${tag}\"` : \"a value with no _tag\";\n}\n\n/**\n * A `Cmd.define`d handler returned something the engine cannot settle: any Msg\n * (the engine mints the Cmd's `<name>_ok` / `<name>_err`, never the handler —\n * ADR 0021), or any other value that is neither an {@link Outcome} nor nothing.\n * Also thrown when such a handler dispatches its own `_ok` / `_err` Msg.\n */\nexport class OutcomeContractError extends Error {\n override readonly name = \"OutcomeContractError\";\n readonly _tag = \"OutcomeContractError\" as const;\n constructor(\n public readonly cmdType: string,\n detail: string,\n ) {\n super(\n `@demlik/tea: the \"${cmdType}\" handler ${detail}. A Cmd.define'd ` +\n `handler returns an outcome — \\`ok(value)\\` or \\`err({ _tag })\\` — and ` +\n `the engine mints \"${cmdType}_ok\" / \"${cmdType}_err\" from it.`,\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/** The value `Cmd.define(\"fetch\", …)` builds: `{ type: \"fetch\", ...input }`. */\nexport type CmdValue<\n Name extends string,\n Input extends CmdInput,\n Ok,\n E extends Tagged,\n> = Cmd<Name, Ok, E | MalformedResult> & Readonly<Input>;\n\n/**\n * The Msg the engine mints when a `Cmd.define`d Cmd's handler succeeds:\n * `<name>_ok`, carrying the Cmd and its value. Handle it in `update` to fold\n * the result into state.\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\n/**\n * The Msg the engine mints when a `Cmd.define`d Cmd's handler fails:\n * `<name>_err`, carrying the Cmd and the tagged error. Handle it in `update` to\n * decide what a failure means.\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` mint a settled Msg OUTSIDE the runtime (a `replay` log, a unit\n * test) and take an optional `at`. A handler never calls them: it returns an\n * {@link Outcome}, and inside `run` the interpret edge mints and stamps.\n */\nexport interface CmdDef<\n Name extends string,\n Input extends CmdInput,\n Ok,\n E extends Tagged,\n> {\n (input: Input): CmdValue<Name, Input, Ok, E>;\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, Ok, E>,\n value: Ok,\n at?: number,\n ) => SettledOk<Name, CmdValue<Name, Input, Ok, E>, Ok>;\n readonly err: (\n cmd: CmdValue<Name, Input, Ok, E>,\n error: E,\n at?: number,\n ) => SettledErr<Name, CmdValue<Name, Input, Ok, E>, E>;\n readonly schema: {\n readonly input: StandardSchemaV1<unknown, Input>;\n readonly ok: StandardSchemaV1<unknown, 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, the `ok` schema the edge parses against\n * and the tags an `Err` may carry. Every `CmdDef<…>` is one of these\n * structurally.\n */\nexport type AnyCmdDef = {\n readonly cmdType: string;\n readonly okType: string;\n readonly errType: string;\n readonly schema: { readonly ok: StandardSchemaV1 };\n readonly errTags: ReadonlyArray<string>;\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 handler that invokes\n// another def's handler INSIDE its own — the agent's fanned tool cells — where\n// `run`'s edge sees the carrier's `type`,\n// never the def's, so the base outcome would cross unminted (#66). Settling\n// through `cmdEdgeOf(ctx)` at the site the def's handler is actually invoked\n// keeps one mint, one parse and one clock for the bare and the wrapped machine\n// alike.\n\n/**\n * Settle one handler's return: mint a def's outcome into its `_ok` / `_err`\n * Msg, or pass a hand-written Cmd's return through. Throws on a contract breach.\n */\nexport type CmdEdge = (\n cmd: { readonly type: string },\n returned: 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 (ADR 0021; invariant 8: the boundary parses, the\n * core trusts). For a Cmd one of `defs` builds, the handler's return is:\n *\n * - `Ok` — parsed against the `ok` schema: a pass mints `<name>_ok` carrying\n * the PARSED value (the schema's strip / transform applied), a fail mints\n * `<name>_err` carrying `malformed_result`, so a corrupt result never\n * reaches a reducer cell that would fold it into Model;\n * - `Err` — minted into `<name>_err` when its `_tag` is declared, and thrown\n * as {@link UndeclaredFailureError} when it is not;\n * - nothing — nothing is dispatched;\n * - anything else, a Msg included — thrown as {@link OutcomeContractError}.\n * The engine mints a defined Cmd's Msg, never the handler.\n *\n * Minted Msgs are stamped with `at` from the clock. A Cmd no def builds — a\n * hand-written Cmd's follow-up — passes through untouched.\n */\nexport function cmdEdgeOver(\n defs: Iterable<AnyCmdDef>,\n clock: () => number,\n): CmdEdge {\n return cmdContractOver(defs, clock).settle;\n}\n\n/**\n * Check one Msg a handler dispatches for the Cmd it was handed. Throws on a\n * contract breach; returns when the Msg may be delivered.\n */\nexport type DispatchCheck = (\n cmd: { readonly type: string },\n msg: { readonly type: string },\n) => void;\n\n/** Both halves of ADR 0021 over one def list: the return edge and the dispatch check. */\nexport interface CmdContract {\n /** The edge a handler's return crosses — see {@link cmdEdgeOver}. */\n readonly settle: CmdEdge;\n /**\n * The dispatch half of the ban. A `Cmd.define`d handler may dispatch other\n * Msgs (progress, say), and may dispatch a `<name>_ok` / `<name>_err` that\n * `settle` minted — a detached handler settling through `cmdEdgeOf(ctx)`\n * (ADR 0018's fan-out). It may never dispatch one it built itself: that Msg\n * skipped the `ok` parse and the `at` stamp, and throws\n * {@link OutcomeContractError}. A Cmd no def builds may dispatch anything.\n */\n readonly checkDispatch: DispatchCheck;\n}\n\n/**\n * The edge and the dispatch check over one def list. They share one record of\n * the Msgs this edge minted, which is how the check tells an engine-minted\n * settle from one the handler built by hand.\n */\nexport function cmdContractOver(\n defs: Iterable<AnyCmdDef>,\n clock: () => number,\n): CmdContract {\n const byType = new Map<string, AnyCmdDef>();\n for (const def of defs) byType.set(def.cmdType, def);\n const minted = new WeakSet<object>();\n return {\n settle: (cmd, returned) => {\n const def = byType.get(cmd.type);\n if (def === undefined) return returned;\n if (returned === undefined || returned === null) return undefined;\n if (!isOutcome(returned)) {\n throw new OutcomeContractError(\n def.cmdType,\n describeReturn(def, returned),\n );\n }\n const msg = mint(def, cmd, returned, clock());\n minted.add(msg);\n return msg;\n },\n checkDispatch: (cmd, msg) => {\n const def = byType.get(cmd.type);\n if (def === undefined) return;\n if (msg.type !== def.okType && msg.type !== def.errType) return;\n if (minted.has(msg)) return;\n throw new OutcomeContractError(\n def.cmdType,\n `dispatched its own \"${msg.type}\" Msg`,\n );\n },\n };\n}\n\nfunction describeReturn(def: AnyCmdDef, returned: unknown): string {\n const type =\n typeof returned === \"object\"\n ? (returned as { type?: unknown }).type\n : undefined;\n if (typeof type !== \"string\") {\n return \"returned a value that is not an outcome\";\n }\n if (type === def.okType || type === def.errType) {\n return `returned its own \"${type}\" Msg`;\n }\n return `returned the \"${type}\" Msg`;\n}\n\nfunction mint(\n def: AnyCmdDef,\n cmd: unknown,\n outcome: Outcome<unknown, unknown>,\n at: number,\n): { readonly type: string; readonly cmd: unknown; readonly at: number } & (\n | { readonly value: unknown }\n | { readonly error: unknown }\n) {\n if (outcome._tag === \"Err\") {\n const tag =\n typeof outcome.error === \"object\" && outcome.error !== null\n ? (outcome.error as { _tag?: unknown })._tag\n : undefined;\n if (typeof tag !== \"string\" || !def.errTags.includes(tag)) {\n throw new UndeclaredFailureError(def.cmdType, outcome.error, def.errTags);\n }\n return { type: def.errType, cmd, error: outcome.error, at };\n }\n const parsed = validateSync(\n def.schema.ok,\n outcome.value,\n `the \"${def.cmdType}\" Cmd's ok schema`,\n );\n if (parsed.issues !== undefined) {\n return {\n type: def.errType,\n cmd,\n error: malformedResult(parsed.issues),\n at,\n };\n }\n return { type: def.okType, cmd, value: parsed.value, at };\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 ?? ((_, returned) => returned);\n}\n\n/**\n * The Msgs a handler's settled return dispatches, in order (#324). A plain\n * Cmd's handler returns one Msg, a list of them, or nothing; by the time the\n * return reaches here a `Cmd.define`d one has already been minted into its\n * single `_ok` / `_err` Msg by the edge above. Both engines' loop and `drive`\n * read a return through this one function, so they agree on what it sends.\n */\nexport function followUps<M>(returned: unknown): readonly M[] {\n if (returned === undefined || returned === null) return [];\n return Array.isArray(returned) ? (returned as readonly M[]) : [returned as M];\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\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>\n ?\n | SettledOk<Name, CmdValue<Name, Input, Ok, E>, Ok>\n | SettledErr<Name, CmdValue<Name, Input, Ok, E>, 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> ? Ok : 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> ? E : never;\n\nfunction defineCmd<\n const Name extends string,\n Input extends CmdInput,\n Ok,\n const Tags extends readonly string[],\n>(\n name: Name,\n spec: {\n readonly input: StandardSchemaV1<unknown, Input>;\n readonly ok: StandardSchemaV1<unknown, Ok>;\n readonly err: Tags;\n },\n): CmdDef<Name, Input, Ok, TaggedError<Tags[number]>> {\n type E = TaggedError<Tags[number]>;\n type C = CmdValue<Name, Input, Ok, E>;\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.\n/**\n * What an update cell returns: the `[nextState, cmds]` tuple, typed so that a\n * Promise cannot stand in for it. An `async` cell fails to compile against it.\n */\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// Which form a given machine is (see the `Machine.update` union and the\n// `defineMachine` overloads) 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)`.\n/**\n * Which of the two shapes a machine's `update` takes: a flat `reducer` keyed by\n * Msg type, or a `transitions` table keyed by state type and then Msg type.\n */\nexport type UpdateForm = \"reducer\" | \"transitions\";\n\n// The single structural heuristic, defined ONCE: only `defineMachine` calls it,\n// plus `formOf`'s fallback for a machine built without it (e.g. a plain object\n// literal annotated as `Machine`).\n/**\n * Work out an `update` record's `UpdateForm` from its shape. For a machine, use\n * `formOf`, which prefers the form `defineMachine` already recorded.\n *\n * A reducer's first own value is a function; a transitions table's is a record\n * of functions. An empty record can never dispatch a Msg, so it reads as\n * `reducer`.\n */\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: no reader\n// re-implements the heuristic. The `__form` tag is authoritative because\n// `defineMachine` computes it once, at the typed construction boundary.\n/**\n * Read a machine's `UpdateForm`. Reach for it when code has to treat reducer\n * and transitions machines differently. It prefers the form `defineMachine`\n * recorded, and works the form out from the shape only for a machine that\n * never went through `defineMachine`.\n */\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.\n/**\n * Thrown when a Msg is dispatched to a state that has no update cell for it. It\n * names the Msg type, the state, and the Msg types that state does accept.\n */\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 to it: `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// Every site that steps a machine — `run`'s applyUpdate, `foldUpdates`\n// (replay/foldMsgs), the PBT fold runner, and the withX wrappers — dispatches\n// through THIS function, so production and the verification tools agree on the\n// update form by construction (#275). Pure and dev-check-free:\n// `deepFreeze`/`assertPureResult` stay at the call sites that want them. The\n// missing-cell throw is the named `NoCellError` (#276), never a bare TypeError.\n//\n// The `Outcome`-returning twin is `tryApplyCell` (in `../runtime-types`).\n// Both read the SAME `lookupCell`, so \"which cell\" is decided once.\n/**\n * Run the one update cell that matches `state` and `msg` and return its\n * `[nextState, cmds]`. Use it to step a machine by hand; it throws\n * `NoCellError` when no cell matches.\n */\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// === checkedStep: one fold step 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 (a `null` — a fold that\n// chose no transition — has no shape to check). Both guards compile out of\n// production (`__DEV__`). `run`'s dev-check extension and `foldUpdates` both\n// step through THIS function so the invariant enforcement lives in exactly one\n// place and cannot drift between the runtime and the pure fold.\nexport function checkedStep<S, M extends { type: string }, R>(\n state: S,\n msg: M,\n step: (state: S, msg: M) => R,\n): R {\n if (__DEV__) deepFreeze(state);\n const result = step(state, msg);\n if (__DEV__ && result !== null) assertPureResult(result, msg.type);\n return result;\n}\n\n/**\n * `applyCell` with the development-mode checks that catch an impure cell: the\n * input state is frozen and the result is asserted to be plain data.\n */\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 return checkedStep(state, msg, (s: S, m: M) =>\n applyCell<S, M, C>(machine, s, m),\n );\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// the `withX` wrappers (since removed, ADR 0022) built their flat merged\n// Reducer by iterating `msgKeysOf(base)`, so a Msg missing from row zero got\n// NO cell in the wrapped machine and threw `NoCellError` at dispatch for a Msg\n// the base handles perfectly well.\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.\n/**\n * List every Msg type a machine has an update cell for, across all of its\n * states.\n */\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`/`subs` plus the\n// 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.\n/**\n * What `describeMachine` returns: the Msg types a machine handles and, for a\n * transitions machine, its states and the Msg types each one accepts.\n */\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\n/**\n * Describe a machine's update table as data: its form, its Msg types, and the\n * per-state accept sets of a transitions machine. Use it to build tooling, or\n * to ask what a machine handles without dispatching to it.\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 the full Msg set is the true answer, not a stand-in.\n/**\n * List the Msg types a machine accepts in the state named `stateType`. A\n * reducer machine accepts every one of its Msg types in every state, and a\n * `stateType` with no row in a transitions table accepts none.\n */\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// Each cell is narrowed to its Msg variant via `Extract<M, { type: K }>`. The\n// mapped type is *load-bearing*: it is what rejects a missing key, so there is\n// no `absurd()` helper at call sites, no silent fall-through, no default branch\n// 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)`.\n/**\n * The flat form of `update`: a record with one handler per Msg type, each\n * returning `[nextState, cmds]`. Leaving a Msg type out is a compile error.\n */\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 });\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.\n/**\n * The helpers for building Cmds: `Cmd.define` declares a typed Cmd constructor,\n * and `Cmd.none`, `Cmd.batch`, `Cmd.when` and `Cmd.whenDefined` build the Cmd\n * list an update cell returns.\n */\nexport const Cmd = {\n /**\n * Declare a typed Cmd constructor (ADR 0014, 0021). Returns the builder —\n * `fetch({ url })` yields `{ type: \"fetch\", url }` — carrying the minted Msg\n * builders `fetch.ok(cmd, value)` / `fetch.err(cmd, error)` (for replay\n * logs and tests) and the declaration the runtime edge parses against.\n * `Settled<typeof fetch>` is the two-arm Msg union it settles with;\n * `defineMachine({ cmds: [fetch] })` 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 * });\n *\n * `input` and `ok` take any Standard Schema whose `validate` is synchronous:\n * zod directly, Effect Schema through `Schema.toStandardSchemaV1(...)`. `err`\n * is the `_tag` list the handler may fail with; the runtime adds\n * `malformed_result` for an `Ok` value the `ok` schema rejects.\n *\n * The handler returns an outcome and the engine mints the Msg:\n *\n * fetch: async (cmd, { ok, err }) =>\n * res.status === 404 ? err({ _tag: \"not_found\" }) : ok(await res.json()),\n *\n * A throw or an undeclared tag goes to the error sink, never to `fetch_err`.\n * The handler reads its services off the plain `ctx` handed to `run` (ADR\n * 0020).\n *\n * A Cmd must not wait; see `DepKeyedSub` for anything that watches.\n */\n define: defineCmd,\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.\n/** The branded string that identifies a running Sub. Build one with `subId`. */\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/**\n * A running subscription as its runner sees it: its `type`, the `deps` value\n * the machine's `subs` entry returned, and an `id` derived from both. Use it to\n * declare a machine's Sub union and to type the `sub` argument of a runner.\n *\n * A machine never builds one. It declares `{ type, deps(state) }` in `subs`\n * (see `DepKeyedSub`) and the engine derives the rest. A runner reads its data\n * off `sub.deps`. `id` is `structuralHash({ type, deps })`, so it changes\n * exactly when the type or the deps value does, which is when the engine\n * restarts the runner.\n */\nexport type Sub<T extends string = string, D = unknown> = {\n readonly id: SubId;\n readonly type: T;\n readonly deps: D;\n};\n\n/**\n * The cleanup function a Sub runner returns. The runner opens a resource and\n * returns the function that closes it. The engine calls it when the Sub's\n * `deps` go null (turned off), when they change (restarted: the old `Dispose`,\n * then a fresh runner), and when the runtime stops. A returned Promise is\n * awaited by `stop()`, with a bound.\n */\nexport type Dispose = () => void | Promise<void>;\n\n// === Built-in sub runners: names every engine ships ===\n//\n// Each engine ships a runner for these Sub types, so a machine declares one\n// and passes no `subscribe` entry for it (#270 R1.1). A `subscribe` entry of\n// the same name handed to `run` replaces the built-in (#270 R2.1) — a test\n// swaps in a fake clock that way.\n//\n// `timer` dispatches `deps.msg` once, `deps.ms` after it starts. A changed\n// `ms` or `msg` is a changed `deps`, so the engine restarts the countdown.\n/** The `deps` a `timer` Sub declares: fire `msg` once, `ms` after it starts. */\nexport type TimerDeps<M> = { readonly ms: number; readonly msg: M };\n/** The built-in `timer` Sub, as its runner sees it. */\nexport type TimerSub<M> = Sub<\"timer\", TimerDeps<M>>;\n/** The Sub types every engine ships a runner for. */\nexport type BuiltinSubType = \"timer\";\n/** The built-in Subs a machine over `M` may declare without declaring them. */\nexport type BuiltinSub<M> = TimerSub<M>;\n\n/**\n * The one `id` of a Sub: a structural hash of its `type` and its `deps`\n * value. Same type and same deps → same id → the running Sub is left alone.\n */\nexport function subIdOf(type: string, deps: unknown): SubId {\n return subId(structuralHash({ type, deps }));\n}\n\n// === depsInactive: the dep-keyed gate, defined ONCE ===\n//\n// \"This Sub has no slice in this state\" is one fact every engine's reconcile\n// and `replay`'s desired set read (all through `desiredSub`), so it gets one\n// definition rather than a `deps === null` written at each.\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.\n/**\n * Turn a plain-data value into a stable string that does not depend on object\n * key order. Use it wherever two values must compare equal by content, as the\n * engine does for Sub ids.\n */\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 // A key holding `undefined` is an absent key, as in JSON: `{ name:\n // undefined }` and `{}` are one slice, so they are one id.\n const keys = Object.keys(obj)\n .filter((k) => obj[k] !== undefined)\n .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, U>: what a machine declares in `subs` ===\n//\n// The machine names a Sub's `type` and the slice of state it depends on\n// (`deps`). That is all it says — a Sub is data (#251 R1.4, spike #252). The\n// engine derives the rest:\n//\n// - the **gate** = `deps(state)` nullish ⇒ off in this state (stopped if\n// running); anything else ⇒ on.\n// - the **id** = `structuralHash({ type, deps })` — changes exactly when the\n// slice changes (restart), stable otherwise (left alone). A constant `deps`\n// (`() => ({ name: \"main\" })`) is a Sub that runs for the machine's life.\n// - the **runner** = `subscribe[type]` handed to `run`, or the engine's\n// built-in of that name (`timer`). The runner gets `{ id, type, deps }`.\n//\n// This is the FoldKit `modelToDependencies` shape, and Elm's: a Sub names the\n// state slice it depends on, the kernel keys on that slice, and the code that\n// opens the resource lives with the host, never on the machine.\n//\n// `DepKeyedSub<S, U>` distributes over the Sub union `U`: each variant\n// `Sub<T, D>` becomes `{ type: T; deps: (state: S) => D | null | undefined }`,\n// so an entry's `deps` is checked against the data its runner will read.\n//\n// Strengthens invariant 4 (external lifecycle owned by the substrate) and\n// invariant 7 (identity derived, never hand-authored).\n/**\n * One entry of a machine's `subs`: a Sub `type` plus `deps(state)`, which\n * returns the data the runner needs, or `null` to keep the Sub off.\n */\nexport type DepKeyedSub<S, U extends Sub = Sub> =\n U extends Sub<infer T, infer D>\n ? {\n readonly type: T;\n /**\n * The slice of state this Sub depends on. `null` or `undefined` ⇒ off in\n * this state (see `depsInactive`), so `(s) => s.optionalRunId` gates\n * correctly. Pure (invariant 2). Plain JSON-compatible data only\n * (invariant 1): the structural hash THROWS on a `Date`, `Map`, `Set`,\n * `Error` or class instance rather than collapsing them onto one id.\n */\n readonly deps: (state: S) => D | null | undefined;\n }\n : never;\n\n// === desiredSub: one entry's Sub at one state, derived ONCE ===\n//\n// The engines' reconcile and `replay`'s desired set both ask \"what Sub does\n// this entry want in this state?\", so the answer has one definition: `null`\n// when the entry is off, else `{ id, type, deps }` with the derived id. It may\n// throw — `deps` is user code, and `structuralHash` refuses non-plain data —\n// and each caller decides what a throw means for it.\n/** An entry of `Machine.subs`, read structurally (its `U` erased). */\nexport type SubEntry<S> = {\n readonly type: string;\n readonly deps: (state: S) => unknown;\n};\n\n/** The entries of `machine.subs`, read structurally. */\nexport function subEntriesOf<S>(machine: {\n readonly subs?: ReadonlyArray<unknown>;\n}): readonly SubEntry<S>[] {\n return (machine.subs ?? []) as readonly SubEntry<S>[];\n}\n\n/** The Sub `entry` wants at `state`, or `null` when it is off there. */\nexport function desiredSub<S>(entry: SubEntry<S>, state: S): Sub | null {\n const deps = entry.deps(state);\n if (depsInactive(deps)) return null;\n return { id: subIdOf(entry.type, deps), type: entry.type, deps };\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).\n/**\n * A machine's optional message filter: `ofState` names the identity this\n * instance owns, and `ofMsg` the identity a Msg is addressed to. The engine\n * drops a Msg addressed to a different identity before `update` runs.\n */\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// Subscribers receive every emitted value synchronously (same fanout\n// 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.\n/**\n * A named, typed channel for values leaving the runtime. A Cmd handler sends on\n * it with `ctx.emit(port, value)` and a host listens with\n * `runtime.subscribePort`; create one with `definePort`.\n */\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\").\n/**\n * The `Ctx` of a machine whose handlers read nothing from context. Use it in\n * place of `unknown` to say so on purpose.\n */\nexport type NoCtx = Readonly<Record<never, never>>;\n\n// === HandlerCtx<Ctx>: the ctx a Cmd handler is handed ===\n//\n// The machine's `Ctx` plus the kernel's `emit`. A machine that declares no\n// context (`ctx: undefined`, or `void`) has no Ctx half to add, so that half\n// becomes `unknown` before the intersection — `undefined & PortEmitter` would\n// otherwise reduce to `never` and leave the handler unable to reach `emit`,\n// `ok` or `err` at all (#296). The check is wrapped in a tuple so a `Ctx`\n// that merely MAY be undefined (`Foo | undefined`) is left alone, and `any`\n// is left as `any` rather than narrowed to the kernel's half.\n//\n// Every handler-ctx site builds on this one alias, so the rule lives here.\nexport type HandlerCtx<Ctx> = (0 extends 1 & Ctx\n ? Ctx\n : // biome-ignore lint/suspicious/noConfusingVoidType: `void` catches both a `ctx: undefined` and a `ctx: void` machine; `undefined` alone misses the second\n [Ctx] extends [void]\n ? unknown\n : Ctx) &\n PortEmitter;\n\n// === Interpret<M, C, Ctx>: record-of-handlers form of `interpret` ===\n//\n// Each cell receives the narrowed Cmd and the runtime-augmented Ctx\n// (`HandlerCtx<Ctx>`) and resolves to a follow-up Msg, a list of them, or\n// `void` (fire-and-forget). A list is dispatched in order as follow-ups, the\n// way Elm's `Cmd.batch` answers with several Msgs (#324).\n//\n// **The injected `dispatch` — the typed Cmd→Msg edge.** A leaf handler that\n// resolves on its own returns its follow-ups — one Msg, a list of them, or\n// nothing (`Promise<M | readonly M[] | void>`) — and IGNORES the third\n// argument. A DETACHED handler (one that hands long-running work to\n// `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 `callHandler` in `../internal/engine/loop.ts`); the\n// optionality is purely a backward-compatibility affordance on the TYPE, not a\n// runtime \"maybe absent\". A handler authored via `wrapDetached` receives a\n// NARROWER view of this dispatch (only its declared result-Msg set).\n//\n// A named type so consumers can type the free-standing handler dictionary\n// they hand `run` with `Interpret<MyMsg, MyCmd, MyCtx>` instead of\n// re-declaring the mapped type at every effects module.\n//\n// A cell's `ctx` is the machine's plain `Ctx` plus the kernel's `emit`; tea\n// does no dependency injection (ADR 0020), so every handler reads the same\n// object `run` was handed.\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).\n//\n// **A `Cmd.define`d Cmd's cell returns an `Outcome` (ADR 0021).** Its ctx also\n// carries the `ok` / `err` builders (`OutcomeHelpers`), `err` typed to the\n// def's declared tags, and the engine mints `<name>_ok` / `<name>_err` from\n// what it returns. Such a cell resolves to an outcome or nothing, never a Msg.\n// A hand-written Cmd's cell returns a Msg, a list of Msgs, or nothing.\n/**\n * The Cmd handler table an engine is handed: one async handler per Cmd type.\n * Leaving a Cmd type out is a compile error.\n */\nexport type Interpret<M extends { type: string }, C extends Cmd, Ctx> = {\n [K in C[\"type\"]]: InterpretCell<M, Extract<C, { type: K }>, Ctx>;\n};\n\n/**\n * One cell of {@link Interpret}: the outcome-returning form for a\n * `Cmd.define`d Cmd, the form returning a Msg, a list of Msgs or nothing for a\n * hand-written one. A Cmd is `Cmd.define`d exactly when its `E` phantom is\n * declared (not `unknown`). A returned list is dispatched in order.\n */\nexport type InterpretCell<M extends { type: string }, C extends Cmd, Ctx> =\n unknown extends ErrorsOf<C>\n ? (\n cmd: C,\n ctx: HandlerCtx<Ctx>,\n dispatch?: (msg: M) => void,\n // biome-ignore lint/suspicious/noConfusingVoidType: an interpret handler returns follow-up Msgs or nothing; `void` permits no-return bodies that `M | undefined` would reject\n ) => Promise<M | readonly M[] | void>\n : (\n cmd: C,\n ctx: HandlerCtx<Ctx> & OutcomeHelpers<OkOfCmd<C>, DeclaredErrorsOf<C>>,\n dispatch?: (msg: M) => void,\n // biome-ignore lint/suspicious/noConfusingVoidType: as above — a no-return body is legal\n ) => Promise<Outcome<OkOfCmd<C>, DeclaredErrorsOf<C>> | void>;\n\n/** The value a Cmd settles with; `unknown` for a hand-written Cmd. */\nexport type OkOfCmd<C> = C extends { readonly __ok?: infer Ok } ? Ok : unknown;\n\n/** The failures a `Cmd.define`d Cmd's handler may return: its declared tags. */\nexport type DeclaredErrorsOf<C> = Exclude<ErrorsOf<C>, MalformedResult>;\n\n/**\n * A Cmd handler that reports back through a `dispatch` limited to the Msgs it\n * is allowed to send. Use it for work that outlives the handler call, and adapt\n * it into an `Interpret` cell with `wrapDetached`.\n *\n * Such a handler hands its long-running work to `ctx.waitUntil(...)` and cannot\n * return its terminal Msg inline, because awaiting it would deadlock the serial\n * dispatch tail. So it returns `Promise<void>` and dispatches instead.\n * `Allowed` is the Cmd's declared result-Msg set (e.g.\n * `GraphFinished | GraphFailed`), and `dispatch` takes only those, so a wrong\n * or mistyped terminal Msg fails to compile.\n */\nexport type InterpretDetached<\n C extends Cmd,\n Allowed extends { type: string },\n Ctx,\n> = (\n cmd: C,\n ctx: HandlerCtx<Ctx>,\n dispatch: (msg: Allowed) => void,\n) => Promise<void>;\n\n// === Subscribe<M, U, Ctx>: the sub runners an engine is handed at run ===\n//\n// A returned Promise from the `Dispose` is AWAITED by `stop()` (bounded), so an\n// async teardown a host relies on before evicting the isolate actually\n// completes. Mid-run reconcile does not await it — the reconcile pass is\n// synchronous by construction (invariant 2) — but the promise is tracked from\n// the moment it exists, so `stop()` catches it either way.\n//\n// A runner's `dispatch` never runs a transition on the runner's own call\n// stack (spike #260): the engine queues the Msg behind the step in progress.\n//\n// Strengthens invariant 7 (identity is explicit — the Sub variant set is\n// load-bearing at the type level).\n/**\n * The Sub runner table an engine is handed: one runner per Sub type. Leaving a\n * Sub type out is a compile error. Each runner receives the running Sub\n * (`{ id, type, deps }`), the Ctx and a `dispatch`. It opens its resource,\n * dispatches Msgs from it, and returns the `Dispose` the engine calls when the\n * Sub stops.\n */\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// === InterpretArg / RunHandlers: the handlers an engine is handed at run ===\n//\n// The Cmd handlers live beside the machine, never on it (#251 R1.1): every\n// engine's `run(machine, { interpret, subscribe })` and `/react`'s\n// `useMachine(machine, { interpret, … })` take them in their options. So the\n// requiredness `Machine.interpret` used to carry lives here instead: a machine\n// that emits no Cmd (`C` is `Cmd<never>`) has nothing to interpret and may omit\n// the map, and one that emits a real Cmd union must hand over a handler for\n// every variant. The tuple-wrap (`[C] extends [Cmd<never>]`) disables the\n// distributive conditional, so a real union never degrades to optional because\n// one arm happens to be `Cmd<never>`.\n/**\n * The `interpret` option of an engine's `run`: optional for a machine that\n * emits no Cmd, required — one handler per Cmd variant — for one that does.\n */\nexport type InterpretArg<M extends { type: string }, C extends Cmd, Ctx> = [\n C,\n] extends [Cmd<never>]\n ? { interpret?: Interpret<M, C, Ctx> }\n : { interpret: Interpret<M, C, Ctx> };\n\n/**\n * The `subscribe` option of an engine's `run`: one runner per Sub type the\n * machine declares, except the built-ins (`timer`) the engine already ships.\n * Optional when every declared type is a built-in. An entry named after a\n * built-in replaces it (#270 R2.1), which is how a test drives time.\n */\nexport type SubscribeArg<M extends { type: string }, U extends Sub, Ctx> = [\n Exclude<U[\"type\"], BuiltinSubType>,\n] extends [never]\n ? {\n readonly subscribe?: Partial<\n // `Exclude` drops the subless marker `Sub<never>`, whose `never` type\n // would otherwise match every key.\n Subscribe<M, Exclude<U, Sub<never>> | BuiltinSub<M>, Ctx>\n >;\n }\n : {\n readonly subscribe: Subscribe<\n M,\n Exclude<U, { readonly type: BuiltinSubType }>,\n Ctx\n > &\n Partial<Subscribe<M, BuiltinSub<M>, Ctx>>;\n };\n\n/**\n * The handlers an engine is handed beside a machine: the {@link InterpretArg}\n * Cmd handlers and the {@link SubscribeArg} sub runners. A machine carries\n * neither — it is data, and one machine file runs under any engine.\n */\nexport type RunHandlers<\n M extends { type: string },\n C extends Cmd,\n U extends Sub,\n Ctx,\n> = InterpretArg<M, C, Ctx> & SubscribeArg<M, U, Ctx>;\n\n/**\n * A machine beside the handlers it runs under — what a wrapper, a battery's\n * `toMachine` or an agent host hands around, and what an engine takes apart:\n * `run(wired.machine, { ...wired, ctx })`.\n */\nexport type Wired<\n S,\n M extends { type: string },\n C extends Cmd,\n U extends Sub,\n Ctx,\n> = { readonly machine: Machine<S, M, C, U, Ctx> } & RunHandlers<M, C, U, Ctx>;\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// A machine carries no handlers (#251 R1.1, R1.4). `interpret` and the sub\n// runners are code, and the machine is data: they arrive where the machine is\n// run — `run(machine, { interpret, subscribe })`, `useMachine(machine, { … })`\n// — so one machine file runs unchanged under any engine. Their conditional\n// requiredness lives on {@link RunHandlers}.\n/**\n * A machine as plain data: `init`, `update`, and optionally `subs`, `cmds` and\n * `identity`. Build one with `defineMachine` and hand it to an engine's `run`.\n */\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 * Both fresh and restored init may return a new State and Cmds. Init is\n * pure: it describes effects; handlers perform them. The engine saves the\n * returned State, reconciles its Subs, then runs its Cmds.\n *\n * Put state-conditional resume work here, with the in-flight phase in the\n * returned State so a fast Sub cannot start it again. A host Msg sent after\n * `ready` runs after Subs have opened and supplies no such ordering.\n * Recorded replay starts from captured post-init State without calling init.\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 * The machine's Subs, as data: each entry names a Sub `type` and the state\n * slice it depends on (`deps`). The engine derives the id\n * (`structuralHash({ type, deps })`) and the gate (`deps` non-null), starts\n * the runner for `type` when an entry turns on, leaves it alone while the id\n * holds, restarts it when the id changes, and stops it on `null` or `stop()`.\n *\n * `U` is the machine's own Sub union (`types.sub`); the built-in `timer`\n * (`{ type: \"timer\", deps: (s) => ({ ms, msg }) }`) is always available.\n *\n * Strengthens invariant 4 (lifecycle owned by the substrate) and invariant 7\n * (identity derived, not hand-authored).\n */\n readonly subs?: ReadonlyArray<DepKeyedSub<S, U | BuiltinSub<M>>>;\n /**\n * Phantom — never assigned, never read. `subs` reaches `U` only through a\n * conditional type, which is no inference site, so this is the slot a caller\n * like `run(machine, …)` infers the Sub union from (and so what types its\n * `subscribe` runners). Same device as `Cmd`'s `__ok`. Tuple-wrapped so an\n * empty union (`never`) is still a candidate rather than `undefined`.\n */\n readonly __sub?: readonly [U];\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 * 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};\n\n// === foldUpdates: the single internal fold `replay` and `foldMsgs` share ===\n//\n// Each Msg is dispatched through `applyCell` — the same primitive `run` uses —\n// so every fold site agrees on the reducer-vs-transitions form by construction\n// (no second copy of the dispatch to drift). The caller keeps the returned Cmds\n// (`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`.\n/**\n * Fold a machine's `update` over a list of Msgs from a starting state, and\n * return the final state with every Cmd the cells emitted. `replay` and\n * `foldMsgs` cover the common cases; use this when you need both the state and\n * the Cmds from a state of your choosing.\n */\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// The reconcile step of Gambetta/Valve authoritative-server prediction:\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 entry, which\n// is where the whole runtime-free surface publishes since #51.\n/**\n * Fold a machine's `update` over a list of Msgs from a base state and return\n * only the final state. Use it for client-side prediction: re-apply\n * unacknowledged inputs on top of a server snapshot without running any effect.\n */\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// describeError — the one way this package renders an UNKNOWN throw as a\n// human-readable reason string.\n//\n// Every \"errors are data\" boundary that catches a `catch (e: unknown)` (or a\n// settled `{ error: unknown }`) and needs a display/`reason` string faces the\n// same fork: an `Error` carries a `.message`; anything else (a thrown string,\n// a rejected non-Error, `undefined`) must be coerced. `String(e)` alone loses\n// the message for real `Error`s (it stringifies to `\"Error: …\"` at best, or a\n// bare `\"[object Object]\"`); `.message` alone throws on non-objects. The\n// `e instanceof Error ? e.message : String(e)` idiom threads both — hoisted\n// here so the rendering rule lives once instead of re-inlined at every\n// settled-error surface.\n// ---------------------------------------------------------------------------\n\nexport function describeError(e: unknown): string {\n return e instanceof Error ? e.message : String(e);\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 * engine-neutral `RunHandle` / `BootedRunHandle` host adapters are typed on,\n * the Promise engine's `RuntimeRef` / `BootingRuntime` / `Runtime` handle\n * hierarchy that widens it, `definePort`, the\n * identity-typed constructors `defineMachine` / `asReducer`, and the pure tools\n * `replay` (compose without running) and `tryInterpret` (Railway).\n */\n\nimport { describeError } from \"./describe-error\";\nimport type {\n AnyCmdDef,\n BuiltinSub,\n CmdOf,\n HandlerCtx,\n InterpretDetached,\n Machine,\n Port,\n Reducer,\n RunHandlers,\n Settled,\n Sub,\n Transitions,\n} from \"./pure/core\";\nimport {\n __DEV__,\n assertPureResult,\n type Cmd,\n deepFreeze,\n desiredSub,\n detectUpdateForm,\n foldUpdates,\n lookupCell,\n NoCellError,\n Outcome,\n subEntriesOf,\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/**\n * A `Reducer` or `Transitions` value that went through `asReducer` or\n * `defineMachine`. It carries the phantom brand and otherwise behaves exactly\n * like the unbranded value.\n */\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 * ```ts\n * import { absurd } from \"@demlik/tea\";\n *\n * type Msg = { type: \"a\" } | { type: \"b\" };\n *\n * function label(msg: Msg): string {\n * switch (msg.type) {\n * case \"a\": return \"A\";\n * case \"b\": return \"B\";\n * default: return absurd(msg); // compile error if a \"c\" is added\n * }\n * }\n * ```\n */\nexport function absurd(x: never): never {\n throw new Error(`unreachable: ${JSON.stringify(x)}`);\n}\n\n// Naming the no-op forces the author to *decide* \"this cell does nothing\" (a\n// real decision), distinct from \"I forgot to write this cell\" (which the mapped\n// type rejects); an implicit wildcard would silently swallow a future Msg\n// variant that should be handled. Assignable to any Transitions cell regardless\n// of S/M/C concrete types.\n/**\n * An update cell that ignores its Msg: it returns the state unchanged, with no\n * Cmds. Use it to say a state deliberately does nothing for a Msg.\n */\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. It mechanizes invariant 7 (identity is explicit) at the runtime\n * layer the 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 * 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 * - `\"interpret\"` — a `Cmd.define`d handler failed outside its declared\n * channel (ADR 0021): it threw, returned an `Err` whose tag it does not\n * declare (`UndeclaredFailureError`), or returned something the engine cannot\n * mint (`OutcomeContractError`, `AsyncSchemaError`). No `_err` Msg is\n * dispatched, and the dispatch that emitted the Cmd still resolves.\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, or\n * the `telemetry` sink threw or rejected.\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 * - `\"sub\"` — a running Sub failed with an error it did not turn into a Msg:\n * its runner threw while starting, or (Effect engine) its Stream failed. The\n * run stops — on the Effect engine by closing its Scope with the failure. A\n * Sub that expects an error maps it to a Msg itself; there is no hook for it\n * here.\n * - `\"discard\"` — work lost to a teardown the host asked for. Four witnesses,\n * each carrying a `RuntimeDiscardNotice`: `stop()` was called while interpret\n * handlers were still awaiting (`RuntimeDiscardedError`), a Msg that\n * arrived DURING `stop()`'s drain, or from a handler `stop()` gave up on, and\n * so could not be delivered (`DispatchDiscardedError`), a drain that did not\n * finish inside `disposeTimeoutMs`, which also counts the Msgs that were still\n * queued (`DrainTimeoutNotice`), and teardown work that did not settle inside\n * `disposeTimeoutMs`\n * (`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 *\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 | \"interpret\"\n | \"stop-save\"\n | \"reduce\"\n | \"listener\"\n | \"observer\"\n | \"event\"\n | \"boot\"\n | \"port-emit\"\n | \"sub-cleanup\"\n | \"sub\"\n | \"discard\"\n | \"identity-drop\";\n\n/**\n * What the `telemetry` sink passed to `run` receives, once per APPLIED\n * transition. Plain data, so a recorded stream stays durable.\n */\nexport interface TelemetryEvent {\n /** This run's applied transitions so far, counted from 1. Boot is not one. */\n readonly seq: number;\n /** The `Msg.type` that drove the transition. */\n readonly msgType: string;\n /** When the transition committed, read off `run`'s `clock` (ms since epoch). */\n readonly at: number;\n}\n\n/**\n * The `telemetry` option of `run`: a fire-and-forget sink. The run never waits\n * on it, and a throw or rejection reaches `onError` under `\"observer\"` without\n * touching the run.\n */\nexport type TelemetrySink = (event: TelemetryEvent) => void | Promise<void>;\n\n/** Context handed to an `OnError` sink alongside the error itself. */\nexport interface RuntimeErrorContext {\n readonly phase: RuntimeErrorPhase;\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 *\n * Optional, except beside a fenced store (see {@link StoreAndOnError}): there it\n * does not compile without one, and a run whose store is fenced at runtime is\n * refused at start without one, whatever its type says. With no\n * sink a `RuntimeDiscardNotice` is warned, and every other failure is rethrown on\n * a fresh macrotask, which ends a Node process and every run in it. That includes\n * a failing Sub (`\"sub\"`). A host running several machines in one process passes\n * a sink that decides what one run's failure means for the rest.\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; `done()`\n// rejects with the throw. Never a silent resume. The run then\n// stops itself, as after a Sub failure and as a crashed OTP\n// process ends: its Subs close, the final save runs, and on the\n// Effect engine its Scope closes (ADR 0033).\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// A Msg the current State has no cell for is NOT a reducer throw — no cell\n// ran — so its `NoCellError` bypasses every strategy: that dispatch rejects,\n// nothing is reported under `\"reduce\"`, and the run stays live (#310).\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 | {\n /**\n * The default. A reducer throw stops the run by itself, the same stop a\n * Sub failure starts: the Msgs already in line fold, then the Subs close,\n * the final save runs and, on the Effect engine, the run's own Scope\n * closes, so a run `spawn` started leaves the host's table and its\n * `notify` runs. `done()` fails with the throw. A later `stop()` from the\n * host does nothing more.\n */\n readonly strategy: \"stop\";\n }\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 * What `done()` rejects with once a Sub's failure the Sub did not map to a Msg\n * has stopped the run, which can then never reach a terminal State. `cause` is\n * what the Sub failed with, the same value `onError` heard under `\"sub\"`.\n */\nexport class SubFailedError extends Error {\n override readonly name = \"SubFailedError\";\n readonly _tag = \"SubFailedError\" as const;\n constructor(public override readonly cause: unknown) {\n super(\"@demlik/tea: a Sub failed and stopped the run.\");\n }\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, 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, up to\n * `disposeTimeoutMs`, 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 * Reported to the `OnError` sink under `phase: \"discard\"` when `stop()`'s wait\n * for the queue hits `disposeTimeoutMs` (ADR 0025): a Cmd handler, a save or\n * detached work had not returned.\n *\n * `stop()` resolves by contract, so it gives up on that work instead of waiting\n * for it without limit. It then stops the Subs and runs the final save as it\n * always does. The work it gave up on is not recalled — a Promise cannot be\n * cancelled — so a handler may still be running after `stop()` has returned.\n * Whatever it returns later is dropped, and so are the Msgs queued behind it.\n * The rest of its step's Cmds are skipped: no handler starts for them, and they\n * get no notice of their own. None of it is saved.\n *\n * `droppedMsgs` is how a host learns what it lost. It counts the Msgs queued\n * behind the stuck work when `stop()` gave up, per Msg type: Msgs handed to\n * `dispatch` or `tell`, and those a handler or a Sub sent. It carries types and\n * counts only, never a payload, so a sink can log it. It is read once and does\n * not change. A Msg it counts is not reported again: if the handler returns\n * late, a `dispatch` caller's promise rejects with a `DispatchDiscardedError`,\n * and a Msg with no caller reaches the sink no second time. If the handler\n * never returns, those promises never settle, and this count is the only word.\n *\n * tea starts no store call after `stop()` has returned. A store call already\n * under way when `stop()` gave up is not cancelled and can finish afterwards;\n * on a plain store that late save can overwrite what a newer run saved, and a\n * fenced store refuses it.\n *\n * `cmdTypes` names the Cmd of each handler call still awaiting, one entry per\n * call. `pendingCmds` counts those plus any detached work, the same count\n * `RuntimeDiscardedError` carries.\n */\nexport class DrainTimeoutNotice extends RuntimeDiscardNotice {\n override readonly name = \"DrainTimeoutNotice\";\n readonly _tag = \"DrainTimeoutNotice\" as const;\n constructor(\n public readonly cmdTypes: readonly string[],\n public readonly pendingCmds: number,\n public readonly timeoutMs: number,\n public readonly droppedMsgs: Readonly<Record<string, number>> = {},\n ) {\n const dropped = Object.entries(droppedMsgs);\n super(\n `@demlik/tea: stop() gave up waiting for the queue after ${timeoutMs}ms ` +\n `with ${pendingCmds} Cmd(s) still in flight` +\n (cmdTypes.length > 0\n ? ` (${cmdTypes.map((type) => `\"${type}\"`).join(\", \")})`\n : \"\") +\n (dropped.length > 0\n ? ` and these Msgs queued: ${dropped\n .map(([type, count]) => `\"${type}\" x${count}`)\n .join(\", \")}`\n : \"\") +\n ` — whatever they return, the rest of their step and the Msgs queued ` +\n `behind them are dropped. No store call starts after stop() has ` +\n `returned; one already under way can still land. Bound the ` +\n `handler's own IO so it returns, 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 also the rejection of the work `stop()` gave up on (see\n * `DrainTimeoutNotice`): a Msg a stuck handler produces after `stop()` has\n * returned, and a Msg that was accepted before `stop()` and was still queued\n * behind that handler.\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}\" was discarded by stop() — it arrived ` +\n `while the runtime was stopping, or was still waiting behind a Cmd ` +\n `handler stop() gave up on. stop() refuses new work so the drain ` +\n `terminates. If it is the result of a Cmd that outlived its runtime, ` +\n `keep the runtime alive until the Cmd settles (in React: stabilize ` +\n `useMachine's ctx) if 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, with three answers:\n// - `S` on a recognized shape — the substrate passes it to `init` as `loaded`;\n// - `null` when nothing was saved — `init(null)`, the fresh-boot path;\n// - `refuse(reason)` for saved bytes it cannot read (#316).\n//\n// A refusal stops `run`: `ready` rejects with a `StoreRefusedError` and nothing\n// is written, so the bytes stay exactly as they were. A throw from `load` or\n// `migrate` is read the same way. Booting fresh over bytes nobody could read\n// would overwrite them on the first save, so a buggy migration would wipe the\n// user's saved state for good. Whether it was corrupt storage or a migration\n// not yet written is the host's call to make, never a silent fresh start.\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.\n/**\n * Where an engine loads and saves a machine's state. Implement `load`, `save`\n * and `migrate` to persist to your own storage, or use a store an adapter\n * ships.\n */\nexport interface Store<S> {\n load(): Promise<unknown>;\n save(state: S): Promise<void>;\n migrate(raw: unknown): Migrated<S>;\n}\n\n/**\n * What `Store.migrate` answers: the parsed `S`, `null` when nothing was saved,\n * or a {@link Refusal} for saved bytes it cannot read.\n */\nexport type Migrated<S> = S | null | Refusal;\n\n/**\n * `migrate`'s answer for saved bytes it cannot read. Build one with\n * {@link refuse}. A class, so no plain State object can pass for one.\n */\nexport class Refusal {\n readonly _tag = \"refusal\" as const;\n constructor(readonly reason: string) {}\n}\n\n/**\n * Refuse saved bytes from `Store.migrate`. `run` then fails with a\n * {@link StoreRefusedError} carrying `reason`, and writes nothing to the store.\n *\n * ```ts\n * migrate: (raw) => {\n * if (raw === null) return null; // nothing saved: boot fresh\n * return isState(raw) ? raw : refuse(\"not a saved State\");\n * }\n * ```\n */\nexport function refuse(reason: string): Refusal {\n return new Refusal(reason);\n}\n\n/**\n * `ready` rejects with this when the saved state could not be restored:\n * `migrate` returned {@link refuse}, or `load` / `migrate` threw (that throw is\n * the `cause`). The run never booted and wrote nothing, so the stored bytes are\n * unchanged.\n *\n * A host that wants a \"couldn't restore\" view catches it and starts its own run\n * with no store; tea has no placeholder mode.\n */\nexport class StoreRefusedError extends Error {\n override readonly name = \"StoreRefusedError\";\n readonly _tag = \"store_refused\" as const;\n constructor(\n readonly reason: string,\n options?: { readonly cause?: unknown },\n ) {\n super(\n `@demlik/tea: store refused — ${reason}. The saved state was not ` +\n `restored and nothing was written.`,\n options,\n );\n }\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.\n/**\n * What a fenced store's `loadFenced` returns: the raw saved value and the\n * version it was written at.\n */\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/**\n * A `Store<S>` that can remove what it saved — how a host forgets a run.\n *\n * The same optional widening as {@link FencedStore} (ADR 0017): `Store<S>` is\n * unchanged, so every external implementor still compiles. `fileStore`,\n * `memoryStore` and `doStore` return one, fenced and unfenced alike.\n *\n * After `delete()`, `load()` returns what a never-saved store returns, so the\n * next `run` boots fresh. The store stays dumb about who deletes: an unfenced\n * `save` after `delete()` simply writes the state again. A fenced store drops\n * its version with the state, so a run still live on it is refused with a\n * {@link StoreConflictError} at its next save. Deleting under a live run is the\n * host's mistake to avoid.\n */\nexport interface DeletableStore<S> extends Store<S> {\n /** Remove the saved state. Idempotent: deleting nothing resolves. */\n delete(): Promise<void>;\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 * A `Store<S>` whose type says it is not fenced. A plain `Store<S>` fits it and\n * a {@link FencedStore} does not. It is what lets {@link StoreAndOnError} tell the\n * two apart, because a `FencedStore` is otherwise also a `Store`.\n */\nexport type UnfencedStore<S> = Store<S> & { readonly fenced?: never };\n\n/**\n * The `store` and `onError` options of a run: a fenced store needs an `onError`,\n * and the mistake does not compile (ADR 0031).\n *\n * Losing a fence is routine for a host that moves runs between processes, and\n * with no `onError` the default sink rethrows the conflict and ends the process,\n * along with every other run in it. A conflict can reach the sink at any save\n * with no caller to reject at: `\"stop-save\"` from `stop()`, `\"follow-up\"` from a\n * Msg a Sub or a Cmd sent. So the sink is required at the type, not left to be\n * remembered.\n *\n * It reads a store's declared type. A fenced store first assigned to a variable\n * typed plain `Store<S>` has given that type up, so it compiles with no\n * `onError`. Both engines then refuse it at start, before anything is loaded:\n * the Promise engine's `run` throws, and the Effect engine's dies. A JavaScript\n * caller is refused the same way.\n */\nexport type StoreAndOnError<S> =\n | { readonly store?: UnfencedStore<S>; readonly onError?: OnError }\n | { readonly store: Store<S>; readonly onError: OnError };\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).\n/**\n * The minimal validator shape `schemaMigrate` accepts: an object with\n * `safeParse`. A zod schema satisfies it.\n */\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. Nothing saved (`null` or `undefined`) returns `null`, the\n * fresh-boot path. Saved bytes the schema rejects, or that make `upcast` throw,\n * return a {@link refuse}, so `run` fails instead of booting fresh over them.\n */\nexport function schemaMigrate<S>(\n schema: Schema<S>,\n upcast: (raw: unknown) => unknown = (raw) => raw,\n): (raw: unknown) => Migrated<S> {\n return (raw: unknown): Migrated<S> => {\n if (raw === null || raw === undefined) return null;\n let migrated: unknown;\n try {\n migrated = upcast(raw);\n } catch (err) {\n return refuse(`upcast threw on the saved state (${describeError(err)})`);\n }\n const parsed = schema.safeParse(migrated);\n return parsed.success\n ? parsed.data\n : refuse(\"the saved state does not match the schema\");\n };\n}\n\n// === DispatchSettle: how far a dispatch awaits ===\n//\n// `\"quiescent\"` is the default because it is the SAFE one: were the default one\n// transition, an `interpret` follow-up Msg would enqueue a fresh transition\n// fire-and-forget relative to the original `dispatch`, resolving \"early\". Its\n// drain is the same one `idle()` performs. `dispatchOnce` is the convenience\n// spelling of `\"once\"`.\n/**\n * How long a `dispatch` waits before it resolves: `quiescent`, the default,\n * waits for every follow-up Msg to drain, and `once` waits for the single\n * transition.\n */\nexport type DispatchSettle = \"quiescent\" | \"once\";\n\n// === RuntimeRef<M>: typed sibling-runtime handle ===\n//\n// Holding a *sibling* runtime is composition by reduction across orthogonal\n// lifecycles (invariant 5): the holder learns the Msg shape it can send, nothing\n// about the referenced runtime's State/Cmd/Sub/Ctx/observers/Port fanout.\n// `Runtime<S, M>` extends `RuntimeRef<M>` structurally.\n/**\n * The dispatch-only view of a runtime. Use it as the type of a handle one\n * runtime holds in order to send Msgs to another.\n */\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// === RunHandle: the handle host adapters are typed on (#281, #250) ===\n//\n// The part of a running machine a host adapter needs and nothing an engine has\n// to invent, so `/react` and `/do` are typed against it and never against one\n// engine's runtime. The Promise engine's `run` returns one. The Effect engine's\n// handle keeps these member names but returns Effects where this returns\n// Promises (#308, ruling R4.1 of #325), so it is not a `RunHandle`. It splits\n// the same way the Promise engine's handle does: before boot there is no State\n// to read, so `getState` lives only on the `BootedRunHandle` that `ready`\n// resolves to.\n\n/**\n * A running machine's handle: queue a Msg, listen, wait for boot, stop.\n * `getState` is not here — there is no State until boot runs, so it lives on\n * the {@link BootedRunHandle} that `ready` resolves to. `E` is the machine's\n * semantic event union (see `on`); `never` when the run projects none.\n */\nexport interface RunHandle<\n S,\n M extends { type: string },\n E extends { type: string } = never,\n> {\n /** Put a Msg in the inbox; resolves once the engine has processed it. */\n dispatch(msg: M): Promise<void>;\n /**\n * A zero-arg change notifier, fired for each applied transition after its\n * save and before its first Cmd's handler starts.\n */\n subscribe(listener: () => void): () => void;\n /** A `(msg, state)` hook, fired after each applied transition's Cmds. */\n observe(observer: (msg: M, state: S) => void): () => void;\n /** Fires once with the initial State — at once if boot already ran. */\n onBoot(handler: (state: S) => void): () => void;\n /** Subscribe to the semantic event of `type` the run's `events` projects. */\n on<K extends E[\"type\"]>(\n type: K,\n handler: (event: Extract<E, { type: K }>) => void,\n ): () => void;\n /** Resolves to the booted handle once boot completes. */\n readonly ready: Promise<BootedRunHandle<S, M, E>>;\n /** Stop the run; resolves once the engine has torn it down. */\n stop(): Promise<void>;\n}\n\n/** A {@link RunHandle} whose boot has completed, so its State exists. */\nexport interface BootedRunHandle<\n S,\n M extends { type: string },\n E extends { type: string } = never,\n> extends RunHandle<S, M, E> {\n /** The current State. Total. */\n getState(): S;\n readonly ready: Promise<BootedRunHandle<S, M, E>>;\n}\n\n/**\n * The options every engine's `run` accepts: the `ctx`, the handlers the\n * machine runs under, an optional `store` with the `onError` a fenced one needs,\n * and the `events` projector that feeds `on`. An engine may take more; a host\n * adapter hands only these.\n */\nexport type RunOptions<\n S,\n M extends { type: string },\n C extends Cmd,\n U extends Sub,\n Ctx,\n E extends { type: string } = never,\n> = CtxArg<Ctx> &\n RunHandlers<M, C, U, Ctx> &\n StoreAndOnError<S> & {\n readonly events?: (msg: M, state: S) => readonly E[];\n };\n\n/**\n * An engine's `run`, seen from a host adapter: a machine and its\n * {@link RunOptions} in, a {@link RunHandle} out. `useMachine` and\n * `createAgentHost` take one — `run` from `@demlik/tea/promise` fits it as it\n * is.\n */\nexport type EngineRun<\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 opts: RunOptions<S, M, C, U, Ctx, E>,\n) => RunHandle<S, M, E>;\n\n// === BootingRuntime: handle returned SYNCHRONOUSLY from run() ===\n\n/**\n * What the Promise engine's `run` returns, the instant it is called, while boot\n * is still in flight: its {@link RunHandle}, widened with Ports and\n * `dispatchOnce`. It exposes exactly the surface total before boot — queue a\n * dispatch, subscribe, observe, wire a Port, stop. Reading State (`getState`)\n * and waiting for quiescence (`idle`) need the initial State to exist, so they\n * live on the {@link Runtime} that `ready` resolves to; \"read State before boot\"\n * is a compile 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).\n */\nexport interface BootingRuntime<\n S,\n M extends { type: string },\n E extends { type: string } = never,\n> extends RuntimeRef<M>,\n RunHandle<S, M, E> {\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 once for every applied\n * transition, after its save and before its first Cmd's handler starts, so a\n * view shows the State while that State's Cmds run. `getState()` inside the\n * listener reads the new State, not the State before. A failed save fires\n * nothing. The listener does not mean the Cmds are done: `observe`, `on` and\n * `done()` hear after them. A `dispatch` issued from the listener is SCHEDULED\n * onto the serial tail behind the fold that fired it, never folded re-entrantly\n * and never discarded, so it needs no `setTimeout(fn, 0)` deferral; it folds\n * ahead of what that fold's Cmds return, and two listeners issuing in order\n * 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/**\n * The Promise engine's booted handle — what {@link BootingRuntime}'s `ready`\n * resolves to once boot completes. It adds the members only meaningful once the\n * initial State exists — `getState()` (total), `idle()` (quiescence), and the\n * `result()` / `done()` reads of the terminal State — and narrows `ready` to\n * resolve to itself. You never construct one directly; you obtain it via\n * `await bootingRuntime.ready`, which makes \"read State before boot\"\n * unrepresentable rather than merely discouraged.\n */\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 saved 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. With a store, returns `undefined`\n * until the current State's save succeeds, including after a failed save.\n * Without a store, answers as soon as State is set. Total — never throws, so a\n * run a failure closed reads `undefined` here; `done()` says why.\n */\n result(): S | undefined;\n /**\n * Resolves with the terminal State only once it is saved (per the `terminal`\n * predicate). If ALREADY saved and terminal, resolves immediately; otherwise\n * on that terminal commit. Rejects with the save failure if a terminal State\n * cannot be saved, for both waiting and later callers. When a failure closes\n * the run short of a terminal State, it rejects for both waiting and later\n * callers too: with `SubFailedError` for a Sub failure the Sub did not map to\n * a Msg, and with what was thrown for a reducer throw under the `stop`\n * strategy. It answers that only after the Msgs already in line have folded,\n * because one of them can still reach a terminal State, and then the State is\n * the answer. A `stop()` with no failure leaves it pending. Without a store,\n * answers as soon as State is set. The awaitable companion to `result()`. With\n * no predicate this resolves never, and rejects only on those failures.\n * Idempotent and 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`. 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 that declares Subs other than the built-in\n * `timer` (its union of `Sub<type, deps>`); `ctx` only by one whose `init`\n * reads a `Ctx` or whose handlers are typed against one.\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.\n/**\n * Define a machine: its `init`, its `update` (a reducer or a transitions\n * table), and optionally its `subs`, `cmds` and `identity`. Every tea program\n * starts here; the result is plain data you hand to an engine's `run`.\n */\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// The parameter type's every cell returns the non-thenable `SyncReturn<S, C>`,\n// so 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.\n/**\n * Type-check a standalone reducer record and return it branded. Use it when you\n * write `update` apart from `defineMachine`.\n */\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 a pure reducer runs as\n// `run(machine)` and the omitted `ctx` defaults to `{}`.\n// `[Record<never, never>] extends [Ctx]` reads as \"is `{}` assignable to `Ctx`\"\n// — true for the context-free shapes, false for `{ db: … }`; the tuple-wrap\n// disables distributive conditional behavior.\n/**\n * The `ctx` field of an engine's options: optional when the machine's `Ctx` is\n * empty, required otherwise.\n */\nexport type CtxArg<Ctx> = [Record<never, never>] extends [Ctx]\n ? { ctx?: Ctx }\n : { ctx: Ctx };\n\n/**\n * Run a machine's `init` and then its `update` over a list of Msgs, with no\n * engine, store or effects. Use it in unit tests to assert the final state, the\n * Cmds emitted, and the Subs that would be running.\n *\n * It composes `init(loaded ?? null, ctx)` and then `update(state, msg)` for each\n * Msg. Restored init may change State and emit Cmds; those Cmds are collected\n * alongside update Cmds. No handler, Store or Sub runner is called.\n * Recorded traces instead use `replayTrace` to fold their captured post-init State.\n *\n * `subs` is each `machine.subs` entry that is on at the final state, as its\n * runner would see it: `{ id, type, deps }`, the id derived exactly as the\n * engine derives it, deduplicated by id the way the engine runs them. So a test\n * asserts \"the retry timer is armed in `waiting`\" without wiring a runner.\n */\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 | BuiltinSub<M>)[];\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 // `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 // The desired set at the final state, through the one derivation the\n // engines reconcile with (`desiredSub`) — never a runner.\n const byId = new Map<string, U | BuiltinSub<M>>();\n for (const entry of subEntriesOf<S>(machine)) {\n const sub = desiredSub(entry, state);\n if (sub !== null && !byId.has(sub.id)) {\n byId.set(sub.id, sub as U | BuiltinSub<M>);\n }\n }\n\n return { state, cmds, subs: [...byId.values()] };\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// its follow-ups inline (`Promise<M | readonly M[] | void>`) and never touches\n// `wrapDetached`. Only the detached sites adopt it. The wrapped result is\n// structurally a plain cell, so the `interpret` 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).\n/**\n * Adapt an `InterpretDetached` handler into an ordinary `interpret` cell. Use\n * it for a Cmd whose work finishes after the handler returns and reports back\n * through `dispatch`.\n */\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: HandlerCtx<Ctx>,\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 core's own\n// `Outcome` record (ADR 0021), the same one a `Cmd.define`d handler returns.\n//\n// PLACEMENT: these live here and not in `pure/core` because they are the\n// caller-facing skins; the pure half of the work is the shared `lookupCell`\n// primitive, which DOES live there. `applyCell` and `tryApplyCell` therefore\n// select the same cell by construction, not by two copies of the\n// 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): Outcome<readonly [S, readonly C[]], NoCellError> {\n const found = lookupCell<S, M, C>(machine, state, msg);\n if (found.cell === undefined) {\n return Outcome.err(\n new NoCellError(msg.type, found.stateName, found.acceptedTypes),\n );\n }\n return Outcome.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 an `Outcome` 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 `Outcome<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): Outcome<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 (stepped._tag === \"Err\") {\n return Outcome.err({ index, msg, error: stepped.error });\n }\n if (__DEV__) assertPureResult(stepped.value, msg.type);\n state = stepped.value[0];\n }\n return Outcome.ok(state);\n}\n\n/**\n * Wrap a function that may throw into a Cmd handler that never rejects: success\n * maps to one Msg through `onOk`, failure to another through `onErr`. Use it\n * for a hand-written Cmd; a `Cmd.define`d Cmd does not need it, because its\n * handler returns an `Outcome` and the engine mints the Msg (ADR 0021).\n *\n * A rejection and a synchronous throw both reach `onErr(error, cmd)`, with the\n * original error untouched so `instanceof` checks inside `onErr` hold. The\n * never-rejects promise assumes `onOk` and `onErr` do not throw.\n */\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 let value: Ok;\n try {\n value = await work(cmd, ctx);\n } catch (error) {\n return onErr(error, cmd);\n }\n return onOk(value, cmd);\n };\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { foldMsgs, structuralHash } from './chunk-GAVLND5C.js';
1
+ import { foldMsgs, structuralHash } from './chunk-A3QPMX5M.js';
2
2
 
3
3
  // src/compose/index.ts
4
4
  function liftSlice(key, state, [slice, cmds]) {
@@ -376,5 +376,5 @@ function fromTransport(opts) {
376
376
  }
377
377
 
378
378
  export { NO_ACK, ack, defineListener, defineManagedResource, dispatchIfPresent, fromBroadcastChannel, fromEventSource, fromEventTarget, fromInterval, fromPort, fromReconnectingWebSocket, fromTimeout, fromTransport, fromWebSocket, historyTracker, initAck, liftSlice, nextSeq, partitionByAck, readInOrder, reconcile, tagSeq };
379
- //# sourceMappingURL=chunk-VHKDUBXC.js.map
380
- //# sourceMappingURL=chunk-VHKDUBXC.js.map
379
+ //# sourceMappingURL=chunk-BVFS3ICC.js.map
380
+ //# sourceMappingURL=chunk-BVFS3ICC.js.map