@orkestrel/workflow 0.0.10 → 0.0.12

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.
@@ -19,28 +19,6 @@ import { Success } from '@orkestrel/contract';
19
19
  import { TableInterface } from '@orkestrel/database';
20
20
  import { TokenUsage } from '@orkestrel/budget';
21
21
 
22
- /**
23
- * Assert that a {@link WorkflowSnapshot} carries a `boolean` `bail` — at the workflow tier AND
24
- * on every phase — and that its every node's status (and its `override`, when present) is drawn
25
- * from the lifecycle vocabulary, throwing a `RESTORE` {@link WorkflowError} otherwise.
26
- *
27
- * @remarks
28
- * The boundary-narrowing guard (AGENTS §14) for {@link restoreWorkflow}: a snapshot is
29
- * untrusted JSON, so a status (or an override) outside
30
- * {@link import('./constants.js').WORKFLOW_STATUSES} /
31
- * {@link import('./constants.js').PHASE_STATUSES} / {@link import('./constants.js').TASK_STATUSES},
32
- * a non-boolean `bail` (the workflow's OR any phase's — both are REQUIRED persisted policy), a
33
- * present-but-invalid phase `concurrency` (not a positive integer), or a present-but-invalid task
34
- * `run` (an empty string) / `retries` / `timeout` (not a non-negative integer),
35
- * is rejected loudly (naming the offending node) rather than silently producing a broken tree.
36
- * The `override` / `concurrency` / `run` / `retries` / `timeout` are optional, so each is only
37
- * checked WHEN present. Structural shape beyond these fields is the contract's concern; this
38
- * guards exactly the fields the live state machine reads back.
39
- *
40
- * @param snapshot - The snapshot to validate
41
- */
42
- export declare function assertSnapshot(snapshot: unknown): void;
43
-
44
22
  /**
45
23
  * Build a {@link PhaseContext} — a phase's own identity plus a back-reference to its
46
24
  * workflow — from the parent {@link WorkflowContext} and the phase node's identity.
@@ -152,7 +130,7 @@ export declare function cloneWorkflowSnapshot(input: unknown, id?: string): Work
152
130
  * @param phases - The per-phase result lists, in phase order
153
131
  * @returns One flattened {@link TaskResult} list, in positional order
154
132
  */
155
- export declare function collectResults(phases: readonly (readonly TaskResult[])[]): readonly TaskResult[];
133
+ export declare function collectResults(phases: ReadonlyArray<readonly TaskResult[]>): readonly TaskResult[];
156
134
 
157
135
  /**
158
136
  * The per-unit handle a runner handler receives — wraps the unit's identity,
@@ -282,13 +260,13 @@ export declare interface ControllerInterface<TInput, TResult> {
282
260
  * @example
283
261
  * ```ts
284
262
  * import { createMemoryDriver } from '@orkestrel/database'
285
- * import { createDatabaseWorkflowStore, createWorkflow, restoreWorkflow } from '@orkestrel/workflow'
263
+ * import { createDatabaseWorkflowStore, createWorkflow, createRestoredWorkflow } from '@orkestrel/workflow'
286
264
  *
287
265
  * const store = createDatabaseWorkflowStore(createMemoryDriver()) // a durable driver swaps in here
288
266
  * const workflow = createWorkflow(definition)
289
267
  * await store.set(workflow.snapshot()) // persist the run state (one JSON column)
290
268
  * const snapshot = await store.get(definition.id)
291
- * const restored = snapshot && restoreWorkflow(snapshot) // an identical live tree
269
+ * const restored = snapshot && createRestoredWorkflow(snapshot) // an identical live tree
292
270
  * ```
293
271
  */
294
272
  export declare function createDatabaseWorkflowStore(driver?: DriverInterface): WorkflowStoreInterface;
@@ -315,23 +293,79 @@ export declare function createDeferred<T>(): DeferredInterface<T>;
315
293
  * {@link createDatabaseWorkflowStore} (the snapshot as one opaque JSON column over a `databases`
316
294
  * table) — for a DURABLE store (run-state surviving a restart) pass it a JSON / SQLite / IndexedDB
317
295
  * driver, and it swaps in WITHOUT touching the runner or the entity tree. Restore stays a caller
318
- * concern: read a snapshot back and rebuild the live tree with {@link restoreWorkflow}.
296
+ * concern: read a snapshot back and rebuild the live tree with {@link createRestoredWorkflow}.
319
297
  *
320
298
  * @returns A memory-backed {@link WorkflowStoreInterface}
321
299
  *
322
300
  * @example
323
301
  * ```ts
324
- * import { createMemoryWorkflowStore, createWorkflow, restoreWorkflow } from '@orkestrel/workflow'
302
+ * import { createMemoryWorkflowStore, createWorkflow, createRestoredWorkflow } from '@orkestrel/workflow'
325
303
  *
326
304
  * const store = createMemoryWorkflowStore()
327
305
  * const workflow = createWorkflow(definition)
328
306
  * await store.set(workflow.snapshot()) // persist the run state
329
307
  * const snapshot = await store.get(definition.id)
330
- * const restored = snapshot && restoreWorkflow(snapshot) // an identical live tree
308
+ * const restored = snapshot && createRestoredWorkflow(snapshot) // an identical live tree
331
309
  * ```
332
310
  */
333
311
  export declare function createMemoryWorkflowStore(): WorkflowStoreInterface;
334
312
 
313
+ /**
314
+ * Build an interrupted workflow back to life at its remaining retry budget.
315
+ *
316
+ * @remarks
317
+ * Each phase captures every unique initial `run` binding once before constructing tasks. Recovery
318
+ * validates those live tasks' captured callable handlers without rereading the registry, while the
319
+ * retained registry identity remains available to resolve future live additions at their mint time.
320
+ *
321
+ * @param snapshot - The hostile persisted snapshot
322
+ * @param options - Runtime handlers and entity options
323
+ * @returns A recoverable live {@link WorkflowInterface} root
324
+ *
325
+ * @example
326
+ * ```ts
327
+ * import { createRecoveredWorkflow } from '@orkestrel/workflow'
328
+ *
329
+ * const recovered = createRecoveredWorkflow(snapshot, { functions })
330
+ * recovered.status // 'pending' — interrupted running work returned to its remaining budget
331
+ * ```
332
+ */
333
+ export declare function createRecoveredWorkflow(snapshot: unknown, options?: WorkflowOptions): WorkflowInterface;
334
+
335
+ /**
336
+ * Build an equivalent live W-b entity tree from a {@link WorkflowSnapshot} — the
337
+ * inverse of {@link WorkflowInterface.snapshot}, restoring structure + each node's status
338
+ * + recorded results + positional order + the persisted `#override`.
339
+ *
340
+ * @remarks
341
+ * Round-trip fidelity is paramount: a `snapshot()` → `createRestoredWorkflow()` reproduces the
342
+ * same status at every node (each `#override` restored DIRECTLY from the snapshot's own
343
+ * `override` field, not guessed from a status divergence), the same recorded
344
+ * {@link import('./types.js').TaskResult}s, and the same positional order (an interior
345
+ * `skip` / `remove` survives). The snapshot is SELF-CONTAINED — it persists the `bail`
346
+ * policy it ran under, so the restore re-derives status IDENTICALLY without a silent
347
+ * default; the snapshot's `bail` is the source of truth, while an explicit `options.bail`
348
+ * still wins when supplied (to deliberately re-run under a different policy). A structurally
349
+ * invalid snapshot (a status — or override — outside the lifecycle vocabulary, or a
350
+ * non-boolean `bail`) throws a `RESTORE` {@link WorkflowError}.
351
+ * Runtime handlers are optional: without a matching `functions` entry, a persisted `run`
352
+ * remains visible with an undefined `handler` so the exact state is inspectable. The runner
353
+ * rejects that unresolved tree if execution is attempted.
354
+ *
355
+ * @param snapshot - The snapshot to restore (carries its own `bail` + `override`)
356
+ * @param options - Runtime options (initial listeners, an optional `bail` override, per-node options)
357
+ * @returns The restored live {@link WorkflowInterface} root
358
+ *
359
+ * @example
360
+ * ```ts
361
+ * import { createRestoredWorkflow } from '@orkestrel/workflow'
362
+ *
363
+ * const restored = createRestoredWorkflow(workflow.snapshot()) // bail comes from the snapshot
364
+ * restored.status === workflow.status // true
365
+ * ```
366
+ */
367
+ export declare function createRestoredWorkflow(snapshot: unknown, options?: WorkflowOptions): WorkflowInterface;
368
+
335
369
  /**
336
370
  * Create a thin generic orchestrator that drives declared units — and any they
337
371
  * `spawn` — through a bounded-concurrency queue, collecting their results in order.
@@ -496,11 +530,11 @@ export declare function createWorkflowContract(): ContractInterface<WorkflowDefi
496
530
  * @remarks
497
531
  * `options.functions` flows into every workflow the manager mints (`add`, via
498
532
  * {@link createWorkflow}) or hydrates (`open`'s registry-miss path, via
499
- * {@link restoreWorkflow}), so a hydrated workflow is RUNNABLE rather than a dead snapshot
533
+ * {@link createRestoredWorkflow}), so a hydrated workflow is RUNNABLE rather than a dead snapshot
500
534
  * mirror. `options.store` is the EXACT analogue of the twins' `store` seam — omitted ⇒ the
501
535
  * manager is registry-only (`open` resolves only what is registered, `save` is a no-op). This
502
536
  * is PURELY ADDITIVE: direct {@link WorkflowStoreInterface} use and
503
- * {@link restoreWorkflow} remain valid — the manager is one more caller-driven persistence
537
+ * {@link createRestoredWorkflow} remain valid — the manager is one more caller-driven persistence
504
538
  * seam, not a replacement.
505
539
  *
506
540
  * @param options - The optional `store` seam and the `functions` registry threaded into every mint/hydrate
@@ -603,18 +637,18 @@ export declare function createWorkflowRunner(options?: WorkflowRunnerOptions): W
603
637
  * idle-TTL / eviction — a persisted run-state is durable orchestration state that lives until an
604
638
  * explicit `delete`. The public surface is EXACTLY `get` / `set` / `delete` — no extra members (the
605
639
  * §22 method bijection with {@link WorkflowStoreInterface}). Restore stays a caller concern: read a
606
- * snapshot back and rebuild the live tree with {@link import('../factories.js').restoreWorkflow}.
640
+ * snapshot back and rebuild the live tree with {@link import('../factories.js').createRestoredWorkflow}.
607
641
  *
608
642
  * @example
609
643
  * ```ts
610
644
  * import { createMemoryDriver } from '@orkestrel/database'
611
- * import { createDatabaseWorkflowStore, createWorkflow, restoreWorkflow } from '@orkestrel/workflow'
645
+ * import { createDatabaseWorkflowStore, createWorkflow, createRestoredWorkflow } from '@orkestrel/workflow'
612
646
  *
613
647
  * const store = createDatabaseWorkflowStore(createMemoryDriver()) // a durable driver swaps in here
614
648
  * const workflow = createWorkflow(definition)
615
649
  * await store.set(workflow.snapshot()) // persist the run state (one JSON column)
616
650
  * const snapshot = await store.get(definition.id)
617
- * const restored = snapshot && restoreWorkflow(snapshot) // an identical live tree
651
+ * const restored = snapshot && createRestoredWorkflow(snapshot) // an identical live tree
618
652
  * await store.delete(definition.id) // drop it
619
653
  * ```
620
654
  */
@@ -865,7 +899,7 @@ export declare function hasWorkflowHandlers(workflow: WorkflowSnapshot, function
865
899
  * insertEntry([['a', 1], ['b', 2]], 1, 'c', 3) // [['a', 1], ['c', 3], ['b', 2]]
866
900
  * ```
867
901
  */
868
- export declare function insertEntry<T>(entries: readonly (readonly [string, T])[], index: number, key: string, value: T): readonly (readonly [string, T])[];
902
+ export declare function insertEntry<T>(entries: ReadonlyArray<readonly [string, T]>, index: number, key: string, value: T): ReadonlyArray<readonly [string, T]>;
869
903
 
870
904
  /** Test the workflow lifecycle vocabulary. */
871
905
  export declare function isLifecycleStatus(value: unknown): value is LifecycleStatus;
@@ -943,8 +977,9 @@ export declare function isWorkflowSnapshot(value: unknown): value is WorkflowSna
943
977
  * name + doc while the vocabulary lives in one place (AGENTS §4.4 "one concept = one
944
978
  * word"). It also types the single runtime terminal check
945
979
  * {@link import('./helpers.js').isTerminalStatus} — every tier's value is a
946
- * `LifecycleStatus`, so the one predicate accepts them all. The tiers stay distinct
947
- * types (a phase status is not a task status) even though they currently share a body.
980
+ * `LifecycleStatus`, so the one predicate accepts them all. The three tiers are direct
981
+ * aliases, not branded types, so TypeScript accepts any one of them wherever another is
982
+ * expected. Each name documents which tier a value came from; it does not enforce it.
948
983
  */
949
984
  export declare type LifecycleStatus = 'pending' | 'running' | 'completed' | 'failed' | 'skipped' | 'stopped';
950
985
 
@@ -980,17 +1015,17 @@ export declare const MAX_TIMER_MS = 2147483647;
980
1015
  *
981
1016
  * The public surface is EXACTLY `get` / `set` / `delete` — no extra members (the §22 method
982
1017
  * bijection with {@link WorkflowStoreInterface}). Restore is a caller concern: read a snapshot
983
- * back and rebuild the live tree with {@link import('../factories.js').restoreWorkflow}.
1018
+ * back and rebuild the live tree with {@link import('../factories.js').createRestoredWorkflow}.
984
1019
  *
985
1020
  * @example
986
1021
  * ```ts
987
- * import { createMemoryWorkflowStore, createWorkflow, restoreWorkflow } from '@orkestrel/workflow'
1022
+ * import { createMemoryWorkflowStore, createWorkflow, createRestoredWorkflow } from '@orkestrel/workflow'
988
1023
  *
989
1024
  * const store = createMemoryWorkflowStore()
990
1025
  * const workflow = createWorkflow(definition)
991
1026
  * await store.set(workflow.snapshot()) // persist the run state
992
1027
  * const snapshot = await store.get(definition.id)
993
- * const restored = snapshot && restoreWorkflow(snapshot) // an identical live tree
1028
+ * const restored = snapshot && createRestoredWorkflow(snapshot) // an identical live tree
994
1029
  * await store.delete(definition.id) // drop it
995
1030
  * ```
996
1031
  */
@@ -1024,7 +1059,7 @@ export declare class MemoryWorkflowStore implements WorkflowStoreInterface {
1024
1059
  * moveEntry([['a', 1], ['b', 2], ['c', 3]], 'a', 2) // [['b', 2], ['c', 3], ['a', 1]]
1025
1060
  * ```
1026
1061
  */
1027
- export declare function moveEntry<T>(entries: readonly (readonly [string, T])[], key: string, index: number): readonly (readonly [string, T])[];
1062
+ export declare function moveEntry<T>(entries: ReadonlyArray<readonly [string, T]>, key: string, index: number): ReadonlyArray<readonly [string, T]>;
1028
1063
 
1029
1064
  /**
1030
1065
  * Park until `signal` aborts — a promise-parked wait (AGENTS §21), never a timer or
@@ -1687,20 +1722,6 @@ export declare const phaseUpdateShape: ObjectShape<{
1687
1722
  bail: OptionalShape<LiteralShape<readonly [true, false]>>;
1688
1723
  }, false>;
1689
1724
 
1690
- /**
1691
- * Rebuild an interrupted workflow at its remaining retry budget.
1692
- *
1693
- * @remarks
1694
- * Each phase captures every unique initial `run` binding once before constructing tasks. Recovery
1695
- * validates those live tasks' captured callable handlers without rereading the registry, while the
1696
- * retained registry identity remains available to resolve future live additions at their mint time.
1697
- *
1698
- * @param snapshot - The hostile persisted snapshot
1699
- * @param options - Runtime handlers and entity options
1700
- * @returns A recoverable live workflow
1701
- */
1702
- export declare function recoverWorkflow(snapshot: unknown, options?: WorkflowOptions): WorkflowInterface;
1703
-
1704
1725
  /**
1705
1726
  * Convert interrupted running work into a recoverable pending suffix or an
1706
1727
  * exhausted recovery failure without replenishing attempts.
@@ -1719,40 +1740,6 @@ export declare function recoverWorkflowSnapshot(snapshot: WorkflowSnapshot): Wor
1719
1740
  */
1720
1741
  export declare function resolveTaskSilence(value: number | undefined, fallback: number | undefined): number | undefined;
1721
1742
 
1722
- /**
1723
- * Rebuild an equivalent live W-b entity tree from a {@link WorkflowSnapshot} — the
1724
- * inverse of {@link WorkflowInterface.snapshot}, restoring structure + each node's status
1725
- * + recorded results + positional order + the persisted `#override`.
1726
- *
1727
- * @remarks
1728
- * Round-trip fidelity is paramount: a `snapshot()` → `restoreWorkflow()` reproduces the
1729
- * same status at every node (each `#override` restored DIRECTLY from the snapshot's own
1730
- * `override` field, not guessed from a status divergence), the same recorded
1731
- * {@link import('./types.js').TaskResult}s, and the same positional order (an interior
1732
- * `skip` / `remove` survives). The snapshot is SELF-CONTAINED — it persists the `bail`
1733
- * policy it ran under, so the restore re-derives status IDENTICALLY without a silent
1734
- * default; the snapshot's `bail` is the source of truth, while an explicit `options.bail`
1735
- * still wins when supplied (to deliberately re-run under a different policy). A structurally
1736
- * invalid snapshot (a status — or override — outside the lifecycle vocabulary, or a
1737
- * non-boolean `bail`) throws a `RESTORE` {@link WorkflowError}.
1738
- * Runtime handlers are optional: without a matching `functions` entry, a persisted `run`
1739
- * remains visible with an undefined `handler` so the exact state is inspectable. The runner
1740
- * rejects that unresolved tree if execution is attempted.
1741
- *
1742
- * @param snapshot - The snapshot to restore (carries its own `bail` + `override`)
1743
- * @param options - Runtime options (initial listeners, an optional `bail` override, per-node options)
1744
- * @returns The restored live {@link WorkflowInterface} root
1745
- *
1746
- * @example
1747
- * ```ts
1748
- * import { restoreWorkflow } from '@orkestrel/workflow'
1749
- *
1750
- * const restored = restoreWorkflow(workflow.snapshot()) // bail comes from the snapshot
1751
- * restored.status === workflow.status // true
1752
- * ```
1753
- */
1754
- export declare function restoreWorkflow(snapshot: unknown, options?: WorkflowOptions): WorkflowInterface;
1755
-
1756
1743
  /**
1757
1744
  * A thin generic orchestrator that drives declared units — and any they `spawn` —
1758
1745
  * through a bounded-concurrency {@link createQueue}, collecting ordered results.
@@ -2104,6 +2091,16 @@ export declare interface RunnerUnit<TInput> {
2104
2091
  * Schedule one cancellable host operation behind an owned settlement signal.
2105
2092
  *
2106
2093
  * @remarks
2094
+ * A defined `signal` that is not a native `AbortSignal` is refused before anything is armed, as a
2095
+ * rejected promise carrying a {@link import('./errors.js').WorkflowError} with the `SCHEDULE` code.
2096
+ * Rejecting rather than throwing keeps every caller on one settlement path, so a backend never has
2097
+ * to guard the call itself.
2098
+ *
2099
+ * The guard is necessary but not sufficient, so linking stays contained. A `Proxy` over a native
2100
+ * signal passes the guard and can still make linking throw from a trap, and that escape would be
2101
+ * synchronous — the one shape every caller here is built not to expect. Containment turns it into
2102
+ * the same `SCHEDULE` rejection, so setup has exactly one failure shape however hostile the input.
2103
+ *
2107
2104
  * The completion and failure paths each own an {@link AbortController}; their native composite is
2108
2105
  * linked to the optional caller signal before `start` can arm host work. Scheduler backends attach
2109
2106
  * only to that safe composite, so caller mutation of `addEventListener` or `removeEventListener`
@@ -2115,7 +2112,8 @@ export declare interface RunnerUnit<TInput> {
2115
2112
  *
2116
2113
  * @param start - Arm host work and return its cancellation closure
2117
2114
  * @param signal - Optional caller cancellation signal
2118
- * @returns A promise settled exactly once by completion, host failure, or caller abort
2115
+ * @returns A promise settled exactly once by an invalid-signal refusal, completion, host failure,
2116
+ * or caller abort
2119
2117
  */
2120
2118
  export declare function scheduleHost(start: (complete: () => void, failure: (error: unknown) => void) => () => void, signal?: AbortSignal): Promise<void>;
2121
2119
 
@@ -2492,7 +2490,7 @@ export declare interface TaskDefinition {
2492
2490
  * Extra attempts after the first on failure (a non-negative integer); the runner threads it
2493
2491
  * to this task's substrate unit, OVERRIDING the phase Runner's `retries` default. Omitted ⇒
2494
2492
  * the default (no extra attempts). PERSISTED in a {@link TaskSnapshot} (like `bail` and
2495
- * `concurrency`), so `restoreWorkflow(snapshot, { functions })` resumes with the same
2493
+ * `concurrency`), so `createRestoredWorkflow(snapshot, { functions })` resumes with the same
2496
2494
  * reliability config; only the resolved handler itself is runtime-only.
2497
2495
  */
2498
2496
  readonly retries?: number;
@@ -2500,7 +2498,7 @@ export declare interface TaskDefinition {
2500
2498
  * @remarks
2501
2499
  * The workflow-owned per-attempt deadline in milliseconds, an integer from `0` through
2502
2500
  * `MAX_TIMER_MS`. Zero or omission means no deadline. PERSISTED in a {@link TaskSnapshot},
2503
- * so `restoreWorkflow(snapshot, { functions })` resumes with the same reliability config;
2501
+ * so `createRestoredWorkflow(snapshot, { functions })` resumes with the same reliability config;
2504
2502
  * only the resolved handler itself is runtime-only.
2505
2503
  */
2506
2504
  readonly timeout?: number;
@@ -2914,7 +2912,7 @@ export declare const taskShape: ObjectShape<{
2914
2912
  * like a {@link PhaseSnapshot}'s `bail` / `concurrency`, so a restore reinstates the same
2915
2913
  * behavior reference and reliability overrides (`run` re-resolves against the
2916
2914
  * {@link WorkflowOptions.functions} registry supplied to
2917
- * {@link import('./factories.js').restoreWorkflow}); each omitted ⇒ the corresponding
2915
+ * {@link import('./factories.js').createRestoredWorkflow}); each omitted ⇒ the corresponding
2918
2916
  * unset default.
2919
2917
  */
2920
2918
  export declare interface TaskSnapshot {
@@ -3025,7 +3023,7 @@ export declare type UnitOutcome<TResult> = {
3025
3023
  * @remarks
3026
3024
  * - **Construction.** Built from a {@link WorkflowSnapshot} (the unified input —
3027
3025
  * {@link import('./factories.js').createWorkflow} seeds an initial snapshot from a
3028
- * {@link import('./types.js').WorkflowDefinition}, {@link import('./factories.js').restoreWorkflow}
3026
+ * {@link import('./types.js').WorkflowDefinition}, {@link import('./factories.js').createRestoredWorkflow}
3029
3027
  * passes a persisted one). Each child {@link Phase} is wired to escalate to `#recompute`.
3030
3028
  * - **Derived status.** `status` is `#override` when forced, else
3031
3029
  * {@link deriveWorkflowStatus} over the live phases' statuses feeding `bail`. `failed` is
@@ -3040,7 +3038,7 @@ export declare type UnitOutcome<TResult> = {
3040
3038
  * workflow tier; `phase(id)` + each `phase.task(id)` navigate DOWN, a task's `phase` / `workflow`
3041
3039
  * navigate UP.
3042
3040
  * - **Snapshot.** `snapshot()` serializes the whole live tree to a {@link WorkflowSnapshot} (pure
3043
- * JSON); {@link import('./factories.js').restoreWorkflow} rebuilds an equivalent live tree.
3041
+ * JSON); {@link import('./factories.js').createRestoredWorkflow} rebuilds an equivalent live tree.
3044
3042
  * - **Observable (AGENTS §13).** The owned {@link emitter} ({@link WorkflowEventMap}) fires
3045
3043
  * `start` / `complete` / `fail` / `pause` / `resume` / `skip` / `stop` after the
3046
3044
  * corresponding status or runtime-gate change; the emitter isolates a listener throw and
@@ -3138,9 +3136,11 @@ export declare interface WorkflowDefinition {
3138
3136
  *
3139
3137
  * @remarks
3140
3138
  * Carries a {@link WorkflowErrorCode} and an optional `context` bag naming the
3141
- * offending node id / status. Raised for an illegal lifecycle transition
3139
+ * offending node id / status / parameter. Raised for an illegal lifecycle transition
3142
3140
  * (`TRANSITION`), a structurally invalid {@link import('./types.js').WorkflowSnapshot}
3143
- * boundary (`RESTORE`), or a refused structural/activity edit (`MUTATION`).
3141
+ * boundary (`RESTORE`), a refused structural/activity edit (`MUTATION`), or a host
3142
+ * schedule refused before arming because the caller's `signal` is not a native
3143
+ * `AbortSignal` (`SCHEDULE`, delivered as a rejected promise).
3144
3144
  */
3145
3145
  export declare class WorkflowError extends Error {
3146
3146
  readonly code: WorkflowErrorCode;
@@ -3156,7 +3156,7 @@ export declare class WorkflowError extends Error {
3156
3156
  * - `TRANSITION` — an illegal state-machine transition (e.g. `start`ing a task that is
3157
3157
  * not `pending`, or `complete`/`fail`ing one that is not `running`); the guard names
3158
3158
  * the offending current status + requested transition in the error `context`.
3159
- * - `RESTORE` — a {@link import('./factories.js').restoreWorkflow} given a structurally
3159
+ * - `RESTORE` — a {@link import('./factories.js').createRestoredWorkflow} given a structurally
3160
3160
  * invalid {@link WorkflowSnapshot} (a status outside the lifecycle vocabulary).
3161
3161
  * - `MUTATION` — a GATED structural or patch edit was refused: a duplicate id on
3162
3162
  * `append`/`add`, a target that does not exist or is not `pending`, an out-of-bounds
@@ -3170,8 +3170,13 @@ export declare class WorkflowError extends Error {
3170
3170
  * {@link TaskManagerInterface.append} / {@link PhaseManagerInterface.append} duplicate-id
3171
3171
  * guard (both genuine programmer-error paths, AGENTS §12). The error `context` names
3172
3172
  * the offending id / index / status.
3173
+ * - `SCHEDULE` — {@link import('./helpers.js').scheduleHost} refused to arm host work
3174
+ * because the caller passed a `signal` that is not a native `AbortSignal`. The refusal
3175
+ * is a REJECTED promise, never a synchronous throw, so every scheduler backend settles
3176
+ * the same way whatever the caller passed. The error `context` names the offending
3177
+ * parameter (`signal`) and the `typeof` the caller supplied.
3173
3178
  */
3174
- export declare type WorkflowErrorCode = 'TRANSITION' | 'RESTORE' | 'MUTATION';
3179
+ export declare type WorkflowErrorCode = 'TRANSITION' | 'RESTORE' | 'MUTATION' | 'SCHEDULE';
3175
3180
 
3176
3181
  /**
3177
3182
  * The push observation surface (AGENTS §13) of the workflow entity (W-b) — the
@@ -3279,7 +3284,7 @@ export declare type WorkflowInput = Partial<WorkflowContext>;
3279
3284
  * may force only a task-free, otherwise-pending tree. The override survives a snapshot.
3280
3285
  * - **Snapshot.** `snapshot()` serializes the whole live tree to a {@link WorkflowSnapshot}
3281
3286
  * (pure JSON — structure + each node's status + recorded results + positional order);
3282
- * {@link restoreWorkflow} rebuilds an equivalent live tree.
3287
+ * {@link createRestoredWorkflow} rebuilds an equivalent live tree.
3283
3288
  * - **Observable (AGENTS §13).** The owned {@link emitter} ({@link WorkflowEventMap}) fires
3284
3289
  * `start` / `complete` / `fail` / `pause` / `resume` / `stop` after the corresponding
3285
3290
  * status or runtime-gate change; the emitter isolates a listener throw and routes it to
@@ -3540,7 +3545,7 @@ export declare class WorkflowManager implements WorkflowManagerInterface {
3540
3545
  * is supplied (the `store` option), `open(id)` resolves an already-registered workflow
3541
3546
  * directly (no store hit); same-id registry misses share one in-flight hydration. On a MISS
3542
3547
  * it HYDRATES one from `store.get(id)` through
3543
- * {@link import('./factories.js').restoreWorkflow} — flowing this manager's `functions`
3548
+ * {@link import('./factories.js').createRestoredWorkflow} — flowing this manager's `functions`
3544
3549
  * registry in so the rehydrated tree is RUNNABLE — registers it, and returns it. Registry
3545
3550
  * mutation wins over an earlier pending hydration: `add` supplies the live result, while
3546
3551
  * `remove` (even for an absent id) and `clear` invalidate the earlier read. Missed and failed
@@ -3554,7 +3559,7 @@ export declare class WorkflowManager implements WorkflowManagerInterface {
3554
3559
  * `ConversationManagerInterface.open` / `.save` and `WorkspaceManagerInterface.open` /
3555
3560
  * `.save` — this is the workflow line's caller-driven persistence gaining the standard
3556
3561
  * open/save seam, ADDITIVE alongside direct {@link WorkflowStoreInterface} use and
3557
- * {@link import('./factories.js').restoreWorkflow} (both remain valid).
3562
+ * {@link import('./factories.js').createRestoredWorkflow} (both remain valid).
3558
3563
  * - **Removal.** `remove` drops one by id, or a batch (§9.2, array overload FIRST) — `true`
3559
3564
  * when any was removed. `clear` empties the registry.
3560
3565
  * - **Event-free.** A purely registry store — no `Emitter`, no events (each
@@ -3599,7 +3604,7 @@ export declare interface WorkflowManagerInterface {
3599
3604
  * - Same-id registry misses share one in-flight `store.get(id)` and resolve to the same live
3600
3605
  * object. On a HIT the snapshot is
3601
3606
  * rehydrated into a fresh {@link WorkflowInterface} via
3602
- * {@link import('./factories.js').restoreWorkflow}, flowing this manager's `functions`
3607
+ * {@link import('./factories.js').createRestoredWorkflow}, flowing this manager's `functions`
3603
3608
  * registry in (so the rehydrated tree carries real resolved `handler`s and can RESUME
3604
3609
  * real work), registers it, and returns it. A payload whose own id differs from `id` rejects
3605
3610
  * with a normalized `RESTORE` error carrying the requested and payload ids.
@@ -3644,7 +3649,7 @@ export declare interface WorkflowManagerInterface {
3644
3649
  * already registered, and {@link WorkflowManagerInterface.save} is a no-op (`false`). `functions`
3645
3650
  * is the workflow-specific addition: the SAME {@link WorkflowFunctions} registry threaded into
3646
3651
  * every {@link import('./factories.js').createWorkflow} ({@link WorkflowManagerInterface.add})
3647
- * and every {@link import('./factories.js').restoreWorkflow}
3652
+ * and every {@link import('./factories.js').createRestoredWorkflow}
3648
3653
  * ({@link WorkflowManagerInterface.open}'s hydration path) the manager performs — so a
3649
3654
  * hydrated workflow carries real resolved `handler`s and is RUNNABLE. Omitted ⇒ named work
3650
3655
  * remains inspectable but cannot be driven; omitted-`run` tasks remain deliberate no-ops.
@@ -3661,7 +3666,7 @@ export declare interface WorkflowManagerOptions {
3661
3666
  /**
3662
3667
  * The {@link WorkflowFunctions} registry threaded into every workflow this manager mints
3663
3668
  * (`add`, via {@link import('./factories.js').createWorkflow}) or hydrates (`open`'s
3664
- * registry-miss path, via {@link import('./factories.js').restoreWorkflow}) — so a
3669
+ * registry-miss path, via {@link import('./factories.js').createRestoredWorkflow}) — so a
3665
3670
  * hydrated workflow is RUNNABLE, its tasks carrying real resolved `handler`s. Omitted ⇒
3666
3671
  * named tasks remain inspectable but execution rejects them.
3667
3672
  */
@@ -3685,7 +3690,7 @@ export declare interface WorkflowOptions {
3685
3690
  * The failure policy (AGENTS §4.4) the live tree applies — the same boolean toggle as
3686
3691
  * {@link WorkflowDefinition.bail}, fed to {@link import('./helpers.js').deriveWorkflowStatus}.
3687
3692
  * {@link import('./factories.js').createWorkflow} defaults it to the definition's `bail`. A
3688
- * {@link WorkflowSnapshot} PERSISTS the policy, so {@link import('./factories.js').restoreWorkflow}
3693
+ * {@link WorkflowSnapshot} PERSISTS the policy, so {@link import('./factories.js').createRestoredWorkflow}
3689
3694
  * takes it from the snapshot (the source of truth); an explicit `options.bail` on restore still
3690
3695
  * wins when supplied. Omitted on a fresh build ⇒ the graceful {@link import('./constants.js').DEFAULT_BAIL}.
3691
3696
  */
@@ -3699,7 +3704,7 @@ export declare interface WorkflowOptions {
3699
3704
  * {@link TaskDefinition.run} / {@link TaskSnapshot.run} name resolves against ONCE at
3700
3705
  * construction into its runtime {@link TaskInterface.handler} — the SAME registry a
3701
3706
  * fresh build ({@link import('./factories.js').createWorkflow}) and a restore
3702
- * ({@link import('./factories.js').restoreWorkflow}) both consume, and the same shape a
3707
+ * ({@link import('./factories.js').createRestoredWorkflow}) both consume, and the same shape a
3703
3708
  * live {@link WorkflowInterface.add} / {@link PhaseInterface.add} mint resolves a newly
3704
3709
  * minted task against. An omitted `run` resolves to no handler and is the deliberate
3705
3710
  * no-op form. A present name absent from `functions` also has no handler so exact restore
@@ -4027,7 +4032,7 @@ export declare interface WorkflowRunnerInterface {
4027
4032
  * does not apply, since the tree already exists.
4028
4033
  *
4029
4034
  * **Run round-trips through the snapshot.** Driving a tree rebuilt by
4030
- * {@link import('./factories.js').restoreWorkflow} behaves according to whether a
4035
+ * {@link import('./factories.js').createRestoredWorkflow} behaves according to whether a
4031
4036
  * {@link WorkflowFunctions} registry was supplied at that build: WITH a registry,
4032
4037
  * each task's `run` name is re-resolved against it, so a matched task carries a real
4033
4038
  * handler and this overload actually DISPATCHES it, resuming real work. Without a registry,
@@ -4139,7 +4144,7 @@ export declare const workflowShape: ObjectShape<{
4139
4144
  * designed in full at W-a so its shape is fixed from the start. It can be written to disk,
4140
4145
  * sent to a prompt companion, loaded across conversations, or reviewed by an agent. Because
4141
4146
  * it is self-contained, it carries the policy it ran under: `bail` (AGENTS §4.4) is the
4142
- * failure policy, so {@link import('./factories.js').restoreWorkflow} re-derives status
4147
+ * failure policy, so {@link import('./factories.js').createRestoredWorkflow} re-derives status
4143
4148
  * IDENTICALLY without a silent default. `status` is the EFFECTIVE status (override-or-derived)
4144
4149
  * at snapshot time; `override` is the forced status of a whole-workflow `skip` / `stop` or
4145
4150
  * vacuous `completed`. The completed override is valid only for an otherwise-derived pending
@@ -4209,7 +4214,7 @@ export declare type WorkflowStatus = LifecycleStatus;
4209
4214
  * {@link import('./stores/MemoryWorkflowStore.js').MemoryWorkflowStore} and its driver-pluggable
4210
4215
  * twin {@link import('./stores/DatabaseWorkflowStore.js').DatabaseWorkflowStore} (the snapshot as
4211
4216
  * one opaque JSON column) share THIS one interface. Restore is NOT a store concern — a caller reads
4212
- * a snapshot back and rebuilds the live tree with the shipped {@link import('./factories.js').restoreWorkflow}.
4217
+ * a snapshot back and rebuilds the live tree with the shipped {@link import('./factories.js').createRestoredWorkflow}.
4213
4218
  *
4214
4219
  * Every primitive is async (a `Promise`), so a durable backend (a database round-trip) fits the
4215
4220
  * same shape as the memory one. The snapshot carries its OWN id, so `set` takes no separate id