@sanity/workflow-engine 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks-cjs/schema.cjs +291 -317
- package/dist/_chunks-cjs/schema.cjs.map +1 -1
- package/dist/_chunks-es/schema.js +291 -317
- package/dist/_chunks-es/schema.js.map +1 -1
- package/dist/define.cjs +480 -74
- package/dist/define.cjs.map +1 -1
- package/dist/define.d.cts +7404 -4450
- package/dist/define.d.ts +7404 -4450
- package/dist/define.js +482 -76
- package/dist/define.js.map +1 -1
- package/dist/index.cjs +1650 -1521
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10557 -5214
- package/dist/index.d.ts +10557 -5214
- package/dist/index.js +1651 -1522
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/api/validate.ts","../src/clock.ts","../src/core/refs.ts","../src/core/params.ts","../src/core/path.ts","../src/core/state-read.ts","../src/core/source.ts","../src/core/bindings.ts","../src/core/eval.ts","../src/types/authorization.ts","../src/core/guards.ts","../src/guard-bindings.ts","../src/guards-lifecycle.ts","../src/keys.ts","../src/core/snapshot.ts","../src/types/instance-state.ts","../src/subscription-documents.ts","../src/snapshot.ts","../src/types/instance.ts","../src/core/slot-validation.ts","../src/state-resolution.ts","../src/engine/context.ts","../src/instance.ts","../src/engine/mutation.ts","../src/engine/effects.ts","../src/engine/results.ts","../src/engine/guard-commit.ts","../src/tags.ts","../src/definition-query.ts","../src/discover.ts","../src/engine/spawn.ts","../src/engine/tasks.ts","../src/engine/stages.ts","../src/engine/cascade.ts","../src/permissions.ts","../src/access.ts","../src/evaluate.ts","../src/guards-query.ts","../src/api/deploy.ts","../src/engine/ops.ts","../src/engine/actions.ts","../src/types/evaluation.ts","../src/api/operations.ts","../src/api/workflow.ts","../src/api/drain.ts","../src/api/instance-session.ts","../src/api/engine-factory.ts","../src/display.ts"],"sourcesContent":["import {parse as parseGroq} from 'groq-js'\n\nimport type {Stage, StateSlot, Task, WorkflowDefinition} from '../define/schema.ts'\n\n/**\n * Parse-validate every GROQ string in a definition before deploy.\n * Surfaces malformed predicate queries, filters, bindings, and\n * `task.completeWhen`/`failWhen` expressions early — long before any\n * instance runs.\n *\n * Throws an `Error` with all problems aggregated. Doesn't try to\n * type-check semantics (just syntax). Reserved params don't need to be\n * declared here — groq-js's parser doesn't know about runtime params,\n * just syntax.\n */\nexport function validateDefinition(definition: WorkflowDefinition): void {\n const v = createDefinitionValidator()\n\n for (const slot of (definition as WorkflowDefinition & {state?: StateSlot[]}).state ?? []) {\n v.checkSlot(slot, `workflow.state \"${slot.id}\"`)\n }\n\n for (const p of definition.predicates ?? []) {\n if (p.groq) v.checkFilter(p.groq, `predicate \"${p.id}\"`)\n }\n\n for (const stage of definition.stages) {\n validateStage(v, stage)\n }\n\n if (v.errors.length > 0) {\n throw new Error(\n `defineWorkflow(\"${definition.workflowId}\", v${definition.version}): ` +\n `${v.errors.length} validation error${v.errors.length === 1 ? '' : 's'}:\\n` +\n v.errors.join('\\n'),\n )\n }\n}\n\ninterface DefinitionValidator {\n errors: string[]\n /** Parse-check raw GROQ; records a syntax error under `where`. */\n tryParse: (groq: string, where: string) => void\n /** Parse-check a filter AND reject `_type` discovery scans in it. */\n checkFilter: (groq: string, where: string) => void\n /** Parse-check a `query`-sourced slot's GROQ. */\n checkSlot: (slot: StateSlot, slotLabel: string) => void\n}\n\nfunction createDefinitionValidator(): DefinitionValidator {\n const errors: string[] = []\n const tryParse = (groq: string, where: string) => {\n try {\n parseGroq(groq)\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n errors.push(` · ${where}: ${message}`)\n }\n }\n // Reject filters that scan by `_type` — those are discovery queries,\n // not predicates. Filters evaluate against the in-memory snapshot\n // (instance + subject + ancestors + state-declared docs), which never\n // contains \"all docs of type X\", so a type scan returns empty and the\n // workflow appears stuck. Regex-based: `*[` followed by `_type`. False\n // negatives slip through harmlessly (runtime still returns empty).\n const rejectTypeScan = (groq: string, where: string) => {\n if (/\\*\\s*\\[\\s*_type\\b/.test(groq)) {\n errors.push(\n ` · ${where}: filter scans by \\`_type\\` — that's a discovery query, not a predicate. ` +\n `Filters evaluate against the in-memory snapshot (instance + ancestors + ` +\n `state-declared docs). To bring extra docs in scope, declare a \\`workflow.state.doc.ref\\` ` +\n `(or \\`doc.refs\\`) slot on the workflow or this stage. For lake scans like ` +\n `\"all articles in this release\", use spawn \\`forEach.groq\\` instead.`,\n )\n }\n }\n const checkFilter = (groq: string, where: string) => {\n tryParse(groq, where)\n rejectTypeScan(groq, where)\n }\n const checkSlot = (slot: StateSlot, slotLabel: string) => {\n if (slot.source.kind === 'query') tryParse(slot.source.query, `${slotLabel}.query`)\n }\n return {errors, tryParse, checkFilter, checkSlot}\n}\n\nfunction validateStage(v: DefinitionValidator, stage: Stage): void {\n for (const slot of stage.state ?? []) {\n v.checkSlot(slot, `stage \"${stage.id}\".state \"${slot.id}\"`)\n }\n if (typeof stage.completion === 'string') {\n v.tryParse(stage.completion, `stage \"${stage.id}\".completion`)\n }\n for (const t of stage.transitions ?? []) {\n // Effect bindings are typed Source values now — no GROQ to parse.\n if (typeof t.filter === 'string')\n v.checkFilter(t.filter, `transition ${stage.id} → ${t.to} filter`)\n }\n for (const task of stage.tasks ?? []) {\n validateTask(v, stage.id, task)\n }\n}\n\nfunction validateTask(v: DefinitionValidator, stageId: string, task: Task): void {\n const where = `stage \"${stageId}\" task \"${task.id}\"`\n for (const slot of task.state ?? []) {\n v.checkSlot(slot, `${where}.state \"${slot.id}\"`)\n }\n if (typeof task.filter === 'string') v.checkFilter(task.filter, `${where}.filter`)\n if (typeof task.completeWhen === 'string')\n v.checkFilter(task.completeWhen, `${where}.completeWhen`)\n for (const a of task.actions ?? []) {\n if (typeof a.filter === 'string')\n v.checkFilter(a.filter, `task \"${task.id}\" action \"${a.id}\".filter`)\n }\n // spawn.forEach.groq is intentionally NOT type-scan-checked — it's\n // discovery, not a filter.\n if (task.spawns?.forEach?.groq) {\n v.tryParse(task.spawns.forEach.groq, `task \"${task.id}\".spawns.forEach.groq`)\n }\n}\n","/**\n * The engine's single source of \"now\".\n *\n * A {@link Clock} returns the current time as an ISO-8601 string. Each\n * verb-driven operation takes ONE reading and threads it everywhere —\n * `$now` in filters, the `now` op-source, every history `at` stamp,\n * `completedAt`, `enteredAt`, `lastChangedAt` — so an eval pass agrees on\n * the time and a frozen clock produces a deterministic instance.\n *\n * A clock is injected ONCE, never per call: production omits it entirely\n * (defaults to {@link wallClock}); deterministic harnesses pass\n * `createEngine({ clock })`, and tests use `@sanity/workflow-engine-test`'s\n * `setNow` / `advance` (the bench wraps the same seam). It is deliberately\n * NOT a field on the public per-verb `*Args` — the raw `workflow.*` verbs\n * accept it only through the internal {@link Clocked} seam, so prod code\n * can't trivially override engine time by accident.\n *\n * Out of scope: `drainEffects` (the external runtime worker claiming and\n * executing effects) still stamps `claimedAt` from wall-clock — it is not\n * a verb and the bench never drives it. Thread a clock there too if the\n * simulator ever needs deterministic drain timing.\n */\nexport type Clock = () => string\n\n/** The default clock: real wall-clock time as an ISO-8601 string. */\nexport const wallClock: Clock = () => new Date().toISOString()\n\n/**\n * Internal clock-injection seam for the raw `workflow.*` verbs. NOT part\n * of the public per-verb args (it is deliberately not re-exported from the\n * package root) — production injects a clock ONCE via\n * `createEngine({ clock })`, and the test bench via its `setNow` /\n * `advance`. This intersection just lets those two callers thread the\n * clock into a raw verb without `clock` cluttering every documented\n * `*Args` interface as if it were an everyday option.\n */\nexport type Clocked<T> = T & {clock?: Clock}\n","/**\n * Global Document References (GDR).\n *\n * Every cross-document reference in the engine API uses this shape so\n * workflow state can live in one Sanity resource while subjects /\n * ancestors / effect-binding refs point at docs in *different* resources.\n *\n * Resource schemes mirror `@sanity/client`'s `ClientConfigResource`\n * discriminator. A GDR id is a typed URI:\n *\n * dataset:<projectId>:<dataset>:<documentId>\n * canvas:<resourceId>:<documentId>\n * media-library:<resourceId>:<documentId>\n * dashboard:<resourceId>:<documentId>\n *\n * The `type` field carries the doc's schema `_type` so consumers don't\n * need a separate lookup to know what they're pointing at.\n */\n\nexport type GdrScheme = 'dataset' | 'canvas' | 'media-library' | 'dashboard'\n\n/**\n * Typed GDR URI string. The compiler rejects bare doc ids (`\"doc-1\"`)\n * — only `<scheme>:<...id-parts>` values typecheck. Construct one via\n * `gdrUri()` / `gdrFromResource()` / `refDataset()` etc., or by hand\n * with the scheme prefix baked in (`` `dataset:proj:ds:${docId}` `` ).\n *\n * Combined with schema validation at the API boundary, this is the\n * type + runtime guarantee that no bare-string id reaches the\n * snapshot, slot, or filter layer.\n */\nexport type GdrUri = `${GdrScheme}:${string}`\n\nexport interface GlobalDocumentReference {\n /** URI: `<scheme>:<...id-parts>` */\n id: GdrUri\n /** Document `_type` (schema name) */\n type: string\n}\n\nexport interface ParsedGdr {\n scheme: GdrScheme\n /** For `dataset`: `<projectId>` */\n projectId?: string\n /** For `dataset`: `<dataset>` */\n dataset?: string\n /** For `canvas` / `media-library` / `dashboard`: `<resourceId>` */\n resourceId?: string\n /** The trailing `<documentId>` part — what `_id` of the target doc is */\n documentId: string\n}\n\nconst KNOWN_SCHEMES = new Set<string>(['dataset', 'canvas', 'media-library', 'dashboard'])\n\n/**\n * Parse a GDR URI into its scheme + addressing parts. Throws on\n * unknown scheme or malformed shape.\n */\nexport function parseGdr(uri: string): ParsedGdr {\n const colon = uri.indexOf(':')\n if (colon < 0) {\n throw new Error(\n `Invalid GDR \"${uri}\": must be a URI of form \"<scheme>:<...id-parts>\". Known schemes: dataset, canvas, media-library, dashboard.`,\n )\n }\n const scheme = uri.slice(0, colon)\n const rest = uri.slice(colon + 1)\n if (!KNOWN_SCHEMES.has(scheme)) {\n throw new Error(\n `Invalid GDR \"${uri}\": unknown scheme \"${scheme}\". Known: dataset, canvas, media-library, dashboard.`,\n )\n }\n const parts = rest.split(':')\n if (parts.some((part) => part.length === 0)) {\n throw new Error(\n `Invalid GDR \"${uri}\": id parts must be non-empty (no leading, trailing, or doubled \":\").`,\n )\n }\n if (scheme === 'dataset') {\n if (parts.length !== 3) {\n throw new Error(\n `Invalid GDR \"${uri}\": dataset scheme requires <projectId>:<dataset>:<documentId> (3 parts after scheme); got ${parts.length}.`,\n )\n }\n return {\n scheme: 'dataset',\n projectId: parts[0]!,\n dataset: parts[1]!,\n documentId: parts[2]!,\n }\n }\n // canvas / media-library / dashboard share <resourceId>:<documentId>\n if (parts.length !== 2) {\n throw new Error(\n `Invalid GDR \"${uri}\": ${scheme} scheme requires <resourceId>:<documentId> (2 parts after scheme); got ${parts.length}.`,\n )\n }\n return {\n scheme: scheme as GdrScheme,\n resourceId: parts[0]!,\n documentId: parts[1]!,\n }\n}\n\n/** Compose a GDR URI from parts. Inverse of `parseGdr`. */\nexport function gdrUri(\n parts:\n | {scheme: 'dataset'; projectId: string; dataset: string; documentId: string}\n | {\n scheme: 'canvas' | 'media-library' | 'dashboard'\n resourceId: string\n documentId: string\n },\n): GdrUri {\n if (parts.scheme === 'dataset') {\n return `dataset:${parts.projectId}:${parts.dataset}:${parts.documentId}` as GdrUri\n }\n return `${parts.scheme}:${parts.resourceId}:${parts.documentId}` as GdrUri\n}\n\n/**\n * Extract the bare document `_id` from a GDR URI — what\n * `*[_id == $docId]` in GROQ needs.\n */\nexport function extractDocumentId(gdrUriString: string): string {\n return parseGdr(gdrUriString).documentId\n}\n\n/** Make a GDR pointer to a project-dataset doc. */\nexport function refDataset(\n projectId: string,\n dataset: string,\n documentId: string,\n type: string,\n): GlobalDocumentReference {\n return {id: gdrUri({scheme: 'dataset', projectId, dataset, documentId}), type}\n}\n\n/** Make a GDR pointer to a Canvas-resource doc. */\nexport function refCanvas(\n resourceId: string,\n documentId: string,\n type: string,\n): GlobalDocumentReference {\n return {id: gdrUri({scheme: 'canvas', resourceId, documentId}), type}\n}\n\n/** Make a GDR pointer to a Media-Library-resource doc. */\nexport function refMediaLibrary(\n resourceId: string,\n documentId: string,\n type: string,\n): GlobalDocumentReference {\n return {id: gdrUri({scheme: 'media-library', resourceId, documentId}), type}\n}\n\n/** Make a GDR pointer to a Dashboard-resource doc. */\nexport function refDashboard(\n resourceId: string,\n documentId: string,\n type: string,\n): GlobalDocumentReference {\n return {id: gdrUri({scheme: 'dashboard', resourceId, documentId}), type}\n}\n\n/**\n * The resource a Sanity client is configured against — mirrors\n * `@sanity/client`'s `ClientConfigResource` discriminator. For\n * `dataset`, `id` is `<projectId>.<dataset>`. For the others, `id` is\n * the resource id.\n */\nexport type WorkflowResource =\n | {type: 'dataset'; id: string}\n | {type: 'canvas'; id: string}\n | {type: 'media-library'; id: string}\n | {type: 'dashboard'; id: string}\n\n/**\n * Build a GDR URI from a workflow resource config + a document id\n * within that resource. This is how the engine mints `_id`s for\n * definitions / instances / ancestor refs into its own resource.\n */\nexport function gdrFromResource(res: WorkflowResource, documentId: string): GdrUri {\n if (res.type === 'dataset') {\n const dot = res.id.indexOf('.')\n if (dot < 0) {\n throw new Error(`Invalid dataset resource id \"${res.id}\": expected \"<projectId>.<dataset>\".`)\n }\n const projectId = res.id.slice(0, dot)\n const dataset = res.id.slice(dot + 1)\n return gdrUri({scheme: 'dataset', projectId, dataset, documentId})\n }\n return gdrUri({scheme: res.type, resourceId: res.id, documentId})\n}\n\n/**\n * The GDR URI a document refers to itself by — its own `_id` minted into\n * its own `workflowResource`. This is the `$self` value filters see and\n * the form `Source.self` resolves to in ops and spawn.\n */\nexport function selfGdr(doc: {workflowResource: WorkflowResource; _id: string}): GdrUri {\n return gdrFromResource(doc.workflowResource, doc._id)\n}\n\n/**\n * Type-narrowing predicate — `true` when `value` looks like a GDR URI\n * (has a known scheme prefix). Use at boundaries that receive\n * stringified ids and need to refuse bare doc ids.\n */\nexport function isGdrUri(value: unknown): value is GdrUri {\n if (typeof value !== 'string') return false\n try {\n parseGdr(value)\n return true\n } catch {\n return false\n }\n}\n\n/** Build a GDR (id + type) pointing at a document within a workflow resource. */\nexport function gdrRef(\n res: WorkflowResource,\n documentId: string,\n type: string,\n): GlobalDocumentReference {\n return {id: gdrFromResource(res, documentId), type}\n}\n\n/** Type filter for GDR shape. */\nexport function isGdr(value: unknown): value is GlobalDocumentReference {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as {id?: unknown}).id === 'string' &&\n typeof (value as {type?: unknown}).type === 'string'\n )\n}\n","/**\n * Pure param transforms.\n *\n * `buildParams(instance, now, extra?)` — assemble the reserved param\n * bag a filter sees: `$self`, `$state`, `$parent`, `$ancestors`,\n * `$stage`, `$now`. All ids are GDR URIs so they match the\n * snapshot's keying. `now` is supplied by the shell (the engine's\n * {@link Clock}) — core never reads wall-clock itself.\n *\n * `paramsForLake(params)` — strip GDR URIs back to bare ids on the\n * reserved id params, for the shell when it needs to fall through\n * to a lake fetch (spawn discovery scans). Pure transform;\n * doesn't touch the network itself.\n *\n * No client. No I/O. The shell builds these and passes them to\n * `evaluateFilter` (also pure).\n */\n\nimport type {WorkflowInstance} from '../types/instance.ts'\nimport type {ResolvedStateSlot} from '../types/state-slots.ts'\nimport {extractDocumentId, isGdrUri, selfGdr} from './refs.ts'\n\n/**\n * Reserved params available to every filter. `$now` is the shell-supplied\n * clock reading, threaded so multiple predicates fired in the same eval\n * pass agree on the time (and a frozen clock makes the pass deterministic).\n *\n * `$state` is a map keyed by slot id — filters read state via\n * `$state.<slotId>.value.id` for doc.refs, `$state.<slotId>.value`\n * for scalar slots, etc. There is no privileged slot name; the\n * engine doesn't care that you happened to name one \"subject\" or\n * \"article\". The author owns the naming.\n */\nexport function buildParams(\n instance: WorkflowInstance,\n now: string,\n extra?: Record<string, unknown>,\n): Record<string, unknown> {\n return {\n self: selfGdr(instance),\n state: stateMap(instance.state ?? []),\n parent: instance.ancestors.at(-1)?.id ?? null,\n ancestors: instance.ancestors.map((a) => a.id),\n /** Current stage id — bind for filters that scope to the current stage. */\n stage: instance.currentStageId,\n now,\n ...extra,\n }\n}\n\n/**\n * Project the instance's workflow-scope state into a `slotId → slot`\n * map so filters can write `$state.article.value.id`. The slot envelope\n * (id, _type, title?, description?, value, resolvedAt?) is exposed —\n * not just the `value` — so filters that want to distinguish \"slot\n * absent\" from \"slot present with null value\" can do so via\n * `defined($state.article)` vs `defined($state.article.value)`.\n *\n * Stage-scope and task-scope state are NOT in `$state`. They live on\n * `instance.stages[id == $stage && !defined(exitedAt)][0].state[]`\n * and the parallel task path, addressable via GROQ traversal.\n */\nfunction stateMap(slots: ResolvedStateSlot[]): Record<string, ResolvedStateSlot> {\n const out: Record<string, ResolvedStateSlot> = {}\n for (const s of slots) out[s.id] = s\n return out\n}\n\n/**\n * Strip GDR URIs back to bare `_id`s on the reserved id params before\n * a lake fetch (discovery scans). Sanity refs are stored bare on disk,\n * so `releaseRef._ref == $state.release.value.id` only matches when\n * the id is bare in the lake query.\n *\n * Pure transform. Doesn't fetch. The shell decides when to call it.\n *\n * The `$state` map is walked recursively because slot values can\n * carry GDRs (doc.ref / doc.refs) that need stripping for lake match\n * predicates.\n */\nexport function paramsForLake(params: Record<string, unknown>): Record<string, unknown> {\n return {\n ...params,\n self: typeof params.self === 'string' ? bareId(params.self) : params.self,\n parent: typeof params.parent === 'string' ? bareId(params.parent) : params.parent,\n ancestors: Array.isArray(params.ancestors)\n ? params.ancestors.map((a) => (typeof a === 'string' ? bareId(a) : a))\n : params.ancestors,\n state: stripStateForLake(params.state),\n }\n}\n\nfunction stripStateForLake(value: unknown): unknown {\n if (value === null || value === undefined) return value\n if (typeof value === 'string') return bareId(value)\n if (Array.isArray(value)) return value.map(stripStateForLake)\n if (typeof value === 'object') {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n out[k] = stripStateForLake(v)\n }\n return out\n }\n return value\n}\n\nfunction bareId(id: string): string {\n return isGdrUri(id) ? extractDocumentId(id) : id\n}\n","/**\n * Walk a dot-separated property path into a value, returning `undefined` at\n * the first non-object link. Pure; shared by binding resolution, state-slot\n * path dives, and op-predicate field reads.\n */\nexport function getPath(value: unknown, path: string): unknown {\n let current: unknown = value\n for (const part of path.split('.')) {\n if (current === undefined || current === null || typeof current !== 'object') return undefined\n current = (current as Record<string, unknown>)[part]\n }\n return current\n}\n","/**\n * Pure state-slot reads.\n *\n * Given an instance and a `(scope, slotId)` address, return the resolved\n * slot's `value`. Workflow-scope reads hit `instance.state`; stage/task\n * reads resolve against the current (un-exited) stage entry and, for task\n * scope, the named task entry. No I/O.\n */\n\nimport type {StateScope} from '../types/enums.ts'\nimport type {WorkflowInstance} from '../types/instance.ts'\n\nexport function readStateSlot(\n instance: WorkflowInstance,\n scope: StateScope,\n slotId: string,\n stageId: string | undefined,\n taskId: string | undefined,\n): unknown {\n if (scope === 'workflow') {\n return slotValue(instance.state?.find((s) => s.id === slotId))\n }\n const stageEntry = instance.stages.find(\n (s) => s.id === (stageId ?? instance.currentStageId) && s.exitedAt === undefined,\n )\n if (stageEntry === undefined) return undefined\n if (scope === 'stage') {\n return slotValue(stageEntry.state?.find((s) => s.id === slotId))\n }\n const taskEntry = stageEntry.tasks.find((t) => t.id === taskId)\n return slotValue(taskEntry?.state?.find((s) => s.id === slotId))\n}\n\nfunction slotValue(slot: unknown): unknown {\n if (slot === undefined || slot === null) return undefined\n if (typeof slot !== 'object') return undefined\n return (slot as {value?: unknown}).value\n}\n","/**\n * Pure `Source` resolution.\n *\n * A `Source` value declared on effects, ops, and state-slot resolvers is\n * evaluated into a concrete value here. No GROQ, no client, no I/O — just\n * structural lookups against the instance + actor + caller params.\n *\n * Pure: `source: \"now\"` reads the shell-supplied `now` (the engine's\n * {@link Clock}), never wall-clock — so an op's `now` agrees with `$now`\n * in the same eval pass and a frozen clock keeps it deterministic.\n */\n\nimport type {Source} from '../define/schema.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {WorkflowInstance} from '../types/instance.ts'\nimport {getPath} from './path.ts'\nimport {readStateSlot} from './state-read.ts'\n\nexport interface ResolveSourceContext {\n instance: WorkflowInstance\n params?: Record<string, unknown>\n actor?: Actor\n /** Shell-supplied clock reading (ISO) backing `source: \"now\"`. */\n now: string\n /**\n * When the Source is being evaluated in the scope of a specific stage\n * or task, provide their ids so `scope: \"stage\" | \"task\"` reads land\n * on the right state[].\n */\n stageId?: string\n taskId?: string\n}\n\n/**\n * Resolve the context-free Source kinds (`literal` / `param` / `actor` /\n * `now`) shared by every Source resolver. Returns `{handled: false}` for\n * the kinds that need resolver-specific backing data (`self`, `stageId`,\n * `stateRead`, `effectOutput`, `object`), so the in-instance resolver\n * ({@link resolveSource}) and the in-mutation op resolver each keep their\n * own handling of those without duplicating these four.\n */\nexport function resolveStaticSource(\n src: Source,\n ctx: {params?: Record<string, unknown>; actor?: Actor | undefined; now: string},\n): {handled: true; value: unknown} | {handled: false} {\n switch (src.source) {\n case 'literal':\n return {handled: true, value: src.value}\n case 'param':\n return {handled: true, value: ctx.params?.[src.paramId]}\n case 'actor':\n return {handled: true, value: ctx.actor}\n case 'now':\n return {handled: true, value: ctx.now}\n default:\n return {handled: false}\n }\n}\n\nexport function resolveSource(src: Source, ctx: ResolveSourceContext): unknown {\n const staticValue = resolveStaticSource(src, ctx)\n if (staticValue.handled) return staticValue.value\n switch (src.source) {\n case 'self':\n return ctx.instance._id\n case 'stageId':\n return ctx.stageId ?? ctx.instance.currentStageId\n case 'stateRead':\n return resolveStateRead(src, ctx)\n case 'effectOutput':\n return resolveEffectOutput(src, ctx)\n case 'object':\n return resolveObject(src, ctx)\n case 'row':\n case 'parentState':\n // Spawn-only sources (resolved by resolveSpawnSource); not in scope here.\n return undefined\n default:\n // literal / param / actor / now resolved above by resolveStaticSource.\n return undefined\n }\n}\n\ntype StateReadSource = Extract<Source, {source: 'stateRead'}>\ntype EffectOutputSource = Extract<Source, {source: 'effectOutput'}>\ntype ObjectSource = Extract<Source, {source: 'object'}>\n\nfunction resolveStateRead(src: StateReadSource, ctx: ResolveSourceContext): unknown {\n const value = readStateSlot(ctx.instance, src.scope, src.slotId, ctx.stageId, ctx.taskId)\n return src.path !== undefined ? getPath(value, src.path) : value\n}\n\nfunction resolveEffectOutput(src: EffectOutputSource, ctx: ResolveSourceContext): unknown {\n const entry = ctx.instance.effectsContext.find((e) => e.id === src.contextId)\n if (entry === undefined) return null\n const value = src.path !== undefined ? getPath(entry.value, src.path) : entry.value\n return value === undefined ? null : value\n}\n\nfunction resolveObject(src: ObjectSource, ctx: ResolveSourceContext): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [field, fieldSrc] of Object.entries(src.fields)) {\n out[field] = resolveSource(fieldSrc, ctx)\n }\n return out\n}\n","/**\n * Pure effect-binding resolution.\n *\n * An effect's `bindings` is a `Record<string, Source>`. This resolves each\n * binding to a concrete value (via {@link resolveSource}) and merges the\n * result with the effect's static input to form the params object the\n * handler is called with. No GROQ, no client, no I/O.\n */\n\nimport type {Source} from '../define/schema.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {WorkflowInstance} from '../types/instance.ts'\nimport {resolveSource, type ResolveSourceContext} from './source.ts'\n\n/**\n * Resolve effect bindings against an instance. Each binding is a typed\n * `Source`; the resolved values are merged with the static input. The\n * result is the params object the handler will be called with.\n */\nexport async function resolveBindings(args: {\n bindings: Record<string, Source> | undefined\n staticInput: Record<string, unknown> | undefined\n instance: WorkflowInstance\n /** Shell-supplied clock reading (ISO) backing `source: \"now\"`. */\n now: string\n params?: Record<string, unknown>\n actor?: Actor\n}): Promise<Record<string, unknown>> {\n const {bindings, staticInput, instance, now, params, actor} = args\n const resolved: Record<string, unknown> = {}\n if (bindings) {\n const ctx: ResolveSourceContext = {\n instance,\n now,\n ...(params !== undefined ? {params} : {}),\n ...(actor !== undefined ? {actor} : {}),\n }\n for (const [key, src] of Object.entries(bindings)) {\n resolved[key] = resolveSource(src, ctx)\n }\n }\n return {...resolved, ...staticInput}\n}\n","/**\n * Pure filter evaluation.\n *\n * Takes a filter (inline GROQ or named-predicate ref), a definition\n * (for predicate lookup + arg validation), a hydrated snapshot, and a\n * param bag. Runs groq-js against the snapshot. Returns boolean.\n *\n * NO CLIENT. NO I/O. NO LAKE FALLBACK.\n *\n * Filters evaluate against whatever the shell handed us — never against\n * the network. Purity is what lets the evaluator compose reactively: an\n * observable's snapshot updates can pipe straight into this function,\n * which a client-taking evaluator could not. If a filter references a\n * doc the shell didn't hydrate, groq-js sees a hole and the predicate\n * evaluates accordingly (usually false / null). Hydration completeness\n * is the shell's responsibility, not the core's.\n *\n * Discovery queries (`*[_type == 'X' && ...]` — spawn `forEach.groq`,\n * cross-doc lake scans) are NOT filters. They live in a separate shell\n * primitive (`discoverItems`) and never come through here.\n */\n\nimport {evaluate, parse} from 'groq-js'\n\nimport type {Filter, Predicate, WorkflowDefinition} from '../define/schema.ts'\nimport {isGdr} from './refs.ts'\nimport type {HydratedSnapshot} from './snapshot.ts'\n\nexport interface EvaluateFilterArgs {\n filter: Filter | undefined\n definition: WorkflowDefinition\n snapshot: HydratedSnapshot\n params: Record<string, unknown>\n}\n\n/**\n * Evaluate a filter against the supplied snapshot. Returns true when no\n * filter is set (vacuous truth). Throws on a malformed named ref or\n * invalid predicate args — those are author bugs, not runtime\n * conditions.\n */\nexport async function evaluateFilter(args: EvaluateFilterArgs): Promise<boolean> {\n const {filter, definition, snapshot, params} = args\n if (filter === undefined) return true\n\n if (typeof filter === 'string') {\n return runGroqAgainstSnapshot(filter, params, snapshot)\n }\n\n const predicate = (definition.predicates ?? []).find((p) => p.id === filter.ref)\n if (predicate === undefined) {\n throw new Error(`Unknown predicate ref: ${filter.ref}`)\n }\n validatePredicateArgs(predicate, filter.args ?? {})\n\n const merged = {...params, ...filter.args}\n return runGroqAgainstSnapshot(predicate.groq, merged, snapshot)\n}\n\nasync function runGroqAgainstSnapshot(\n groq: string,\n params: Record<string, unknown>,\n snapshot: HydratedSnapshot,\n): Promise<boolean> {\n // No `*`? Pure-param query. Empty dataset is fine.\n if (!groq.includes('*')) {\n const tree = parse(groq, {params})\n const value = await evaluate(tree, {params})\n return Boolean(await value.get())\n }\n // `*`-touching query. Evaluate against the in-memory snapshot.\n const tree = parse(groq, {params})\n const value = await evaluate(tree, {dataset: snapshot.docs, params})\n return Boolean(await value.get())\n}\n\nfunction validatePredicateArgs(predicate: Predicate, args: Record<string, unknown>): void {\n for (const param of predicate.params ?? []) {\n validatePredicateParam(predicate.id, param, args)\n }\n}\n\ntype PredicateParam = NonNullable<Predicate['params']>[number]\n\nfunction validatePredicateParam(\n predicateId: string,\n param: PredicateParam,\n args: Record<string, unknown>,\n): void {\n if (!(param.id in args)) {\n throw new Error(`Predicate \"${predicateId}\" requires param \"${param.id}\"`)\n }\n const value = args[param.id]\n if (!matchesParamType(param.type, value)) {\n throw new Error(\n `Predicate \"${predicateId}\" param \"${param.id}\" must be of type ${param.type}; got ${describeValue(value)}`,\n )\n }\n if (param.enum && !param.enum.includes(value as string)) {\n throw new Error(\n `Predicate \"${predicateId}\" param \"${param.id}\" must be one of ${param.enum.join(', ')}; got \"${String(value)}\"`,\n )\n }\n}\n\nfunction matchesParamType(type: PredicateParam['type'], value: unknown): boolean {\n switch (type) {\n case 'string':\n return typeof value === 'string'\n case 'number':\n return typeof value === 'number'\n case 'boolean':\n return typeof value === 'boolean'\n case 'string[]':\n return Array.isArray(value) && value.every((v) => typeof v === 'string')\n case 'reference':\n return isGdr(value)\n }\n}\n\nfunction describeValue(value: unknown): string {\n if (Array.isArray(value)) return 'array'\n if (value === null) return 'null'\n return typeof value\n}\n","/**\n * Authorization model — grants and mutation guards.\n *\n * Grants are most-permissive-wins value permissions. Mutation guards are\n * the compiled/persisted form of an authoring `Guard`: owner-registered,\n * scoped by `match`, gated by a GROQ `predicate`, enforced OPTIMISTICALLY\n * engine-side only.\n */\n\nimport type {DocumentValuePermission, MutationGuardAction} from './enums.ts'\n\n// Grants. Filters are GROQ strings evaluated through groq-js with the\n// document as the dataset and the actor id as `identity()`. Compose:\n// most-permissive wins.\n\nexport interface Grant {\n filter: string\n permissions: DocumentValuePermission[]\n}\n\n// Mutation guards — the compiled/persisted form of an authoring `Guard`. A\n// guard is owner-registered, scoped by `match`, gated by a GROQ `predicate`\n// (empty = unconditional deny), with an opaque `metadata` bag the predicate\n// can read. Enforcement is OPTIMISTIC engine-side only.\n//\n// `resourceType`/`resourceId` scope a guard to a single datasource: the engine\n// spans datasources and must record which one a guard belongs to (the content\n// lake is per-datasource and infers the resource from storage).\n\n/**\n * The lake document type for a mutation guard. Single source of truth — both\n * the runtime value (id construction, `compileGuard`, queries) and the\n * {@link MutationGuardDoc} `_type` literal derive from here, so the `temp.`\n * POC prefix drops in exactly one place at cutover.\n */\nexport const GUARD_DOC_TYPE = 'temp.system.guard'\n\nexport interface MutationGuardMatch {\n types?: string[]\n /** Bare document ids (resource-local; both published and `drafts.` forms). */\n idRefs?: string[]\n idPatterns?: string[]\n actions: MutationGuardAction[]\n}\n\n/**\n * The persisted body of a mutation guard — every field except the lake system\n * fields. Shared by {@link MutationGuardDoc} (the stored doc) and the engine's\n * compile inputs, so the field set lives in one place.\n */\nexport interface MutationGuardBody {\n /** Engine-layer: the single datasource this guard belongs to. */\n resourceType: string\n resourceId: string\n /** Registering identity — the engine robot. Only owner/admin may modify. */\n owner: string\n /**\n * Provenance — the workflow that registered this guard. The lake's own guard\n * model carries none of these; they exist so the engine can find its guards\n * for coherency refresh and housekeeping without parsing them out of `_id`.\n */\n sourceInstanceId: string\n sourceDefinitionId: string\n sourceStageId: string\n name?: string\n description?: string\n /** Bare document ids (resource-local; both published and `drafts.` forms). */\n match: MutationGuardMatch\n /** GROQ; empty string = unconditional deny. Bare ids/fields only — no GDRs. */\n predicate: string\n /** Caller-owned projected state the predicate reads as `guard.metadata.*`. */\n metadata: Record<string, unknown>\n}\n\nexport interface MutationGuardDoc extends MutationGuardBody {\n _id: string\n _type: typeof GUARD_DOC_TYPE\n // System fields are assigned by the lake on write — never sent on create\n // (an empty-string `_createdAt`/`_updatedAt` fails datetime validation).\n _rev?: string\n _createdAt?: string\n _updatedAt?: string\n}\n\n/**\n * Inputs to predicate evaluation: `document.before`/`after`, the `mutation`,\n * the `guard`, and `identity()`. `before` is null on create, `after` null on\n * delete.\n */\nexport interface MutationContext {\n before: ({_id: string; _type: string} & Record<string, unknown>) | null\n after: ({_id: string; _type: string} & Record<string, unknown>) | null\n action: MutationGuardAction\n /** Authenticated caller id, resolved as `identity()` in the predicate. */\n identity?: string\n}\n\n/**\n * Thrown when one or more guards deny a mutation. POC: raised by the engine /\n * bench enforcement layer; carries every denial. Fail-closed: a predicate that\n * errors or is non-true denies.\n */\nexport class MutationGuardDeniedError extends Error {\n readonly denied: Array<{guardId: string; name?: string}>\n readonly documentId: string\n readonly action: MutationGuardAction\n\n constructor(args: {\n documentId: string\n action: MutationGuardAction\n denied: Array<{guardId: string; name?: string}>\n }) {\n const ids = args.denied.map((d) => d.guardId).join(', ')\n super(`Mutation on \"${args.documentId}\" (${args.action}) denied by guard(s) [${ids}]`)\n this.name = 'MutationGuardDeniedError'\n this.denied = args.denied\n this.documentId = args.documentId\n this.action = args.action\n }\n}\n","/**\n * Pure compilation and evaluation of lake mutation guards.\n *\n * NO CLIENT. NO I/O. The shell resolves a stage `Guard`'s `match.idRefs`\n * Sources to bare ids + a resource and its `metadata` Sources to values, then\n * hands the resolved pieces here to assemble a `temp.system.guard` doc and to\n * evaluate predicates against a `before`/`after` mutation image via groq-js.\n *\n * Guard semantics:\n * - empty predicate ⇒ unconditional deny;\n * - fail-closed — a compile/eval error or non-`true` result denies;\n * - evaluation context = document before/after + mutation + guard + identity().\n *\n * Enforcement is OPTIMISTIC: the lake does not enforce `temp.system.guard`\n * yet, so a pass here is an engine *preview*, not proof. The predicate dialect\n * is groq-js delta-mode; the guard doc is referenced as the `$guard` param and\n * `identity()` resolves to the authenticated caller, the same way `permissions.ts`\n * feeds grant filters.\n */\n\nimport {evaluate, parse} from 'groq-js'\n\nimport {\n GUARD_DOC_TYPE,\n type MutationContext,\n type MutationGuardBody,\n type MutationGuardDoc,\n} from '../types/authorization.ts'\nimport type {MutationGuardAction} from '../types/enums.ts'\n\n/** Deterministic id so deploy/retract are query-free and idempotent. */\nexport function lakeGuardId(args: {instanceDocId: string; stageId: string; index: number}): string {\n return `${GUARD_DOC_TYPE}.${args.instanceDocId}.${args.stageId}.${args.index}`\n}\n\nexport interface CompileGuardArgs extends MutationGuardBody {\n id: string\n}\n\n/** Assemble a persisted guard doc from resolved pieces. */\nexport function compileGuard(args: CompileGuardArgs): MutationGuardDoc {\n return {\n _id: args.id,\n _type: GUARD_DOC_TYPE,\n resourceType: args.resourceType,\n resourceId: args.resourceId,\n owner: args.owner,\n sourceInstanceId: args.sourceInstanceId,\n sourceDefinitionId: args.sourceDefinitionId,\n sourceStageId: args.sourceStageId,\n ...(args.name !== undefined ? {name: args.name} : {}),\n ...(args.description !== undefined ? {description: args.description} : {}),\n match: args.match,\n predicate: args.predicate,\n metadata: args.metadata,\n } satisfies MutationGuardDoc\n}\n\n/**\n * Translate a lake-wire predicate to groq-js for optimistic POC evaluation.\n * The wire dialect binds `guard` and `mutation` as predicate identifiers;\n * groq-js has no such globals, so we expose them as `$params` and rewrite the\n * references.\n * `identity()`, `delta::*`, and `before`/`after` are native to groq-js and pass\n * through. The STORED predicate stays in wire form (bare `guard`/`mutation`) so\n * it is correct when handed to the real lake; this rewrite is eval-time only.\n */\nfunction toGroqJsPredicate(predicate: string): string {\n return predicate\n .replace(/(?<!\\$)\\bguard\\./g, '$guard.')\n .replace(/(?<!\\$)\\bmutation\\./g, '$mutation.')\n}\n\n/** Glob match supporting a single `*` wildcard per pattern. */\nfunction globMatch(pattern: string, value: string): boolean {\n if (!pattern.includes('*')) return pattern === value\n const escaped = pattern.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&').replace(/\\*/g, '.*')\n return new RegExp(`^${escaped}$`).test(value)\n}\n\n/**\n * Does this guard's `match` apply to a mutation on the given document?\n * `types` and id facets are ANDed; an unspecified facet does not constrain.\n */\nexport function guardMatches(\n guard: MutationGuardDoc,\n doc: {id: string; type?: string},\n action: MutationGuardAction,\n): boolean {\n const m = guard.match\n if (!m.actions.includes(action)) return false\n if (m.types && m.types.length > 0 && !(doc.type !== undefined && m.types.includes(doc.type))) {\n return false\n }\n const hasIdFacet = (m.idRefs && m.idRefs.length > 0) || (m.idPatterns && m.idPatterns.length > 0)\n if (hasIdFacet) {\n const byRef = m.idRefs?.includes(doc.id) ?? false\n const byPattern = m.idPatterns?.some((p) => globMatch(p, doc.id)) ?? false\n if (!byRef && !byPattern) return false\n }\n return true\n}\n\n/**\n * Evaluate a guard predicate against a mutation. Returns `true` only when the\n * predicate is strictly `true` (ALLOW). Empty predicate denies. Fail-closed:\n * any thrown error or non-`true` result denies.\n */\nexport async function evaluateMutationGuard(args: {\n guard: MutationGuardDoc\n context: MutationContext\n}): Promise<boolean> {\n const {guard, context} = args\n if (guard.predicate === '') return false // alwaysDeny\n const params = {guard, mutation: {action: context.action}}\n try {\n const tree = parse(toGroqJsPredicate(guard.predicate), {mode: 'delta', params})\n const value = await evaluate(tree, {\n before: context.before,\n after: context.after,\n params,\n ...(context.identity !== undefined ? {identity: context.identity} : {}),\n })\n return (await value.get()) === true\n } catch {\n return false\n }\n}\n\n/**\n * Run every guard whose `match` applies and collect those that DENY. Empty\n * result ⇒ allowed (optimistically).\n */\nexport async function denyingGuards(args: {\n guards: MutationGuardDoc[]\n doc: {id: string; type?: string}\n context: MutationContext\n}): Promise<MutationGuardDoc[]> {\n const {guards, doc, context} = args\n const denied: MutationGuardDoc[] = []\n for (const guard of guards) {\n if (!guardMatches(guard, doc, context.action)) continue\n if (!(await evaluateMutationGuard({guard, context}))) denied.push(guard)\n }\n return denied\n}\n","import {isGdrUri, parseGdr} from './core/refs.ts'\nimport type {ParsedGdr} from './core/refs.ts'\nimport {resolveSource} from './core/source.ts'\nimport type {Source} from './define/schema.ts'\nimport type {WorkflowInstance} from './types/instance.ts'\n\nexport interface Resource {\n type: string\n id: string\n}\n\nfunction resourceOf(p: ParsedGdr): Resource {\n if (p.scheme === 'dataset') return {type: 'dataset', id: `${p.projectId}.${p.dataset}`}\n return {type: p.scheme, id: p.resourceId ?? ''}\n}\n\ninterface GdrTarget {\n parsed: ParsedGdr\n type?: string\n}\n\nexport interface BindingContext {\n instance: WorkflowInstance\n stageId: string\n /** Shell-supplied clock reading (ISO) backing `source: \"now\"`. */\n now: string\n}\n\n/**\n * Resolve a single `idRefs` Source to a GDR URI + an optional author type.\n * Returns null for unresolvable / non-GDR targets (e.g. `self`).\n */\nfunction resolveIdRefTarget(src: Source, ctx: BindingContext): GdrTarget | null {\n const value = resolveSource(src, ctx)\n if (typeof value === 'string' && isGdrUri(value)) {\n return {parsed: parseGdr(value)}\n }\n if (value && typeof value === 'object') {\n const v = value as {id?: unknown; type?: unknown}\n if (typeof v.id === 'string' && isGdrUri(v.id)) {\n return typeof v.type === 'string'\n ? {parsed: parseGdr(v.id), type: v.type}\n : {parsed: parseGdr(v.id)}\n }\n }\n return null\n}\n\n/**\n * Resolve every `idRefs` Source. Returns null if any target is unresolvable\n * (the whole guard is then deferred) or if no targets are declared.\n */\nexport function resolveIdRefTargets(\n idRefs: readonly Source[] | undefined,\n ctx: BindingContext,\n): GdrTarget[] | null {\n const targets: GdrTarget[] = []\n for (const src of idRefs ?? []) {\n const target = resolveIdRefTarget(src, ctx)\n if (target === null) return null\n targets.push(target)\n }\n return targets.length === 0 ? null : targets\n}\n\n/**\n * Enforce the single-resource invariant: every target must live in the same\n * datasource. Returns that shared resource, or throws on a span.\n */\nexport function assertSingleResource(targets: readonly GdrTarget[]): Resource {\n const resource = resourceOf(targets[0]!.parsed)\n for (const g of targets) {\n const r = resourceOf(g.parsed)\n if (r.type !== resource.type || r.id !== resource.id) {\n throw new Error(\n `Guard targets span multiple resources (${resource.type}:${resource.id} vs ${r.type}:${r.id}); a guard is single-resource.`,\n )\n }\n }\n return resource\n}\n\n/** Bare ids in both published + draft forms for each target. */\nexport function bareIdRefs(targets: readonly GdrTarget[]): string[] {\n return targets.flatMap((g) => [g.parsed.documentId, `drafts.${g.parsed.documentId}`])\n}\n\n/**\n * Effective `match.types`: author-specified wins; otherwise the distinct\n * inferred types across targets, or undefined when none were inferred.\n */\nexport function resolveMatchTypes(\n targets: readonly GdrTarget[],\n authorTypes: string[] | undefined,\n): string[] | undefined {\n if (authorTypes !== undefined) return authorTypes\n const inferred = [...new Set(targets.map((g) => g.type).filter((t): t is string => !!t))]\n return inferred.length > 0 ? inferred : undefined\n}\n\n/** Project each metadata Source to its resolved value. */\nexport function resolveMetadata(\n metadata: Record<string, Source> | undefined,\n ctx: BindingContext,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [k, src] of Object.entries(metadata ?? {})) {\n out[k] = resolveSource(src, ctx)\n }\n return out\n}\n","/**\n * Shell-side lake-guard lifecycle: deploy and retract `temp.system.guard`\n * documents as a workflow enters and exits stages. NOT pure — resolves each\n * stage `Guard`'s `match.idRefs` / `metadata` Sources against the instance,\n * splits the resolved GDR into the guard's resource (resourceType/resourceId)\n * + bare ids, and writes via `clientForGdr` into that resource.\n *\n * Single-resource is enforced here: all idRefs of one guard must resolve to\n * the same datasource (the guard lives in and references only that one).\n *\n * \"Retract\" lifts the predicate to `\"true\"` (unconditionally allow) rather\n * than deleting — the `WorkflowClient` contract has no delete, and a loop-back\n * re-enters the stage and re-deploys the real predicate. POC simplification;\n * orphan accumulation + cross-dataset non-atomicity are documented seams.\n *\n * Reconcile runs post-persist, outside the instance's `ifRevisionId` guard, so\n * both primitives gate on the instance's live committed stage (see\n * {@link committedStageId}) to drop stale / superseded reconciles. The window\n * between that live-stage read and the guard write is itself non-atomic across\n * resources — the same documented-seam direction (over-lock) as above.\n *\n * Enforcement is OPTIMISTIC: deploying a guard does not make the lake enforce\n * it. The engine evaluates guards itself (core/guards.ts); the bench throws.\n */\n\nimport {compileGuard, lakeGuardId} from './core/guards.ts'\nimport type {ParsedGdr} from './core/refs.ts'\nimport type {Guard, WorkflowDefinition} from './define/schema.ts'\nimport {\n assertSingleResource,\n bareIdRefs,\n resolveIdRefTargets,\n resolveMatchTypes,\n resolveMetadata,\n} from './guard-bindings.ts'\nimport type {MutationGuardDoc} from './types/authorization.ts'\nimport type {WorkflowClient} from './types/client.ts'\nimport type {WorkflowInstance} from './types/instance.ts'\n\nexport const GUARD_OWNER = 'robot:workflow-engine'\n/** Retracted predicate — unconditionally allows, lifting the guard. */\nexport const GUARD_LIFTED_PREDICATE = 'true'\n\ninterface ResolvedGuard {\n doc: MutationGuardDoc\n routeGdr: ParsedGdr\n}\n\n/**\n * Resolve a stage `Guard` into a persisted doc + the GDR to route the write.\n * Returns null when no target resolves to a GDR (e.g. `self` — instance-side\n * guards are deferred), or when targets span resources (rejected).\n */\nfunction resolveGuard(\n guard: Guard,\n index: number,\n instance: WorkflowInstance,\n stageId: string,\n now: string,\n): ResolvedGuard | null {\n const ctx = {instance, stageId, now}\n\n const targets = resolveIdRefTargets(guard.match.idRefs, ctx)\n if (targets === null) return null\n\n const resource = assertSingleResource(targets)\n const types = resolveMatchTypes(targets, guard.match.types)\n\n const doc = compileGuard({\n id: lakeGuardId({instanceDocId: instance._id, stageId, index}),\n resourceType: resource.type,\n resourceId: resource.id,\n owner: GUARD_OWNER,\n sourceInstanceId: instance._id,\n sourceDefinitionId: instance.workflowId,\n sourceStageId: stageId,\n ...(guard.name !== undefined ? {name: guard.name} : {}),\n ...(guard.description !== undefined ? {description: guard.description} : {}),\n match: {\n ...(types !== undefined ? {types} : {}),\n idRefs: bareIdRefs(targets),\n ...(guard.match.idPatterns !== undefined ? {idPatterns: guard.match.idPatterns} : {}),\n actions: guard.match.actions,\n },\n predicate: guard.predicate ?? '',\n metadata: resolveMetadata(guard.metadata, ctx),\n })\n\n return {doc, routeGdr: targets[0]!.parsed}\n}\n\nasync function upsertGuard(client: WorkflowClient, doc: MutationGuardDoc): Promise<void> {\n const existing = await client.getDocument(doc._id)\n if (!existing) {\n await client.create(doc)\n return\n }\n // Patch the whole body (provenance included) so create and update can never\n // disagree on which fields they persist. System fields are lake-assigned.\n const {_id, _type, _rev, _createdAt, _updatedAt, ...body} = doc\n await client.patch(doc._id).set(body).commit()\n}\n\nexport interface StageGuardArgs {\n client: WorkflowClient\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient\n instance: WorkflowInstance\n definition: WorkflowDefinition\n stageId: string\n /** Shell-supplied clock reading (ISO) backing guard `source: \"now\"`. */\n now: string\n}\n\n/** Resolve a stage's guards to their routed client + guard doc, skipping any that don't resolve. */\nfunction resolvedStageGuards(\n args: StageGuardArgs,\n): Array<{client: WorkflowClient; doc: MutationGuardDoc}> {\n const stage = args.definition.stages.find((s) => s.id === args.stageId)\n const out: Array<{client: WorkflowClient; doc: MutationGuardDoc}> = []\n for (const [index, guard] of (stage?.guards ?? []).entries()) {\n const resolved = resolveGuard(guard, index, args.instance, args.stageId, args.now)\n if (resolved === null) continue\n out.push({client: args.clientForGdr(resolved.routeGdr), doc: resolved.doc})\n }\n return out\n}\n\n/**\n * Re-read the instance's committed stage from the lake. Reconcile runs as a\n * post-persist step *outside* the instance's `ifRevisionId` guard, so a stale\n * or retried reconcile can land after a newer transition already moved the\n * instance on. Both reconcile primitives gate on this live stage so they never\n * act on a stage the instance has since left. `undefined` means the instance\n * doc is gone (deleted out of band) — both primitives then no-op, leaving the\n * deployed guards untouched (the orphan seam's over-lock direction) rather than\n * blindly deploying for, or lifting the lock of, a vanished instance.\n */\nasync function committedStageId(args: StageGuardArgs): Promise<string | undefined> {\n const live = await args.client.getDocument<WorkflowInstance>(args.instance._id)\n return live?.currentStageId\n}\n\n/**\n * Deploy every guard for a stage being entered (idempotent upsert), but only\n * while the instance is still committed to that stage. A deploy that lost the\n * race to a newer transition would otherwise re-enforce a stage the instance\n * already left — a stale lock the newer transition's retract can't see. A\n * vanished instance (`undefined`) likewise no-ops: `undefined !== stageId`.\n */\nexport async function deployStageGuards(args: StageGuardArgs): Promise<void> {\n if ((await committedStageId(args)) !== args.stageId) return\n for (const {client, doc} of resolvedStageGuards(args)) {\n await upsertGuard(client, doc)\n }\n}\n\n/**\n * Retract every guard for a stage being exited (lift predicate to allow), but\n * only once the instance has genuinely moved off that stage. Skip if it is\n * still there (a concurrent loop-back re-entered the stage and must keep its\n * lock) or gone (leave the lock as the orphan seam rather than silently\n * unlocking a vanished instance — the same over-lock direction as deploy).\n */\nexport async function retractStageGuards(args: StageGuardArgs): Promise<void> {\n const live = await committedStageId(args)\n if (live === undefined || live === args.stageId) return\n for (const {client, doc} of resolvedStageGuards(args)) {\n const existing = await client.getDocument<MutationGuardDoc>(doc._id)\n if (!existing) continue\n await client.patch(doc._id).set({predicate: GUARD_LIFTED_PREDICATE}).commit()\n }\n}\n","/** Hex-encoded random key, sliced to {@link length} chars. Used for every\n * Sanity array `_key` and document id suffix the engine mints. */\nexport function randomKey(length = 12): string {\n const bytes = new Uint8Array(length)\n globalThis.crypto.getRandomValues(bytes)\n return [...bytes]\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n .slice(0, length)\n}\n","/**\n * Pure snapshot construction.\n *\n * A `HydratedSnapshot` is an in-memory groq-js dataset of docs the\n * engine evaluator can query without touching the network. Inside it,\n * **every identity is a GDR URI** — `_id` on each top-level doc AND\n * every nested `_ref` value. That uniformity is what lets the snapshot\n * behave like a real groq-js store: `*[_id == $subject][0].team->name`\n * deref works because `_ref` URIs and `_id` URIs are in the same form;\n * `*[_id in $ancestors]...` joins work because both ends speak URI.\n *\n * The CORE rule: ids are rewritten in the snapshot, NEVER in the\n * underlying storage. Persistence stays bare. Sanity rejects `:` in\n * `_id`s, and `_ref` values inside stored docs are the bare ids Sanity\n * validated on write. The URI form is a runtime concept; the bench /\n * shell loads docs in their storage form and hands them to the core,\n * which restamps them for snapshot keying.\n *\n * **A `_ref` inside a doc is always assumed to point at a doc in the\n * same resource as its containing doc** — that's how Sanity\n * references work (same dataset, validated on write). The rewriter\n * uses the parent doc's resource to construct the GDR URI for each\n * nested `_ref`. Cross-resource refs would need an explicit envelope\n * (out of scope for now).\n */\n\nimport type {SanityDocument} from '@sanity/types'\n\nimport {gdrFromResource, type WorkflowResource} from './refs.ts'\n\n/**\n * The in-memory groq-js dataset filters evaluate against. Built once\n * per cascade entry (in the shell), passed through to `evaluateFilter`\n * (in the core) for every filter check.\n */\nexport interface HydratedSnapshot {\n /** All hydrated docs, keyed by GDR URI as `_id`. */\n docs: SanityDocument[]\n /**\n * The set of GDR URIs present in `docs`. Helpful for tests and shells\n * that want to assert \"is this doc in scope?\" — the core eval pipeline\n * itself doesn't read it.\n */\n knownIds: Set<string>\n}\n\n/**\n * One loaded doc plus the resource it came from. The shell builds\n * this list by routing reads to the right client for each doc, then\n * hands it to `buildSnapshot`.\n */\nexport interface LoadedDoc {\n doc: SanityDocument\n resource: WorkflowResource\n}\n\n/**\n * Build a snapshot from a set of loaded docs. Pure transform.\n *\n * For each `LoadedDoc { doc, resource }`:\n * - The doc's `_id` is rewritten to `gdrFromResource(resource, _id)`.\n * - Every nested `_ref` value (recursively, through objects and arrays)\n * is rewritten the same way: bare ref → URI in the parent's resource.\n * Already-qualified `_ref` URIs (containing `:`) are left alone.\n *\n * Plain string fields, numbers, booleans — anything that isn't an\n * object with a `_ref` field — pass through untouched. The rewriter is\n * structural, not schema-aware: only the `_ref` field on an object is\n * treated as a Sanity reference. Everything else is user data.\n */\nexport function buildSnapshot(args: {docs: LoadedDoc[]}): HydratedSnapshot {\n const docs: SanityDocument[] = []\n const knownIds = new Set<string>()\n for (const {doc, resource} of args.docs) {\n const uri = gdrFromResource(resource, doc._id)\n const restamped = restampForSnapshot(doc, uri, resource)\n docs.push(restamped)\n knownIds.add(uri)\n }\n return {docs, knownIds}\n}\n\n/**\n * Restamp a single doc for the snapshot — rewrite `_id` to the given\n * GDR URI, recursively rewrite every nested `_ref` to a GDR URI in the\n * doc's own resource. Pure; doesn't mutate the input.\n */\nfunction restampForSnapshot<T extends SanityDocument>(\n doc: T,\n gdrUri: string,\n resource: WorkflowResource,\n): T {\n const rewritten = rewriteRefsRecursive(doc, resource) as T\n return {...rewritten, _id: gdrUri}\n}\n\n/**\n * Walk an arbitrary JSON-ish value and rewrite every `_ref` field on\n * an object to its GDR URI form (in `resource`). Other fields and\n * non-object values pass through unchanged.\n */\nfunction rewriteRefsRecursive(value: unknown, resource: WorkflowResource): unknown {\n if (Array.isArray(value)) {\n return value.map((v) => rewriteRefsRecursive(v, resource))\n }\n if (value === null || typeof value !== 'object') return value\n const obj = value as Record<string, unknown>\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(obj)) {\n if (k === '_ref' && typeof v === 'string') {\n // Already-qualified URIs (cross-resource refs) pass through.\n out[k] = v.includes(':') ? v : gdrFromResource(resource, v)\n } else {\n out[k] = rewriteRefsRecursive(v, resource)\n }\n }\n return out\n}\n","/**\n * Per-stage instance state.\n *\n * The instance carries `stages: StageEntry[]` — one entry per stage the\n * instance has been in, in entry order. The CURRENT stage is the last\n * entry whose `exitedAt` is undefined. Past stages persist with\n * `exitedAt` set so the audit trail is complete.\n *\n * Each StageEntry owns its tasks. TaskEntry is the task's runtime state\n * (status, who/when, spawn-children). Its `id` matches the authoring\n * `Task.id`.\n */\n\nimport type {GlobalDocumentReference} from '../core/refs.ts'\nimport type {TaskStatus} from './enums.ts'\nimport type {StageId, TaskId} from './ids.ts'\nimport type {ResolvedStateSlot} from './state-slots.ts'\n\nexport interface TaskEntry {\n _key: string\n /** Matches the authoring `Task.id`. */\n id: TaskId\n status: TaskStatus\n startedAt?: string\n completedAt?: string\n completedBy?: string\n filterEvaluation?: {\n at: string\n truthy: boolean\n detail?: string\n }\n /**\n * Children spawned by this task (via `task.spawns`). Each entry is a\n * GDR pointing at a `workflow.instance` document. Used by ancestor\n * propagation to walk back up the tree.\n */\n spawnedInstances?: GlobalDocumentReference[]\n /**\n * Task-scoped resolved state slots. Reserved for the task-scope state\n * work; absent until the engine writes to it.\n */\n state?: ResolvedStateSlot[]\n}\n\nexport interface StageEntry {\n _key: string\n id: StageId\n enteredAt: string\n /** Set on transition out; absent for the current stage. */\n exitedAt?: string\n /** Stage-scoped resolved state slots. */\n state: ResolvedStateSlot[]\n tasks: TaskEntry[]\n}\n\n/**\n * The open (un-exited) {@link StageEntry} matching `currentStageId`, or\n * `undefined`. On loop-backs (re-entering a stage) several entries share\n * an id — the prior ones have `exitedAt` set, the current one does not.\n * Reads the `stages` + `currentStageId` shape shared by the persisted\n * `WorkflowInstance` and the engine's mutable copy.\n */\nexport function findOpenStageEntry(host: {\n stages: StageEntry[]\n currentStageId: StageId\n}): StageEntry | undefined {\n return host.stages.find((s) => s.id === host.currentStageId && s.exitedAt === undefined)\n}\n","/**\n * The reactive watch-set: which documents an instance's evaluation\n * depends on.\n *\n * A consumer that wants to drive the engine from live data subscribes\n * to exactly these docs, rebuilds the snapshot when any of them change,\n * and re-evaluates ({@link evaluateFromSnapshot}). The engine owns no\n * subscription itself — it only says *what* to watch.\n *\n * Pure: derivable from the persisted instance alone (resolved\n * `doc.ref`/`doc.refs`/`release.ref` slot GDRs on the workflow scope +\n * current stage, `instance.ancestors`, and the instance itself). No I/O.\n * This is the \"which ids\" half that {@link hydrateSnapshot} loads — both\n * derive the set from {@link collectWatchRefs}, so there is one source of\n * truth.\n */\n\nimport {\n type GdrUri,\n type GlobalDocumentReference,\n gdrRef,\n isGdr,\n isGdrUri,\n type ParsedGdr,\n parseGdr,\n} from './core/refs.ts'\nimport type {WorkflowPerspective} from './types/client.ts'\nimport {findOpenStageEntry} from './types/instance-state.ts'\nimport type {WorkflowInstance} from './types/instance.ts'\n\n/**\n * A document the reactive layer should subscribe to, with its GDR\n * exploded so consumers never re-parse: the resource-addressing parts\n * (from {@link ParsedGdr}), the round-trip `globalDocumentId` URI, and\n * the target doc's schema `_type`. The resource parts let an adapter\n * detect refs pointing at a project/dataset/resource it isn't\n * configured for; `type` feeds per-doc handles (`useDocument` /\n * `editState`).\n */\nexport interface SubscriptionDocument extends ParsedGdr {\n /** Full GDR URI — resource-qualified identity, for round-trip / snapshot keying. */\n globalDocumentId: GdrUri\n /** Target doc's schema `_type`. */\n type: string\n}\n\n/**\n * Every {@link GlobalDocumentReference} an instance's evaluation reads:\n * the instance itself, its ancestors, the **content** docs named by\n * resolved `doc.ref`/`doc.refs` slots, and the **release** docs named by\n * `release.ref` slots — on the workflow scope and the current stage.\n * Order: self, ancestors, content slots, release slots. May contain\n * duplicates and non-GDR ids — the loader and\n * {@link subscriptionDocumentsForInstance} handle those respectively.\n */\nexport function collectWatchRefs(instance: WorkflowInstance): GlobalDocumentReference[] {\n const stage = findOpenStageEntry(instance)\n return [\n gdrRef(instance.workflowResource, instance._id, instance._type),\n ...instance.ancestors,\n ...slotDocRefs(instance.state),\n ...slotDocRefs(stage?.state),\n ...slotReleaseRefs(instance.state),\n ...slotReleaseRefs(stage?.state),\n ]\n}\n\n/**\n * Whether a watched ref reads RAW — never perspective-scoped. The\n * instance, its ancestors (both `workflow.instance`), and `release.ref`\n * system docs (`system.release`) are not versioned by a release\n * perspective; everything else is content and resolves to its\n * version/draft/published form. This is the single encoding of the rule\n * the {@link WatchSet} `perspective` contract describes to consumers, and\n * the rule {@link hydrateSnapshot} applies on the fetch side.\n */\nexport function readsRaw(ref: {type: string}): boolean {\n return ref.type === 'workflow.instance' || ref.type === 'system.release'\n}\n\n/**\n * The Content Release a watched doc resolves under, or `undefined` for a raw\n * read — how a reactive adapter turns the watch-set's perspective into the\n * per-doc release its store needs. Instance / ancestor / `system.release` docs\n * read raw ({@link readsRaw}); a content doc resolves under the **leading**\n * release in the stack. The engine never forms the `versions.<release>.<id>`\n * id — the adapter does (Studio's `editState` version arg, the SDK handle\n * `{releaseName}`). A non-array perspective (`raw`/`published`/`drafts`)\n * carries no release, so content falls back to draft/published.\n *\n * Note: this resolves a **single** release — the documented `instance.perspective`\n * shapes (`[release]` / `[release, \"drafts\"]`). The stores' per-doc reads take\n * one release, so a multi-release stack can't be observed reactively here; the\n * engine's own fetch path ({@link hydrateSnapshot}) honours the full stack via\n * `client.fetch({perspective})`.\n */\nexport function contentReleaseName(args: {\n ref: {type: string}\n perspective: WorkflowPerspective | undefined\n}): string | undefined {\n const {ref, perspective} = args\n if (readsRaw(ref)) return undefined\n if (!Array.isArray(perspective)) return undefined\n return perspective.find((entry) => entry !== 'drafts' && entry !== 'published' && entry !== 'raw')\n}\n\n/**\n * The reactive subscription target for an instance: the exploded,\n * deduped watch-set plus the instance's read {@link WorkflowPerspective}.\n */\nexport interface WatchSet {\n /**\n * Docs to subscribe to — instance + ancestors + the docs named by\n * `doc.ref`/`doc.refs`/`release.ref` slots — deduped by\n * `globalDocumentId`. Refs that aren't resource-qualified GDR URIs are\n * skipped (without a resource there's nothing to subscribe against).\n */\n documents: SubscriptionDocument[]\n /**\n * The instance's effective read perspective (a release stack like\n * `[releaseName]` or `[releaseName, \"drafts\"]`), already resolved at\n * `startInstance`. `undefined` means raw/published.\n *\n * The engine does not form `versions.<release>.<id>` ids — it has no\n * such concept (it reads content through `client.fetch({perspective})`\n * for queries). A reactive consumer applies this perspective when it\n * subscribes: a **content** doc must be resolved to its version /\n * draft / published form (e.g. Studio `editState`'s version param, or\n * the SDK's `getVersionId`), while instance / ancestor / `system.release`\n * docs are always raw. The `type` on each {@link SubscriptionDocument}\n * tells the consumer which is which.\n */\n perspective?: WorkflowPerspective\n}\n\nexport function subscriptionDocumentsForInstance(instance: WorkflowInstance): WatchSet {\n const seen = new Set<string>()\n const documents: SubscriptionDocument[] = []\n for (const ref of collectWatchRefs(instance)) {\n if (!isGdrUri(ref.id) || seen.has(ref.id)) continue\n seen.add(ref.id)\n documents.push({...parseGdr(ref.id), globalDocumentId: ref.id, type: ref.type})\n }\n return {\n documents,\n ...(instance.perspective !== undefined ? {perspective: instance.perspective} : {}),\n }\n}\n\n/**\n * Pull the {@link GlobalDocumentReference} values out of `doc.ref` /\n * `doc.refs` (content) state slots. Content only — release slots come\n * from {@link slotReleaseRefs}, so guard discovery (which reads this via\n * `collectSlotDocUris`) stays scoped to content docs.\n */\nexport function slotDocRefs(slots: unknown): GlobalDocumentReference[] {\n return slotEntries(slots).flatMap((slot) => {\n if (slot._type === 'workflow.state.doc.ref') {\n return isGdr(slot.value) ? [slot.value] : []\n }\n if (slot._type === 'workflow.state.doc.refs') {\n return Array.isArray(slot.value) ? slot.value.filter(isGdr) : []\n }\n return []\n })\n}\n\n/**\n * Pull the {@link GlobalDocumentReference} values out of `release.ref`\n * state slots — a `release.ref` value is a `ReleaseRef`, a GDR\n * (`type: \"system.release\"`) pointing at the `_.releases.<name>` system\n * doc, so a release changing re-evaluates the instance. Separate from\n * {@link slotDocRefs}: release docs are watched but read RAW (a release\n * perspective doesn't version a system doc), and guard discovery must not\n * follow them.\n */\nfunction slotReleaseRefs(slots: unknown): GlobalDocumentReference[] {\n return slotEntries(slots).flatMap((slot) =>\n slot._type === 'workflow.state.release.ref' && isGdr(slot.value) ? [slot.value] : [],\n )\n}\n\n/**\n * Narrow a polymorphic resolved-slot array to the `{_type, value}` shape\n * the ref extractors read. Tolerates `unknown` (resolved slot arrays are\n * polymorphic) and drops non-object entries.\n */\nfunction slotEntries(slots: unknown): {_type?: string; value?: unknown}[] {\n if (!Array.isArray(slots)) return []\n return slots.filter(\n (slot): slot is {_type?: string; value?: unknown} => !!slot && typeof slot === 'object',\n )\n}\n","/**\n * Shell-side snapshot hydration.\n *\n * The core defines `HydratedSnapshot`, `LoadedDoc`, and the pure\n * `buildSnapshot` transform (recursive `_ref` + `_id` rewriting to\n * GDR URIs). This module does the I/O: route each read to the right\n * resource client, gather loaded docs with their resource attribution,\n * hand the list to `buildSnapshot`.\n *\n * **Scope rule (the contract):** a doc is in the snapshot iff it is\n * - the workflow instance itself,\n * - any ancestor doc (from `instance.ancestors[].id`),\n * - a doc declared by a `workflow.state.doc.ref` / `.doc.refs` slot on\n * the workflow OR the current stage,\n * - or the `system.release` doc named by a `release.ref` slot.\n *\n * Authors who want their filters to read a referenced doc via `->`\n * deref MUST declare a doc.ref / doc.refs slot pointing at it. The\n * shell loads exactly what's declared; the core rewrites refs purely\n * over that set. No transitive crawling; no surprise hops.\n *\n * **Perspective:** content docs (`doc.ref`/`doc.refs`) are read under the\n * instance's `perspective` so a workflow in a Content Release sees its\n * subject's version content. The instance, ancestors (both\n * `workflow.instance`), and `release.ref` system docs are always read RAW\n * — per the engine contract, and because a release perspective doesn't\n * version those.\n */\n\nimport type {SanityDocument} from '@sanity/types'\n\nimport {parseGdr, selfGdr, type ParsedGdr, type WorkflowResource} from './core/refs.ts'\nimport {buildSnapshot, type HydratedSnapshot, type LoadedDoc} from './core/snapshot.ts'\nimport {collectWatchRefs, readsRaw, slotDocRefs} from './subscription-documents.ts'\nimport type {WorkflowClient, WorkflowPerspective} from './types/client.ts'\nimport type {WorkflowInstance} from './types/instance.ts'\n\n/**\n * Build the in-memory snapshot for filter evaluation on the instance's\n * current stage. Routed reads, then pure construction.\n *\n * The set of docs loaded is exactly {@link collectWatchRefs} — the same\n * watch-set {@link subscriptionDocumentsForInstance} emits, so the\n * reactive read path and the fetch path stay in lockstep. The instance\n * itself is already in hand, so it's pushed directly; everything else is\n * routed through `clientForGdr`.\n *\n * A doc that resolves to `null` (missing, or ACL-filtered to nothing)\n * simply isn't in the snapshot — predicates referencing it see\n * `null` / empty results. A read that *throws* (client/transport error)\n * propagates and fails the whole hydration; it is not swallowed.\n */\nexport async function hydrateSnapshot(args: {\n client: WorkflowClient\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient\n instance: WorkflowInstance\n /**\n * Content overlay — doc values the consumer already holds, keyed by GDR\n * URI. An id present here is used as-is (last-write-wins, scoped to the\n * watch-set); absent ids are loaded. The reactive session supplies this\n * so held content isn't refetched; absent → today's fetch behaviour.\n */\n overlay?: ReadonlyMap<string, LoadedDoc>\n}): Promise<HydratedSnapshot> {\n const {client, clientForGdr, instance, overlay} = args\n const loaded: LoadedDoc[] = []\n const visited = new Set<string>()\n\n const loadInto = async (\n uri: string,\n perspective: WorkflowPerspective | undefined,\n ): Promise<void> => {\n if (visited.has(uri)) return\n const held = overlay?.get(uri)\n if (held !== undefined) {\n loaded.push(held)\n visited.add(uri)\n return\n }\n const fetched = await loadByGdr(\n client,\n clientForGdr,\n instance.workflowResource,\n uri,\n perspective,\n )\n if (fetched) {\n loaded.push(fetched)\n visited.add(uri)\n }\n }\n\n // The instance itself is already loaded. Push it directly and key it\n // with the same GDR-URI form `buildSnapshot` uses, so a self-\n // referential ancestor/slot dedups against it (collectWatchRefs lists\n // self first, but loadInto will skip it as already-visited).\n loaded.push({doc: instance, resource: instance.workflowResource})\n visited.add(selfGdr(instance))\n\n // Content docs honor the instance's perspective; instance / ancestor /\n // release docs read RAW (see {@link readsRaw} — the one home for that\n // rule, shared with the WatchSet contract the reactive consumer follows).\n for (const ref of collectWatchRefs(instance)) {\n await loadInto(ref.id, readsRaw(ref) ? undefined : instance.perspective)\n }\n\n return buildSnapshot({docs: loaded})\n}\n\nasync function loadByGdr(\n defaultClient: WorkflowClient,\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient,\n defaultResource: WorkflowResource,\n uri: string,\n perspective: WorkflowPerspective | undefined,\n): Promise<LoadedDoc | null> {\n let parsed: ParsedGdr\n try {\n parsed = parseGdr(uri)\n } catch {\n // Not a GDR URI — load the value directly against the default\n // client. Without a parsed GDR we can't know the resource, so we\n // attribute the doc to the default client's own resource.\n const doc = await readDoc(defaultClient, uri, perspective)\n if (!doc) return null\n return {doc, resource: defaultResource}\n }\n const routed = clientForGdr(parsed)\n const doc = await readDoc(routed, parsed.documentId, perspective)\n if (!doc) return null\n return {doc, resource: resourceFromParsed(parsed)}\n}\n\n/**\n * Read one doc by id, honoring the instance's read perspective. Without\n * a perspective it's a raw point read (`getDocument`). With one — a\n * release stack like `[releaseName]` — the read goes through\n * `fetch(..., {perspective})` so version/draft content is projected onto\n * the published id and a content doc that exists only inside a release is\n * still visible to filters. Mirrors how state-slot query resolution\n * already reads under perspective. The caller decides which reads are\n * perspective-scoped (content) vs raw — see {@link readsRaw}.\n */\nasync function readDoc(\n client: WorkflowClient,\n id: string,\n perspective: WorkflowPerspective | undefined,\n): Promise<SanityDocument | null> {\n if (perspective === undefined) {\n return (await client.getDocument<SanityDocument>(id)) ?? null\n }\n const doc = await client.fetch<SanityDocument | null>('*[_id == $id][0]', {id}, {perspective})\n return doc ?? null\n}\n\nexport function resourceFromParsed(parsed: ParsedGdr): WorkflowResource {\n if (parsed.scheme === 'dataset') {\n return {type: 'dataset', id: `${parsed.projectId}.${parsed.dataset}`}\n }\n return {type: parsed.scheme, id: parsed.resourceId ?? ''}\n}\n\n/**\n * Walk resolved state slots and collect every GDR URI mentioned by a\n * `doc.ref` or `doc.refs` slot's value. The GDR-keyed id list lake\n * guard discovery needs; {@link slotDocRefs} is the typed source.\n */\nexport function collectSlotDocUris(resolvedStateSlots: unknown): string[] {\n return slotDocRefs(resolvedStateSlots).map((ref) => ref.id)\n}\n","// Instance — the persisted `workflow.instance` document.\n\nimport type {SanityDocument} from '@sanity/types'\n\nimport type {GlobalDocumentReference, WorkflowResource} from '../core/refs.ts'\nimport type {WorkflowPerspective} from './client.ts'\nimport type {EffectHistoryEntry, EffectsContextEntry, PendingEffect} from './effects.ts'\nimport type {HistoryEntry} from './history.ts'\nimport type {StageId} from './ids.ts'\nimport type {StageEntry} from './instance-state.ts'\nimport type {ResolvedStateSlot} from './state-slots.ts'\n\n/**\n * The lake document type for a workflow instance. Single source of truth — the\n * {@link WorkflowInstance} `_type`, every tag-scoped query, and the create\n * write all derive from here, mirroring {@link WORKFLOW_DEFINITION_TYPE}.\n */\nexport const WORKFLOW_INSTANCE_TYPE = 'workflow.instance'\n\nexport interface WorkflowInstance extends SanityDocument {\n _type: typeof WORKFLOW_INSTANCE_TYPE\n /**\n * Engine-scope tags stamped on the instance at create time. Engines\n * with disjoint tag sets cannot read this instance; engines sharing\n * any tag with this array can.\n */\n tags: string[]\n /**\n * The Sanity resource this instance lives in. Stored on the doc so\n * any internal operation can mint GDRs for ancestors / spawned\n * children / etc. without re-supplying it. Mirrors\n * `@sanity/client`'s `ClientConfigResource`.\n */\n workflowResource: WorkflowResource\n workflowId: string\n pinnedVersion: number\n /** Frozen JSON snapshot of the definition at the moment the instance started. */\n definitionSnapshot: string\n /**\n * Workflow-level resolved state slots.\n * Populated from the workflow definition's `state[]` declarations plus\n * the caller-supplied `initialState` at `startInstance`. Persists for\n * the lifetime of the instance.\n *\n * To declare \"the subject document of this workflow\", add a\n * `{ type: \"workflow.state.doc.ref\", id: \"subject\", source: { kind: \"init\" } }`\n * slot to the workflow definition. The `$subject` GROQ binding then\n * resolves to that slot's value. There is no other subject mechanism.\n */\n state: ResolvedStateSlot[]\n /**\n * Stable named params the runtime hands to effect handlers via binding\n * resolution. Set at `startInstance`. **Not read by transition filters.**\n */\n effectsContext: EffectsContextEntry[]\n /**\n * Chain of ancestor workflow instances, root-first. Each entry is a\n * GDR pointing at a workflow.instance document in the engine's own\n * workflow resource.\n */\n ancestors: GlobalDocumentReference[]\n /**\n * Optional perspective applied to state-slot query reads and spawn\n * `forEach.groq` discovery. When unset the engine treats reads as\n * `\"raw\"` (no filtering). Set at `startInstance` time to scope a\n * workflow's reads to a Content Release stack (e.g. `[releaseName]`\n * or `[releaseName, \"drafts\"]`).\n *\n * Engine-internal reads of `workflow.instance` / `workflow.definition`\n * are always raw, regardless of this field.\n */\n perspective?: WorkflowPerspective\n currentStageId: StageId\n /**\n * Per-stage instance entries — one StageEntry per stage the instance\n * has been in, in entry order. Past stages persist with `exitedAt`\n * set; the current stage is the entry whose `exitedAt` is undefined.\n * Each entry owns its tasks.\n */\n stages: StageEntry[]\n pendingEffects: PendingEffect[]\n effectHistory: EffectHistoryEntry[]\n history: HistoryEntry[]\n startedAt: string\n lastChangedAt: string\n completedAt?: string\n}\n","/**\n * Per-slot-type value validation.\n *\n * Every write into a typed slot must match the slot's declared shape.\n * The validator is called at three boundaries:\n *\n * 1. `workflow.op.state.set` — full-value replace on any slot\n * 2. `workflow.op.state.append` — one-item push on array slots\n * 3. `resolveDeclaredState` — init / literal / stateRead / query\n *\n * `validateSlotValue` checks a complete slot value against the slot\n * type's shape (scalar or array-of-items, depending on the kind).\n *\n * `validateSlotAppendItem` checks a single item against the slot's\n * row shape (only array slots support append).\n *\n * Both throw `SlotValueShapeError` with the slot id, slot type and a\n * brief description of the observed shape — so the cause is obvious\n * in test output, drive-script stdout, and the workflow history.\n *\n * Notes stays permissive (any object with optional `_key`) pending a\n * dedicated row-shape design.\n */\n\nimport * as v from 'valibot'\n\nimport {isGdrUri} from './refs.ts'\n\nclass SlotValueShapeError extends Error {\n readonly slotType: string\n readonly slotId: string\n readonly issues: string[]\n\n constructor(args: {slotType: string; slotId: string; issues: string[]; mode: 'value' | 'item'}) {\n const issueText = args.issues.join('; ')\n super(`Slot ${args.mode} shape invalid for \"${args.slotId}\" (${args.slotType}): ${issueText}`)\n this.name = 'SlotValueShapeError'\n this.slotType = args.slotType\n this.slotId = args.slotId\n this.issues = args.issues\n }\n}\n\n// Per-shape schemas — used both for whole-value and per-item validation.\n\nconst GdrShape = v.looseObject({\n id: v.pipe(\n v.string(),\n v.check((s) => isGdrUri(s), 'must be a GDR URI'),\n ),\n type: v.pipe(v.string(), v.minLength(1)),\n})\n\n// Release ref: a GDR to the `_.releases.<name>` system doc, plus the\n// bare release name the engine reads to derive perspective.\nconst ReleaseRefShape = v.looseObject({\n id: v.pipe(\n v.string(),\n v.check((s) => isGdrUri(s), 'must be a GDR URI'),\n ),\n type: v.literal('system.release'),\n releaseName: v.pipe(v.string(), v.minLength(1)),\n})\n\nconst ActorShape = v.looseObject({\n kind: v.picklist(['user', 'ai', 'system']),\n id: v.pipe(v.string(), v.minLength(1)),\n roles: v.optional(v.array(v.string())),\n onBehalfOf: v.optional(v.string()),\n})\n\nconst AssigneeShape = v.union([\n v.looseObject({kind: v.literal('user'), id: v.pipe(v.string(), v.minLength(1))}),\n v.looseObject({kind: v.literal('role'), role: v.pipe(v.string(), v.minLength(1))}),\n])\n\nconst ChecklistItemShape = v.looseObject({\n label: v.pipe(v.string(), v.minLength(1)),\n done: v.boolean(),\n doneBy: v.optional(v.string()),\n doneAt: v.optional(v.string()),\n _key: v.optional(v.pipe(v.string(), v.minLength(1))),\n})\n\n// Notes are intentionally loose pending the row-shape design.\nconst NoteItemShape = v.pipe(\n v.looseObject({\n _key: v.optional(v.pipe(v.string(), v.minLength(1))),\n }),\n v.check(\n (val) => typeof val === 'object' && val !== null && !Array.isArray(val),\n 'must be an object',\n ),\n)\n\n// Scalars that allow null (write-sourced slots default to null until written).\nconst NullableString = v.union([v.null(), v.string()])\nconst NullableNumber = v.union([v.null(), v.number()])\nconst NullableBoolean = v.union([v.null(), v.boolean()])\n\n// dateTime: stricter than plain string — must parse as ISO-8601.\nconst NullableDateTime = v.union([\n v.null(),\n v.pipe(\n v.string(),\n v.check((s) => !Number.isNaN(Date.parse(s)), 'must be an ISO-8601 datetime string'),\n ),\n])\n\n// URL: loose — accept any non-empty string. Tightening later is easy;\n// loosening would break already-stored values.\nconst NullableUrl = NullableString\n\n// Whole-value schemas, keyed by slot type.\n\nconst valueSchemas = {\n 'workflow.state.doc.ref': v.union([v.null(), GdrShape]),\n 'workflow.state.doc.refs': v.array(GdrShape),\n 'workflow.state.release.ref': v.union([v.null(), ReleaseRefShape]),\n 'workflow.state.query': v.any(),\n 'workflow.state.value.string': NullableString,\n 'workflow.state.value.url': NullableUrl,\n 'workflow.state.value.number': NullableNumber,\n 'workflow.state.value.boolean': NullableBoolean,\n 'workflow.state.value.dateTime': NullableDateTime,\n 'workflow.state.value.actor': v.union([v.null(), ActorShape]),\n 'workflow.state.checklist': v.array(ChecklistItemShape),\n 'workflow.state.notes': v.array(NoteItemShape),\n 'workflow.state.assignees': v.array(AssigneeShape),\n} as const\n\n// Per-item schemas for `workflow.op.state.append`. Scalar slot types\n// don't support append — callers asking for them get an error.\n\nconst itemSchemas = {\n 'workflow.state.doc.refs': GdrShape,\n 'workflow.state.checklist': ChecklistItemShape,\n 'workflow.state.notes': NoteItemShape,\n 'workflow.state.assignees': AssigneeShape,\n} as const\n\ntype AppendableSlotType = keyof typeof itemSchemas\n\nfunction isAppendable(slotType: string): slotType is AppendableSlotType {\n return slotType in itemSchemas\n}\n\n// Public API.\n\nexport function validateSlotValue(args: {slotType: string; slotId: string; value: unknown}): void {\n const schema = (valueSchemas as Record<string, v.GenericSchema>)[args.slotType]\n if (schema === undefined) {\n throw new SlotValueShapeError({\n slotType: args.slotType,\n slotId: args.slotId,\n issues: [`unknown slot type ${args.slotType}`],\n mode: 'value',\n })\n }\n const result = v.safeParse(schema, args.value)\n if (!result.success) {\n throw new SlotValueShapeError({\n slotType: args.slotType,\n slotId: args.slotId,\n issues: formatIssues(result.issues),\n mode: 'value',\n })\n }\n}\n\nexport function validateSlotAppendItem(args: {\n slotType: string\n slotId: string\n item: unknown\n}): void {\n if (!isAppendable(args.slotType)) {\n throw new SlotValueShapeError({\n slotType: args.slotType,\n slotId: args.slotId,\n issues: [`slot type ${args.slotType} does not support append`],\n mode: 'item',\n })\n }\n const schema = itemSchemas[args.slotType]\n const result = v.safeParse(schema, args.item)\n if (!result.success) {\n throw new SlotValueShapeError({\n slotType: args.slotType,\n slotId: args.slotId,\n issues: formatIssues(result.issues),\n mode: 'item',\n })\n }\n}\n\nfunction formatIssues(issues: readonly v.BaseIssue<unknown>[]): string[] {\n return issues.map((i) => {\n const keys = i.path?.map((p) => p.key) ?? []\n const path = keys.length > 0 ? `at ${keys.join('.')}: ` : ''\n return `${path}${i.message}`\n })\n}\n","/**\n * Resolve a definition's `state[]` declarations into `ResolvedStateSlot`s.\n *\n * Shared by:\n * - `workflow.startInstance` (workflow-scope state)\n * - engine stage entry (stage-scope state on StageEntry)\n * - engine task activation (task-scope state on TaskEntry)\n *\n * Source-kind semantics:\n * - `kind: \"init\"` reads from caller-supplied `initialState`.\n * - `kind: \"query\"` runs the slot's GROQ against the lake via the\n * supplied client; result lands as the slot value with `resolvedAt`\n * stamped on `workflow.state.query` slots.\n * - `kind: \"write\"` defaults to null (scalars) or `[]` (array kinds);\n * ops fill it later.\n */\n\nimport {paramsForLake} from './core/params.ts'\nimport {getPath} from './core/path.ts'\nimport {gdrFromResource, isGdrUri, type WorkflowResource} from './core/refs.ts'\nimport {validateSlotValue} from './core/slot-validation.ts'\nimport type {StateSlot} from './define/schema.ts'\nimport type {WorkflowClient, WorkflowPerspective} from './types/client.ts'\nimport type {InitialStateValue, ResolvedStateSlot} from './types/state-slots.ts'\n\nexport interface ResolveStateContext {\n /** Lake client for `kind: \"query\"` slot evaluation. Omitted → query\n * slots fall back to their default value. */\n client?: WorkflowClient\n /**\n * Shell-supplied clock reading (ISO). Bound as `$now` for query-slot\n * GROQ and stamped as `resolvedAt` on `workflow.state.query` slots, so\n * state resolution shares the engine's single {@link Clock}.\n */\n now: string\n selfId?: string\n tags?: string[]\n /** Bound to `$stage` inside stage/task-scope query slots. */\n stageId?: string\n /** Bound to `$task` inside task-scope query slots. */\n taskId?: string\n /**\n * Already-resolved state slots in the SAME scope being resolved\n * right now. Exposed to subsequent query-sourced slots as\n * `$state.<slotId>`; also the lookup target for\n * `source: { kind: \"stateRead\", scope: \"stage\" }` on a sibling\n * stage-scope slot. Sequential resolution means slot N's source can\n * read slots 0..N-1 by id but not later ones.\n */\n resolvedState?: ResolvedStateSlot[]\n /**\n * Already-resolved workflow-scope state. Available when resolving\n * stage- or task-scope slots so a `source: { kind: \"stateRead\",\n * scope: \"workflow\" }` can read durable workflow-scope slots that\n * were resolved at `startInstance` time.\n */\n workflowState?: ResolvedStateSlot[]\n /**\n * Resource of the workflow itself. Used to canonicalize raw Sanity\n * reference shapes (`{_ref, _type}`) returned by `kind: \"query\"`\n * slots into GDR `{id, type}` form. Without this, a query-sourced\n * doc.ref slot would leave its value in the lake shape and the\n * snapshot hydrator wouldn't know to pull the referenced doc into\n * scope.\n */\n workflowResource?: WorkflowResource\n /**\n * Perspective for `kind: \"query\"` slot evaluation. Threaded through\n * to `client.fetch(..., { perspective })`. Lets a slot that runs\n * GROQ against the lake see a release-stacked view rather than the\n * published shadow. Unset → reads run under the client's default\n * perspective (which is `\"raw\"` on the test client and whatever the\n * caller configured on `@sanity/client`).\n */\n perspective?: WorkflowPerspective\n}\n\n/**\n * Derive a read perspective from resolved workflow-scope state: if any\n * `workflow.state.release.ref` slot has a value, return a single-release\n * stack `[releaseName]`. Returns `undefined` when no release slot is\n * populated, so callers can fall back to an explicit perspective or\n * the engine default.\n *\n * The first populated release slot wins (workflows targeting more than\n * one release aren't modelled — a single release-ref slot is the\n * canonical shape). Pure: operates on already-resolved slots.\n */\nexport function derivePerspectiveFromState(\n slots: ResolvedStateSlot[] | undefined,\n): WorkflowPerspective | undefined {\n if (slots === undefined) return undefined\n for (const slot of slots) {\n if (slot._type === 'workflow.state.release.ref' && slot.value !== null) {\n const releaseName = slot.value.releaseName\n if (typeof releaseName === 'string' && releaseName.length > 0) {\n return [releaseName]\n }\n }\n }\n return undefined\n}\n\nexport async function resolveDeclaredState(args: {\n slotDefs: StateSlot[] | undefined\n initialState: InitialStateValue[]\n ctx: ResolveStateContext\n randomKey: () => string\n}): Promise<ResolvedStateSlot[]> {\n const {slotDefs, initialState, ctx, randomKey} = args\n if (slotDefs === undefined || slotDefs.length === 0) return []\n const out: ResolvedStateSlot[] = []\n for (const slot of slotDefs) {\n // Each slot sees the already-resolved ones via `$state.<slotId>`.\n const scopedCtx: ResolveStateContext = {...ctx, resolvedState: out}\n out.push(await resolveOneSlot(slot, initialState, scopedCtx, randomKey))\n }\n return out\n}\n\nconst ARRAY_SLOT_TYPES = new Set<StateSlot['type']>([\n 'workflow.state.doc.refs',\n 'workflow.state.checklist',\n 'workflow.state.notes',\n 'workflow.state.assignees',\n])\n\n/** Default for an unfilled slot: `[]` for array kinds, `null` otherwise. */\nfunction defaultSlotValue(slotType: StateSlot['type']): unknown {\n return ARRAY_SLOT_TYPES.has(slotType) ? [] : null\n}\n\n/**\n * Read a caller-supplied `init` value. Rejects bare doc ids at the\n * boundary: the engine stores GDR URIs throughout — callers MUST\n * construct full URIs (via `gdrFromResource` / `refDataset` / etc.)\n * before passing them into `initialState`. Silent canonicalisation\n * would mask the shape gap and let bare-id refs leak into snapshots,\n * where they mismatch every GDR-keyed lookup and break filters.\n */\nfunction resolveInitValue(\n slot: StateSlot,\n initialState: InitialStateValue[],\n defaultValue: unknown,\n): unknown {\n const initMatch = initialState.find((s) => s.id === slot.id && s.type === slot.type)\n if (initMatch === undefined) return defaultValue\n assertInitValueShape(slot, initMatch.value)\n return initMatch.value\n}\n\nfunction resolveStateReadValue(\n source: Extract<StateSlot['source'], {kind: 'stateRead'}>,\n ctx: ResolveStateContext,\n defaultValue: unknown,\n): unknown {\n const slotsForScope =\n source.scope === 'workflow' ? (ctx.workflowState ?? []) : (ctx.resolvedState ?? [])\n const target = slotsForScope.find((s) => s.id === source.slotId)\n const targetValue = target === undefined ? undefined : (target as {value?: unknown}).value\n const resolved = source.path !== undefined ? getPath(targetValue, source.path) : targetValue\n return resolved === undefined || resolved === null ? defaultValue : resolved\n}\n\n/**\n * Run a `query` slot's GROQ against the lake. Params carry GDR URIs\n * (snapshot form) but are stripped to bare for the fetch — same pattern\n * as filter evaluation's lake fallback: the lake stores bare `_id`s, so\n * `$state.<slot>.value.id` etc. must be bare too.\n *\n * `$state` exposes slots already resolved before this one (sequential\n * resolution). Cyclic references to later slots produce `undefined` in\n * GROQ and the slot falls through to its default.\n */\nasync function resolveQueryValue(\n slot: StateSlot,\n source: Extract<StateSlot['source'], {kind: 'query'}>,\n ctx: ResolveStateContext,\n client: WorkflowClient,\n defaultValue: unknown,\n): Promise<unknown> {\n const params = paramsForLake({\n self: ctx.selfId ?? null,\n state: stateMapFromResolved(ctx.resolvedState ?? []),\n stage: ctx.stageId ?? null,\n task: ctx.taskId ?? null,\n now: ctx.now,\n engineTags: ctx.tags ?? [],\n })\n try {\n const fetchOptions = ctx.perspective !== undefined ? {perspective: ctx.perspective} : undefined\n const result = await client.fetch<unknown>(source.query, params, fetchOptions)\n return normalizeQueryResult(slot.type, result, ctx.workflowResource) ?? defaultValue\n } catch (err) {\n throw new Error(\n `Failed to resolve query slot \"${slot.id}\" (${slot.type}): ${\n err instanceof Error ? err.message : String(err)\n }`,\n {cause: err},\n )\n }\n}\n\nasync function resolveSlotValue(\n slot: StateSlot,\n initialState: InitialStateValue[],\n ctx: ResolveStateContext,\n defaultValue: unknown,\n): Promise<unknown> {\n const source = slot.source\n if (source.kind === 'init') return resolveInitValue(slot, initialState, defaultValue)\n if (source.kind === 'literal') return source.value ?? defaultValue\n if (source.kind === 'stateRead') return resolveStateReadValue(source, ctx, defaultValue)\n if (source.kind === 'query' && ctx.client !== undefined) {\n return resolveQueryValue(slot, source, ctx, ctx.client, defaultValue)\n }\n // \"write\" (and \"query\" without a client) use defaults.\n return defaultValue\n}\n\n/** Build the persisted slot envelope; `query` slots carry `resolvedAt`. */\nfunction buildResolvedSlot(\n slot: StateSlot,\n value: unknown,\n _key: string,\n now: string,\n): ResolvedStateSlot {\n const titleProp = slot.title !== undefined ? {title: slot.title} : {}\n const descriptionProp = slot.description !== undefined ? {description: slot.description} : {}\n if (slot.type === 'workflow.state.query') {\n return {\n _key,\n _type: 'workflow.state.query',\n id: slot.id,\n ...titleProp,\n ...descriptionProp,\n value,\n resolvedAt: now,\n }\n }\n return {\n _key,\n _type: slot.type,\n id: slot.id,\n ...titleProp,\n ...descriptionProp,\n value,\n } as ResolvedStateSlot\n}\n\nasync function resolveOneSlot(\n slot: StateSlot,\n initialState: InitialStateValue[],\n ctx: ResolveStateContext,\n randomKey: () => string,\n): Promise<ResolvedStateSlot> {\n const defaultValue = defaultSlotValue(slot.type)\n const value = await resolveSlotValue(slot, initialState, ctx, defaultValue)\n\n // Validate the resolved value against the slot's declared shape.\n // The `value.query` slot type is permissive (escape hatch). Default\n // values (null / []) are always shape-valid; init/literal/stateRead/\n // query may have produced something else — catch shape mismatches\n // here before they leak into the persisted snapshot.\n validateSlotValue({slotType: slot.type, slotId: slot.id, value})\n\n return buildResolvedSlot(slot, value, randomKey(), ctx.now)\n}\n\n/** Project resolved slots into the `$state` shape (slotId → slot envelope). */\nfunction stateMapFromResolved(slots: ResolvedStateSlot[]): Record<string, ResolvedStateSlot> {\n const out: Record<string, ResolvedStateSlot> = {}\n for (const s of slots) out[s.id] = s\n return out\n}\n\n/**\n * Validate caller-supplied `initialState` values for shape correctness\n * BEFORE they hit the persisted instance. Init-sourced doc.ref /\n * doc.refs slots reject bare-string `id`s — the engine stores GDR\n * URIs everywhere and a bare id silently mismatches snapshots later.\n * Throws a clear error pointing at the slot id + bad value.\n *\n * Query-sourced values are NOT validated here; the lake returns\n * various shapes and {@link normalizeQueryResult} is the only path that\n * gets to canonicalise them.\n */\nfunction assertInitValueShape(slot: StateSlot, value: unknown): void {\n if (slot.type === 'workflow.state.doc.ref') {\n assertGdrShape(value, `state slot \"${slot.id}\" (workflow.state.doc.ref)`)\n return\n }\n if (slot.type === 'workflow.state.release.ref') {\n assertGdrShape(value, `state slot \"${slot.id}\" (workflow.state.release.ref)`)\n const v = value as {releaseName?: unknown}\n if (typeof v.releaseName !== 'string' || v.releaseName.length === 0) {\n throw new Error(\n `Invalid init value for state slot \"${slot.id}\" (workflow.state.release.ref): ` +\n `\\`releaseName\\` must be a non-empty string. Got ${JSON.stringify(v.releaseName)}.`,\n )\n }\n return\n }\n if (slot.type === 'workflow.state.doc.refs') {\n if (!Array.isArray(value)) {\n throw new Error(\n `Invalid init value for state slot \"${slot.id}\" (workflow.state.doc.refs): expected an array of GDRs, got ${typeof value}.`,\n )\n }\n for (const [i, item] of value.entries()) {\n assertGdrShape(item, `state slot \"${slot.id}\" (workflow.state.doc.refs) item [${i}]`)\n }\n }\n}\n\nfunction assertGdrShape(value: unknown, context: string): void {\n if (typeof value !== 'object' || value === null) {\n throw new Error(\n `Invalid GDR for ${context}: expected { id: \"<scheme>:...\", type: \"<schema>\" }, got ${typeof value}.`,\n )\n }\n const v = value as {id?: unknown; type?: unknown}\n if (typeof v.id !== 'string' || !isGdrUri(v.id)) {\n throw new Error(\n `Invalid GDR for ${context}: \\`id\\` must be a GDR URI (\"<scheme>:<...id-parts>\" with scheme dataset|canvas|media-library|dashboard). ` +\n `Got ${JSON.stringify(v.id)}. Construct via \\`gdrFromResource\\` / \\`refDataset\\` / \\`refCanvas\\` etc. — bare document ids are not accepted.`,\n )\n }\n if (typeof v.type !== 'string' || v.type.length === 0) {\n throw new Error(\n `Invalid GDR for ${context}: \\`type\\` (schema name) must be a non-empty string. Got ${JSON.stringify(v.type)}.`,\n )\n }\n}\n\n/**\n * Convert a raw GROQ result into the slot's expected value shape.\n *\n * For `doc.ref` / `doc.refs` slots, the engine's internal contract is\n * a GDR `{id, type}` object. But a natural query like\n * `*[_id == $subject][0].primaryTeam` returns the Sanity reference\n * shape `{_ref, _type: \"reference\"}` — bare `_ref`, generic `_type`.\n * Convert it: GDR id = `gdrFromResource(workflowResource, _ref)`,\n * GDR type = \"document\" (the target doc's real schema type isn't\n * carried by the ref envelope; consumers shouldn't depend on it for\n * the slot value's `type` field).\n *\n * Already-GDR-shaped values (with `id` + `type`) pass through. Bare\n * strings are treated as doc ids and wrapped. Arrays are walked for\n * the refs case. Other slot kinds pass through unchanged.\n */\nfunction normalizeQueryResult(\n slotType: StateSlot['type'],\n raw: unknown,\n workflowResource: WorkflowResource | undefined,\n): unknown {\n if (raw === null || raw === undefined) return raw\n if (slotType === 'workflow.state.doc.ref') {\n return coerceToGdr(raw, workflowResource)\n }\n if (slotType === 'workflow.state.doc.refs') {\n if (!Array.isArray(raw)) return []\n return raw.map((item) => coerceToGdr(item, workflowResource)).filter((v) => v !== null)\n }\n return raw\n}\n\ntype Gdr = {id: import('./core/refs.ts').GdrUri; type: string}\n\n/** Resolve a doc id (bare or already-URI) to a GDR URI via the resource. */\nfunction toGdrUri(\n docId: string,\n workflowResource: WorkflowResource,\n): import('./core/refs.ts').GdrUri {\n return isGdrUri(docId) ? docId : gdrFromResource(workflowResource, docId)\n}\n\n/**\n * Coerce an already-GDR-shaped `{id, type}` value. The id must be a\n * known-scheme URI to pass through; otherwise it's a bare id from a\n * non-canonical source and we re-derive it via the resource. Returns\n * null when the shape doesn't match so callers fall through.\n */\nfunction coerceGdrShape(raw: object, workflowResource: WorkflowResource | undefined): Gdr | null {\n if (!('id' in raw) || !('type' in raw)) return null\n const r = raw as {id: unknown; type: unknown}\n if (typeof r.id !== 'string' || typeof r.type !== 'string') return null\n if (isGdrUri(r.id)) return {id: r.id, type: r.type}\n if (workflowResource) return {id: gdrFromResource(workflowResource, r.id), type: r.type}\n return null\n}\n\n/**\n * Coerce a Sanity reference envelope `{_ref, _type: \"reference\"}` to a\n * GDR. Without `workflowResource` there's no way to construct the URI;\n * returns null and lets the snapshot hydrator skip the slot.\n */\nfunction coerceRefEnvelope(\n raw: object,\n workflowResource: WorkflowResource | undefined,\n): Gdr | null {\n if (!('_ref' in raw)) return null\n const r = raw as {_ref: unknown}\n if (typeof r._ref !== 'string' || !workflowResource) return null\n return {id: toGdrUri(r._ref, workflowResource), type: 'document'}\n}\n\nfunction coerceToGdr(raw: unknown, workflowResource: WorkflowResource | undefined): Gdr | null {\n if (raw === null || raw === undefined) return null\n if (typeof raw === 'object') {\n return coerceGdrShape(raw, workflowResource) ?? coerceRefEnvelope(raw, workflowResource)\n }\n // Bare string — assume doc id in the workflow resource.\n if (typeof raw === 'string' && workflowResource) {\n return {id: toGdrUri(raw, workflowResource), type: 'document'}\n }\n return null\n}\n","import {type Clock, wallClock} from '../clock.ts'\nimport {evaluateFilter} from '../core/eval.ts'\nimport {buildParams} from '../core/params.ts'\nimport {extractDocumentId, type ParsedGdr} from '../core/refs.ts'\nimport type {HydratedSnapshot, LoadedDoc} from '../core/snapshot.ts'\nimport type {Filter, Stage, Task, WorkflowDefinition} from '../define/schema.ts'\nimport {randomKey} from '../keys.ts'\nimport {hydrateSnapshot} from '../snapshot.ts'\nimport {resolveDeclaredState} from '../state-resolution.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {StageId} from '../types/ids.ts'\nimport type {WorkflowInstance} from '../types/instance.ts'\nimport type {InitialStateValue, ResolvedStateSlot} from '../types/state-slots.ts'\n\n/**\n * Convert a GDR URI back to a bare document id. The engine's\n * cross-resource reference fields (`ancestors[].id`,\n * `spawnedInstances[].id`) carry full GDR URIs; the persistent `_id`\n * on disk is bare. Use this when fetching a referenced doc from Sanity.\n */\nexport function gdrToBareId(uri: string): string {\n return uri.includes(':') ? extractDocumentId(uri) : uri\n}\n\n// Internal — context load\n\nexport interface EngineContext {\n /** Engine's own client — bound to the workflow resource. */\n client: WorkflowClient\n /**\n * The single clock reading for this operation, taken once when the\n * context is built. EVERY \"now\" the engine stamps in this context —\n * `$now` in filters, the `now` op-source, all history `at`,\n * `completedAt`, `enteredAt`, `lastChangedAt` — reads {@link EngineContext.now},\n * so the whole operation shares one instant rather than drifting across\n * repeated wall-clock reads.\n */\n now: string\n /**\n * The {@link Clock} this context was built from, carried so nested\n * operations the context spawns (child priming + cascade inside\n * `persist`) read the SAME clock. Stamps use {@link EngineContext.now},\n * not this — call it only to seed a fresh context. Defaults to\n * {@link wallClock}.\n */\n clock: Clock\n /**\n * Route a cross-resource read by parsed GDR. Returns the engine's\n * own client when the resolver doesn't have an entry. The cascade\n * uses this for subject + ancestor loads.\n */\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient\n instance: WorkflowInstance\n definition: WorkflowDefinition\n /**\n * GDR-keyed snapshot of docs hydrated at cascade entry — instance,\n * subject (if cross-resource and reachable), ancestors. Always\n * present: `loadContext` builds it via `hydrateSnapshot`. Filters\n * evaluate against this snapshot (pure, no lake fallback). The shell\n * is responsible for completeness — anything not hydrated is invisible\n * to the filter.\n */\n snapshot: HydratedSnapshot\n}\n\nexport async function loadContext(\n client: WorkflowClient,\n instanceId: string,\n options?: {\n clientForGdr?: (parsed: ParsedGdr) => WorkflowClient\n clock?: Clock\n /** Content overlay — held doc values the cascade reads instead of\n * fetching (see {@link hydrateSnapshot}). Absent ids still load, so\n * a partial overlay degrades safely to a refetch. */\n overlay?: ReadonlyMap<string, LoadedDoc>\n },\n): Promise<EngineContext> {\n const instance = await client.getDocument<WorkflowInstance>(instanceId)\n if (!instance) {\n throw new Error(`Workflow instance ${instanceId} not found`)\n }\n const definition = JSON.parse(instance.definitionSnapshot) as WorkflowDefinition\n const clientForGdr = options?.clientForGdr ?? (() => client)\n const clock = options?.clock ?? wallClock\n const snapshot = await hydrateSnapshot({\n client,\n clientForGdr,\n instance,\n ...(options?.overlay !== undefined ? {overlay: options.overlay} : {}),\n })\n return {client, clientForGdr, clock, now: clock(), instance, definition, snapshot}\n}\n\n/** Evaluate a filter against the context's definition + hydrated\n * snapshot, with the instance's reserved params bound. An undefined\n * filter is vacuously true (see {@link evaluateFilter}). */\nexport function ctxEvaluateFilter(\n ctx: EngineContext,\n filter: Filter | undefined,\n): Promise<boolean> {\n return evaluateFilter({\n filter,\n definition: ctx.definition,\n snapshot: ctx.snapshot,\n params: buildParams(ctx.instance, ctx.now),\n })\n}\n\n/** Assemble an {@link EngineContext} for an already-loaded instance,\n * hydrating its snapshot. Used by the post-prime + propagation paths\n * that re-read the instance mid-cascade. */\nexport async function buildEngineContext(args: {\n client: WorkflowClient\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient\n instance: WorkflowInstance\n definition: WorkflowDefinition\n clock?: Clock\n}): Promise<EngineContext> {\n const {client, clientForGdr, instance, definition} = args\n const clock = args.clock ?? wallClock\n return {\n client,\n clientForGdr,\n clock,\n now: clock(),\n instance,\n definition,\n snapshot: await hydrateSnapshot({client, clientForGdr, instance}),\n }\n}\n\nexport function findStage(definition: WorkflowDefinition, stageId: StageId): Stage {\n const stage = definition.stages.find((s) => s.id === stageId)\n if (stage === undefined) {\n throw new Error(`Stage \"${stageId}\" not found in definition ${definition.workflowId}`)\n }\n return stage\n}\n\n/**\n * Build the per-stage resolved state[] from the stage definition + an\n * optional `initialState` (e.g. supplied to `setStage`). Bound to the\n * instance's subject and to `$stage = stage.id`.\n */\nexport async function resolveStageStateSlots(args: {\n client: WorkflowClient\n instance: WorkflowInstance\n stage: Stage\n now: string\n initialState?: InitialStateValue[]\n}): Promise<ResolvedStateSlot[]> {\n const {client, instance, stage, now, initialState} = args\n return resolveDeclaredState({\n slotDefs: stage.state,\n initialState: initialState ?? [],\n ctx: {\n client,\n now,\n selfId: instance._id,\n tags: instance.tags ?? [],\n stageId: stage.id,\n workflowResource: instance.workflowResource,\n // Allow stage-scope slots' `source: { kind: \"stateRead\", scope:\n // \"workflow\", ... }` to see the already-resolved workflow-scope\n // state.\n workflowState: instance.state ?? [],\n ...(instance.perspective !== undefined ? {perspective: instance.perspective} : {}),\n },\n randomKey,\n })\n}\n\n/** Same shape as `resolveStageStateSlots` but scoped to a task. */\nexport async function resolveTaskStateSlots(args: {\n client: WorkflowClient\n instance: WorkflowInstance\n stage: Stage\n task: Task\n now: string\n}): Promise<ResolvedStateSlot[]> {\n const {client, instance, stage, task, now} = args\n return resolveDeclaredState({\n slotDefs: task.state,\n initialState: [],\n ctx: {\n client,\n now,\n selfId: instance._id,\n tags: instance.tags ?? [],\n stageId: stage.id,\n workflowResource: instance.workflowResource,\n taskId: task.id,\n workflowState: instance.state ?? [],\n ...(instance.perspective !== undefined ? {perspective: instance.perspective} : {}),\n },\n randomKey,\n })\n}\n","import type {GlobalDocumentReference, WorkflowResource} from './core/refs.ts'\nimport type {WorkflowDefinition} from './define/schema.ts'\nimport {randomKey} from './keys.ts'\nimport type {Actor} from './types/actor.ts'\nimport type {WorkflowPerspective} from './types/client.ts'\nimport type {EffectsContextEntry} from './types/effects.ts'\nimport {WORKFLOW_INSTANCE_TYPE, type WorkflowInstance} from './types/instance.ts'\nimport type {ResolvedStateSlot} from './types/state-slots.ts'\n\n/** Wrap a scalar or GDR value in its typed {@link EffectsContextEntry}\n * envelope, minting a fresh `_key`. */\nexport function effectsContextEntry(\n id: string,\n value: string | number | boolean | GlobalDocumentReference,\n): EffectsContextEntry {\n const _key = randomKey()\n if (typeof value === 'string') return {_key, _type: 'effectsContext.string', id, value}\n if (typeof value === 'number') return {_key, _type: 'effectsContext.number', id, value}\n if (typeof value === 'boolean') return {_key, _type: 'effectsContext.boolean', id, value}\n return {_key, _type: 'effectsContext.ref', id, value}\n}\n\n/**\n * Build a fresh {@link WorkflowInstance} document for `create`. Shared by\n * `startInstance` (root instances) and the spawn path (child instances):\n * both pin the definition snapshot, seed state + effectsContext, enter\n * the initial stage with a single `stageEntered` history entry, and stamp\n * `_createdAt`/`startedAt`/`lastChangedAt` to the same `now`.\n */\nexport function buildInstanceBase(args: {\n id: string\n now: string\n tags: string[]\n workflowResource: WorkflowResource\n workflowId: string\n pinnedVersion: number\n definition: WorkflowDefinition\n state: ResolvedStateSlot[]\n effectsContext: EffectsContextEntry[]\n ancestors: GlobalDocumentReference[]\n perspective: WorkflowPerspective | undefined\n initialStageId: string\n actor: Actor | undefined\n}): WorkflowInstance {\n const {id, now, actor, perspective} = args\n return {\n _id: id,\n _type: WORKFLOW_INSTANCE_TYPE,\n _rev: '',\n _createdAt: now,\n _updatedAt: now,\n tags: args.tags,\n workflowResource: args.workflowResource,\n workflowId: args.workflowId,\n pinnedVersion: args.pinnedVersion,\n definitionSnapshot: JSON.stringify(args.definition),\n state: args.state,\n effectsContext: args.effectsContext,\n ancestors: args.ancestors,\n ...(perspective !== undefined ? {perspective} : {}),\n currentStageId: args.initialStageId,\n stages: [],\n pendingEffects: [],\n effectHistory: [],\n history: [\n {\n _key: randomKey(),\n _type: 'workflow.history.stageEntered',\n at: now,\n stageId: args.initialStageId,\n ...(actor !== undefined ? {actor} : {}),\n },\n ],\n startedAt: now,\n lastChangedAt: now,\n }\n}\n","import type {SanityDocument} from '@sanity/types'\n\nimport type {Stage, Task} from '../define/schema.ts'\nimport {randomKey} from '../keys.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {EffectHistoryEntry, EffectsContextEntry, PendingEffect} from '../types/effects.ts'\nimport type {TaskStatus} from '../types/enums.ts'\nimport type {HistoryEntry} from '../types/history.ts'\nimport type {StageId, TaskId} from '../types/ids.ts'\nimport {findOpenStageEntry, type StageEntry, type TaskEntry} from '../types/instance-state.ts'\nimport type {WorkflowInstance} from '../types/instance.ts'\nimport type {ResolvedStateSlot} from '../types/state-slots.ts'\nimport {cascadeAutoTransitions, primeInitialStage, propagateToAncestors} from './cascade.ts'\nimport {type EngineContext, findStage} from './context.ts'\n\n// Internal — commits\n\nexport interface MutableInstance {\n currentStageId: StageId\n state: ResolvedStateSlot[]\n stages: StageEntry[]\n pendingEffects: PendingEffect[]\n effectHistory: EffectHistoryEntry[]\n effectsContext: EffectsContextEntry[]\n history: HistoryEntry[]\n lastChangedAt: string\n completedAt?: string\n /**\n * Net-new child workflow instances queued by `spawnChildren` during\n * this mutation. Drained at `persist` time into a single same-resource\n * transaction so the parent's `spawnedInstances` patch and the child\n * `create`s commit atomically.\n */\n pendingCreates: WorkflowInstance[]\n}\n\nexport function startMutation(instance: WorkflowInstance): MutableInstance {\n return {\n currentStageId: instance.currentStageId,\n // Deep-ish copy. Per-scope state slot arrays need their own copies\n // so ops can mutate without leaking into the source.\n state: (instance.state ?? []).map((s) => ({...s})),\n stages: instance.stages.map((s) => ({\n ...s,\n state: (s.state ?? []).map((slot) => ({...slot})),\n tasks: s.tasks.map((t) => ({\n ...t,\n ...(t.state !== undefined ? {state: t.state.map((slot) => ({...slot}))} : {}),\n })),\n })),\n pendingEffects: [...instance.pendingEffects],\n effectHistory: [...instance.effectHistory],\n effectsContext: [...instance.effectsContext],\n history: [...instance.history],\n lastChangedAt: instance.lastChangedAt,\n ...(instance.completedAt !== undefined ? {completedAt: instance.completedAt} : {}),\n pendingCreates: [],\n }\n}\n\n/** Build a `taskStatusChanged` history entry, stamping a fresh `_key`.\n * `at` is the operation's clock reading (the caller's `ctx.now`). */\nexport function taskStatusChangedEntry(args: {\n stageId: StageId\n taskId: TaskId\n from: TaskStatus\n to: TaskStatus\n at: string\n actor?: Actor\n}): HistoryEntry {\n return {\n _key: randomKey(),\n _type: 'workflow.history.taskStatusChanged',\n at: args.at,\n stageId: args.stageId,\n taskId: args.taskId,\n from: args.from,\n to: args.to,\n ...(args.actor !== undefined ? {actor: args.actor} : {}),\n }\n}\n\n/**\n * Build the three-entry history sequence for a stage move:\n * `stageExited` → `transitionFired` → `stageEntered`. All three share\n * `at`, the (optional) `transitionId`, `actor`, and the `via`/`reason`\n * discriminators that distinguish filtered transitions from admin\n * overrides.\n */\nexport function stageTransitionHistory(args: {\n fromStageId: StageId\n toStageId: StageId\n at: string\n transitionId?: string\n actor?: Actor\n via?: 'transition' | 'setStage'\n reason?: string\n}): HistoryEntry[] {\n const {fromStageId, toStageId, at, transitionId, actor, via, reason} = args\n const shared = {\n at,\n ...(transitionId !== undefined ? {transitionId} : {}),\n ...(actor !== undefined ? {actor} : {}),\n ...(via !== undefined ? {via} : {}),\n ...(reason !== undefined ? {reason} : {}),\n }\n return [\n {\n _key: randomKey(),\n _type: 'workflow.history.stageExited',\n stageId: fromStageId,\n toStageId,\n ...shared,\n },\n {\n _key: randomKey(),\n _type: 'workflow.history.transitionFired',\n fromStageId,\n toStageId,\n ...shared,\n },\n {\n _key: randomKey(),\n _type: 'workflow.history.stageEntered',\n stageId: toStageId,\n fromStageId,\n ...shared,\n },\n ]\n}\n\n/**\n * The persisted state fields of an instance, sans `lastChangedAt`. Single\n * source for both `persist` (what a commit writes) and guard-failure rollback\n * (what restoring the pre-commit instance must write back), so the two can't\n * drift. `completedAt` is included only when set — callers rolling back a move\n * that newly completed an instance must `unset` it separately.\n */\nexport function instanceStateFields(\n src: Pick<\n MutableInstance,\n | 'currentStageId'\n | 'state'\n | 'stages'\n | 'pendingEffects'\n | 'effectHistory'\n | 'effectsContext'\n | 'history'\n | 'completedAt'\n >,\n): Record<string, unknown> {\n const fields: Record<string, unknown> = {\n currentStageId: src.currentStageId,\n state: src.state,\n stages: src.stages,\n pendingEffects: src.pendingEffects,\n effectHistory: src.effectHistory,\n effectsContext: src.effectsContext,\n history: src.history,\n }\n if (src.completedAt !== undefined) fields.completedAt = src.completedAt\n return fields\n}\n\n/**\n * A read-only `WorkflowInstance` view of an in-flight mutation: the persisted\n * identity/provenance fields from `base`, with the mutated `currentStageId` /\n * `state` / `stages` layered on. Guard (re)deployment resolves Sources against\n * this so it sees post-move state, not the stale loaded instance.\n */\nexport function materializeInstance(\n base: WorkflowInstance,\n mutation: MutableInstance,\n): WorkflowInstance {\n return {\n ...base,\n currentStageId: mutation.currentStageId,\n state: mutation.state,\n stages: mutation.stages,\n }\n}\n\nexport async function persist(\n ctx: EngineContext,\n mutation: MutableInstance,\n): Promise<SanityDocument> {\n // Patch (not createOrReplace): patches require the doc to exist, so\n // a deleted instance mid-cascade fails fast instead of getting\n // silently resurrected. `ifRevisionId` adds optimistic concurrency —\n // if another writer raced us, the patch errors instead of clobbering.\n const set: Record<string, unknown> = {\n ...instanceStateFields(mutation),\n lastChangedAt: ctx.now,\n }\n\n const pendingCreates = mutation.pendingCreates\n if (pendingCreates.length === 0) {\n return ctx.client.patch(ctx.instance._id).set(set).ifRevisionId(ctx.instance._rev).commit()\n }\n\n // Multi-doc same-resource write: bundle the N child creates with the\n // parent's patch in one Sanity transaction. Children inherit the\n // parent's `workflowResource` so they are always provably same-resource.\n const tx = ctx.client.transaction()\n for (const body of pendingCreates) tx.create(body)\n tx.patch(ctx.client.patch(ctx.instance._id).set(set).ifRevisionId(ctx.instance._rev))\n await tx.commit()\n mutation.pendingCreates = []\n\n // Children are now durably in the lake with the parent's\n // `spawnedInstances` recorded atomically. Prime each child's initial\n // stage, cascade to whatever stage it lands on (possibly terminal),\n // then propagate up — a child that reached terminal needs to\n // re-evaluate its parent's spawn-completion gate. Pre-refactor,\n // `spawnChildren` ran per-child create+prime+cascade synchronously\n // and `activateTask`'s in-memory `checkSpawnCompletion` flipped the\n // parent's task done in the same mutation; deferring creates into\n // the transaction means we restore that effect via explicit\n // propagation here.\n const actorForPriming: Actor | undefined = undefined\n for (const body of pendingCreates) {\n await primeInitialStage(ctx.client, body._id, actorForPriming, ctx.clientForGdr, ctx.clock)\n await cascadeAutoTransitions(ctx.client, body._id, actorForPriming, ctx.clientForGdr, ctx.clock)\n await propagateToAncestors(ctx.client, body._id, actorForPriming, ctx.clientForGdr, ctx.clock)\n }\n\n // Reload the parent so callers see the post-commit `_rev`. Persist's\n // historical return shape is the patched parent doc; preserve that.\n const reloaded = await ctx.client.getDocument<SanityDocument>(ctx.instance._id)\n if (!reloaded) {\n throw new Error(`Instance ${ctx.instance._id} disappeared after transaction commit`)\n }\n return reloaded\n}\n\n// Helpers for working with the per-stage task entries. The open\n// StageEntry lookup is {@link findOpenStageEntry} (in types/instance-state).\n\nfunction currentStageEntry(mutation: MutableInstance): StageEntry {\n const entry = findOpenStageEntry(mutation)\n if (entry === undefined) {\n throw new Error(\n `Mutation invariant broken: no current (un-exited) StageEntry for currentStageId \"${mutation.currentStageId}\"`,\n )\n }\n return entry\n}\n\nexport function currentTasks(mutation: MutableInstance): TaskEntry[] {\n return currentStageEntry(mutation).tasks\n}\n\n/** Find a task definition on the instance's current stage, throwing a\n * consistent error when it isn't declared there. */\nexport function findTaskInCurrentStage(\n ctx: EngineContext,\n taskId: TaskId,\n): {stage: Stage; task: Task} {\n const stage = findStage(ctx.definition, ctx.instance.currentStageId)\n const task = (stage.tasks ?? []).find((t) => t.id === taskId)\n if (task === undefined) {\n throw new Error(\n `Task \"${taskId}\" not found in current stage \"${stage.id}\" of ${ctx.definition.workflowId}`,\n )\n }\n return {stage, task}\n}\n\n/** The mutation copy's entry for `taskId`. Throws if it vanished — the\n * live instance and its mutation copy must agree on task identity. */\nexport function requireMutationTaskEntry(mutation: MutableInstance, taskId: TaskId): TaskEntry {\n const mutEntry = currentTasks(mutation).find((t) => t.id === taskId)\n if (mutEntry === undefined) {\n throw new Error(`Task \"${taskId}\" disappeared from mutation copy — invariant broken`)\n }\n return mutEntry\n}\n\nfunction findCurrentStageEntry(instance: WorkflowInstance): StageEntry | undefined {\n return findOpenStageEntry(instance)\n}\n\nexport function findCurrentTasks(instance: WorkflowInstance): TaskEntry[] {\n return findCurrentStageEntry(instance)?.tasks ?? []\n}\n","import {resolveBindings} from '../core/bindings.ts'\nimport type {GlobalDocumentReference} from '../core/refs.ts'\nimport type {Effect} from '../define/schema.ts'\nimport {effectsContextEntry} from '../instance.ts'\nimport {randomKey} from '../keys.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {EffectHistoryEntry, EffectOrigin, PendingEffect} from '../types/effects.ts'\nimport type {HistoryEntry} from '../types/history.ts'\nimport type {WorkflowInstance} from '../types/instance.ts'\nimport {type EngineContext, loadContext} from './context.ts'\nimport {type MutableInstance, persist, startMutation} from './mutation.ts'\nimport type {CompleteEffectResult, EngineCallOptions} from './results.ts'\n\n/**\n * Mark a queued effect as completed. Drains it from `pendingEffects`,\n * appends an `EffectHistoryEntry`, and (if `outputs` are supplied)\n * upserts those into `effectsContext` by key — making them available to\n * downstream effect bindings.\n *\n * This is the only path that mutates `effectsContext` after start.\n */\nexport async function completeEffect(args: {\n client: WorkflowClient\n instanceId: string\n effectKey: string\n status: 'done' | 'failed'\n outputs?: Record<string, string | number | boolean | GlobalDocumentReference>\n detail?: string\n error?: {message: string; stack?: string}\n durationMs?: number\n options?: EngineCallOptions\n}): Promise<CompleteEffectResult> {\n const {client, instanceId, effectKey, status, outputs, detail, error, durationMs, options} = args\n const ctx = await loadContext(client, instanceId, {\n ...(options?.clock ? {clock: options.clock} : {}),\n })\n return commitCompleteEffect(\n ctx,\n effectKey,\n status,\n outputs,\n detail,\n error,\n durationMs,\n options?.actor,\n )\n}\n\n/** Build the {@link EffectHistoryEntry} recorded when a queued effect\n * completes, carrying the pending entry's identity forward and stamping\n * the run outcome. A supplied `actor` overrides the pending entry's. */\nfunction buildEffectHistoryEntry(\n pending: PendingEffect,\n outcome: {\n status: 'done' | 'failed'\n ranAt: string\n actor: Actor | undefined\n detail: string | undefined\n error: {message: string; stack?: string} | undefined\n durationMs: number | undefined\n outputs: Record<string, string | number | boolean | GlobalDocumentReference> | undefined\n },\n): EffectHistoryEntry {\n const {status, ranAt, actor, detail, error, durationMs, outputs} = outcome\n const resolvedActor = actor ?? pending.actor\n return {\n _key: pending._key,\n effectId: pending.effectId,\n ...(pending.title !== undefined ? {title: pending.title} : {}),\n ...(pending.description !== undefined ? {description: pending.description} : {}),\n params: pending.params,\n origin: pending.origin,\n ...(resolvedActor !== undefined ? {actor: resolvedActor} : {}),\n ranAt,\n ...(durationMs !== undefined ? {durationMs} : {}),\n status,\n ...(detail !== undefined ? {detail} : {}),\n ...(error !== undefined ? {error} : {}),\n ...(outputs !== undefined ? {outputs} : {}),\n }\n}\n\n/** Upsert completed-effect outputs into the mutation's `effectsContext`,\n * replacing any existing entry with the same id. */\nfunction upsertEffectsContext(\n mutation: MutableInstance,\n outputs: Record<string, string | number | boolean | GlobalDocumentReference>,\n): void {\n for (const [id, value] of Object.entries(outputs)) {\n const existingIndex = mutation.effectsContext.findIndex((e) => e.id === id)\n const entry = effectsContextEntry(id, value)\n if (existingIndex >= 0) mutation.effectsContext[existingIndex] = entry\n else mutation.effectsContext.push(entry)\n }\n}\n\nasync function commitCompleteEffect(\n ctx: EngineContext,\n effectKey: string,\n status: 'done' | 'failed',\n outputs: Record<string, string | number | boolean | GlobalDocumentReference> | undefined,\n detail: string | undefined,\n error: {message: string; stack?: string} | undefined,\n durationMs: number | undefined,\n actor: Actor | undefined,\n): Promise<CompleteEffectResult> {\n const pending = ctx.instance.pendingEffects.find((e) => e._key === effectKey)\n if (pending === undefined) {\n throw new Error(`Pending effect \"${effectKey}\" not found on instance ${ctx.instance._id}`)\n }\n\n const mutation = startMutation(ctx.instance)\n mutation.pendingEffects = mutation.pendingEffects.filter((e) => e._key !== effectKey)\n\n const ranAt = ctx.now\n mutation.effectHistory.push(\n buildEffectHistoryEntry(pending, {status, ranAt, actor, detail, error, durationMs, outputs}),\n )\n\n if (status === 'done' && outputs !== undefined) {\n upsertEffectsContext(mutation, outputs)\n }\n\n mutation.history.push({\n _key: randomKey(),\n _type: 'workflow.history.effectCompleted',\n at: ranAt,\n effectKey,\n effectId: pending.effectId,\n status,\n ...(outputs !== undefined ? {outputs} : {}),\n ...(detail !== undefined ? {detail} : {}),\n ...(actor !== undefined ? {actor} : {}),\n })\n\n await persist(ctx, mutation)\n return {effectKey, status}\n}\n\n/** Materialise one queued effect: its {@link PendingEffect} envelope and\n * the matching `effectQueued` history entry, sharing a freshly-minted\n * `_key`. Caller pushes each into the right array. */\nexport function buildQueuedEffect(\n effect: Effect,\n origin: EffectOrigin,\n params: Record<string, unknown>,\n actor: Actor | undefined,\n now: string,\n): {pending: PendingEffect; history: HistoryEntry} {\n const key = randomKey()\n const pending: PendingEffect = {\n _key: key,\n _type: 'workflow.pendingEffect',\n effectId: effect.id,\n ...(effect.title !== undefined ? {title: effect.title} : {}),\n ...(effect.description !== undefined ? {description: effect.description} : {}),\n ...(effect.bindings !== undefined ? {bindings: effect.bindings} : {}),\n params,\n origin,\n ...(actor !== undefined ? {actor} : {}),\n queuedAt: now,\n }\n const history: HistoryEntry = {\n _key: randomKey(),\n _type: 'workflow.history.effectQueued',\n at: now,\n effectKey: key,\n effectId: effect.id,\n origin,\n }\n return {pending, history}\n}\n\nexport async function queueEffects(\n ctx: EngineContext,\n mutation: MutableInstance,\n effects: Effect[] | undefined,\n origin: EffectOrigin,\n actor: Actor | undefined,\n callerParams?: Record<string, unknown>,\n): Promise<void> {\n if (!effects) return\n const now = ctx.now\n // Effect bindings see the FRESHEST state — read from the in-progress\n // mutation so an op that ran earlier in the same action commit is\n // visible to a bound effect on the same action.\n const liveInstance: WorkflowInstance = {\n ...ctx.instance,\n state: mutation.state,\n stages: mutation.stages,\n effectsContext: mutation.effectsContext,\n }\n for (const effect of effects) {\n const params = await resolveBindings({\n bindings: effect.bindings,\n staticInput: effect.input,\n instance: liveInstance,\n now,\n ...(callerParams !== undefined ? {params: callerParams} : {}),\n ...(actor !== undefined ? {actor} : {}),\n })\n const {pending, history} = buildQueuedEffect(effect, origin, params, actor, now)\n mutation.pendingEffects.push(pending)\n mutation.history.push(history)\n }\n}\n","import type {Clock} from '../clock.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {StateScope, TaskStatus} from '../types/enums.ts'\nimport type {StageId, TaskId} from '../types/ids.ts'\n\n// Public API\n\nexport interface EngineCallOptions {\n actor?: Actor\n /** Injected {@link Clock} for deterministic time; defaults to wall-clock. */\n clock?: Clock\n}\n\nexport interface TransitionResult {\n fired: boolean\n fromStageId?: StageId\n toStageId?: StageId\n transitionId?: string\n}\n\nexport interface InvokeResult {\n invoked: boolean\n taskId: TaskId\n}\n\nexport interface OpAppliedSummary {\n opType: string\n target?: {scope: StateScope; slotId: string}\n resolved?: Record<string, unknown>\n}\n\nexport interface ActionResult {\n fired: boolean\n taskId: TaskId\n action: string\n newStatus?: TaskStatus\n /** Deterministic engine primitives that ran inline during the commit. */\n ranOps?: OpAppliedSummary[]\n}\n\n/**\n * Thrown when caller-supplied params don't satisfy the action's\n * declared `params[]` — missing required fields or wrong primitive\n * type. The action does not commit; the engine has not mutated state.\n */\nexport class ActionParamsInvalidError extends Error {\n readonly action: string\n readonly taskId: TaskId\n readonly issues: {paramId: string; reason: string}[]\n constructor(args: {action: string; taskId: TaskId; issues: {paramId: string; reason: string}[]}) {\n const lines = args.issues.map((i) => ` - ${i.paramId}: ${i.reason}`).join('\\n')\n super(`Action \"${args.action}\" on task \"${args.taskId}\" rejected: invalid params\\n${lines}`)\n this.name = 'ActionParamsInvalidError'\n this.action = args.action\n this.taskId = args.taskId\n this.issues = args.issues\n }\n}\n\n/**\n * Thrown when a guard deploy fails *after* its state move committed and the\n * engine could not restore the instance to its pre-move state — either the\n * rollback write itself failed, or the move created sibling docs (spawn) that a\n * parent-only rollback cannot undo. The workflow's persisted state and its\n * deployed guards are now divergent and need manual reconciliation; the engine\n * screams rather than leaving the inconsistency silent.\n */\nexport class WorkflowStateDivergedError extends Error {\n readonly instanceId: string\n /** The guard-deploy failure that triggered the (attempted) rollback. */\n readonly guardError: unknown\n /** The rollback failure, when rollback was attempted and itself failed. */\n readonly rollbackError?: unknown\n constructor(args: {\n instanceId: string\n guardError: unknown\n rollbackError?: unknown\n reason: string\n }) {\n super(\n `Workflow \"${args.instanceId}\" state committed but its guards could not be reconciled: ${args.reason}.`,\n {cause: args.guardError},\n )\n this.name = 'WorkflowStateDivergedError'\n this.instanceId = args.instanceId\n this.guardError = args.guardError\n if (args.rollbackError !== undefined) this.rollbackError = args.rollbackError\n }\n}\n\nexport interface CompleteEffectResult {\n effectKey: string\n status: 'done' | 'failed'\n}\n\n/** Total `fireAction` commit attempts before giving up — one initial try\n * plus reloads after each lost `ifRevisionId` race. */\nexport const CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS = 3\n\n/**\n * Thrown when a `fireAction` commit loses the optimistic-locking race on\n * all {@link CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS} attempts — every reload +\n * `ifRevisionId` retry was beaten by another writer committing first.\n * Surfacing it (rather than silently overwriting) lets the caller decide\n * whether to retry later or report a write storm; nothing was committed\n * on the final attempt.\n */\nexport class ConcurrentFireActionError extends Error {\n readonly instanceId: string\n readonly taskId: TaskId\n readonly action: string\n readonly attempts: number\n constructor(args: {instanceId: string; taskId: TaskId; action: string; attempts: number}) {\n super(\n `Action \"${args.action}\" on task \"${args.taskId}\" (instance ${args.instanceId}) lost the ` +\n `optimistic-locking race ${args.attempts} attempts running — a concurrent writer kept ` +\n `committing first. Re-read and retry, or investigate a write storm on this instance.`,\n )\n this.name = 'ConcurrentFireActionError'\n this.instanceId = args.instanceId\n this.taskId = args.taskId\n this.action = args.action\n this.attempts = args.attempts\n }\n}\n\n/**\n * True when a rev-guarded write was rejected by optimistic-locking — a 409\n * from the real client or the bench's `ifRevisionId check failed`. Lets\n * callers retry on a lost race while still rethrowing real errors\n * (validation, network, missing task) rather than masking them as conflicts.\n */\nexport function isRevisionConflict(error: unknown): boolean {\n if (typeof error !== 'object' || error === null) return false\n const {statusCode, message} = error as {statusCode?: unknown; message?: unknown}\n if (statusCode === 409) return true\n return typeof message === 'string' && message.includes('ifRevisionId check failed')\n}\n\n/**\n * Thrown when auto-transitions on an instance fail to stabilise within\n * {@link CascadeLimitError.limit} passes — the signature of a runaway\n * cascade. The classic trigger is two stages whose transition guards\n * stay simultaneously satisfied (e.g. an `op.state.set` lands a value\n * that trips the very guard that fired, and nothing ever clears it), so\n * the engine flip-flops and would otherwise write revisions forever.\n *\n * The cascade aborts at the limit rather than the engine hanging; the\n * instance is left at whatever stage the last completed pass reached.\n */\nexport class CascadeLimitError extends Error {\n readonly instanceId: string\n readonly limit: number\n constructor(args: {instanceId: string; limit: number}) {\n super(\n `Cascade did not stabilise after ${args.limit} auto-transitions on ${args.instanceId} — ` +\n `likely a runaway loop (transition guards that stay mutually satisfied). ` +\n `Check that each transition's filter eventually goes false.`,\n )\n this.name = 'CascadeLimitError'\n this.instanceId = args.instanceId\n this.limit = args.limit\n }\n}\n","import type {WorkflowClient} from '../types/client.ts'\nimport {WorkflowStateDivergedError} from './results.ts'\n\nexport interface DeployOrRollbackArgs {\n client: WorkflowClient\n instanceId: string\n /** The post-commit revision the rollback patch must still match. */\n committedRev: string | undefined\n /** Pre-commit field values to write back if the deploy fails. */\n restore: Record<string, unknown>\n /** Fields the move added that a rollback must remove (e.g. a fresh `completedAt`). */\n unset?: string[]\n /**\n * False when the commit also created sibling docs (a spawn transaction) that\n * a parent-only rollback cannot undo — a deploy failure then screams instead\n * of leaving orphaned children behind a half-applied move.\n */\n reversible: boolean\n /** Deploy/reconcile the stage's guards. Runs after the state has committed. */\n deploy: () => Promise<void>\n}\n\n/**\n * Deploy guards for a just-committed state move, rolling the move back if the\n * deploy fails. Ordering is deliberate: guards deploy AFTER the state commits\n * (a guard can lock the caller out of further edits, so it must follow the\n * state it enforces). On a deploy failure the engine restores the pre-commit\n * instance and re-throws the original error — the caller sees the failure with\n * state intact. When a clean rollback is impossible (spawn) or the rollback\n * write itself fails, it throws {@link WorkflowStateDivergedError} so the\n * divergence is loud, never silent.\n */\nexport async function deployOrRollback(args: DeployOrRollbackArgs): Promise<void> {\n try {\n await args.deploy()\n } catch (guardError) {\n if (!args.reversible) {\n throw new WorkflowStateDivergedError({\n instanceId: args.instanceId,\n guardError,\n reason: 'the move created child instances a parent-only rollback cannot undo',\n })\n }\n try {\n let patch = args.client.patch(args.instanceId).set(args.restore)\n if (args.unset && args.unset.length > 0) patch = patch.unset(args.unset)\n if (args.committedRev !== undefined) patch = patch.ifRevisionId(args.committedRev)\n await patch.commit()\n } catch (rollbackError) {\n throw new WorkflowStateDivergedError({\n instanceId: args.instanceId,\n guardError,\n rollbackError,\n reason: 'rollback of the committed move failed',\n })\n }\n throw guardError\n }\n}\n","/**\n * Engine-scope tags — the multi-tenant isolation primitive.\n *\n * Every engine takes a required `tags: string[]` set at construction.\n * Tags must be Sanity-ID-compatible since they're joined into IDs with\n * `.` — ASCII lowercase + digits + dashes, no leading dash, no dots.\n *\n * The first tag in the array is the *canonical* tag, used as the ID\n * prefix when the engine writes new definitions or instances. The full\n * tag set goes onto every written doc and is the basis for read\n * filtering (tag intersection between engine and doc).\n */\n\nconst TAG_RE = /^[a-z0-9][a-z0-9-]*$/\n\nexport function validateTags(tags: string[]): void {\n if (tags.length === 0) {\n throw new Error('tags: must be a non-empty array')\n }\n for (const tag of tags) {\n if (!TAG_RE.test(tag)) {\n throw new Error(\n `tags: invalid tag \"${tag}\" — must match ${TAG_RE.source} (ASCII lowercase + digits + dashes, no leading dash, no dots)`,\n )\n }\n }\n}\n\nexport function canonicalTag(tags: string[]): string {\n return tags[0]!\n}\n\n/**\n * The engine's read-partition invariant as a GROQ predicate: a document is\n * visible when its `tags[]` intersect the caller's tag set.\n *\n * @param param - GROQ parameter holding the caller's tags. Defaults to\n * `engineTags`, matching the `workflow.query` guard so any query built with\n * it stays tag-scoped.\n */\nexport function tagScopeFilter(param = 'engineTags'): string {\n return `count(tags[@ in $${param}]) > 0`\n}\n","/**\n * Pure GROQ builder for resolving a deployed workflow definition. Composes the\n * doc-type constant and the tag-scope predicate so the engine's internal\n * lookups and the CLI share one definition of \"tag-scoped, latest-or-pinned\n * `workflow.definition`\" instead of hand-writing the query at each call site.\n */\n\nimport {WORKFLOW_DEFINITION_TYPE} from './define/schema.ts'\nimport {tagScopeFilter} from './tags.ts'\n\n/**\n * GROQ resolving a single deployed {@link WORKFLOW_DEFINITION_TYPE} visible to\n * the caller's tags. With {@link explicit} the query pins `$version`; otherwise\n * it returns the highest deployed version.\n *\n * Params: `$workflowId`, `$engineTags`, plus `$version` when {@link explicit}.\n *\n * @param explicit - whether the caller wants a specific version (`$version`)\n * rather than the latest.\n */\nexport function definitionLookupGroq(explicit: boolean): string {\n const scoped = `_type == \"${WORKFLOW_DEFINITION_TYPE}\" && workflowId == $workflowId && ${tagScopeFilter()}`\n return explicit\n ? `*[${scoped} && version == $version][0]`\n : `*[${scoped}] | order(version desc)[0]`\n}\n","/**\n * Shell-side discovery query.\n *\n * Spawn `forEach.groq` scans the lake for rows to spawn child\n * workflows over. These are NOT filters — they look at content that\n * isn't in the snapshot (typically every doc of a given type that\n * references a doc the workflow already knows about). Different\n * semantics, different primitive, different code path from\n * `evaluateFilter`.\n *\n * Keeping discovery out of the filter pipeline is what lets the core\n * stay pure. Filters eval against pre-hydrated data; discovery hits the\n * lake by design.\n */\n\nimport {paramsForLake} from './core/params.ts'\nimport {parseGdr} from './core/refs.ts'\nimport type {WorkflowClient, WorkflowPerspective} from './types/client.ts'\n\n/**\n * Run a discovery GROQ against the appropriate client.\n *\n * The query receives params with GDR IDs stripped back to bare form\n * (via `paramsForLake`) because lake refs are bare. Caller decides\n * which client to use — typically the resource client of the first\n * `doc.ref` state slot, since discovery scans look for items related\n * to docs the workflow already references.\n */\nexport async function discoverItems(args: {\n client: WorkflowClient\n groq: string\n params: Record<string, unknown>\n /**\n * Read-side perspective. When set, the engine threads the instance's\n * `perspective` field through so spawn `forEach.groq` sees a\n * release-stacked view of the lake. Unset → client default.\n */\n perspective?: WorkflowPerspective\n}): Promise<unknown> {\n const {client, groq, params, perspective} = args\n const fetchOptions = perspective !== undefined ? {perspective} : undefined\n return client.fetch(groq, paramsForLake(params), fetchOptions)\n}\n\n/**\n * Convenience: pick the right client for a discovery scan given the\n * subject's GDR URI. Bare ids (no `:`) → default client. Anything\n * parseable → routed client.\n */\nexport function clientForDiscovery(\n defaultClient: WorkflowClient,\n clientForGdr: (parsed: import('./core/refs.ts').ParsedGdr) => WorkflowClient,\n subjectGdrUri: string | undefined,\n): WorkflowClient {\n if (!subjectGdrUri || !subjectGdrUri.includes(':')) return defaultClient\n try {\n return clientForGdr(parseGdr(subjectGdrUri))\n } catch {\n return defaultClient\n }\n}\n","import type {SanityDocument} from '@sanity/types'\nimport {evaluate, parse} from 'groq-js'\n\nimport {buildParams} from '../core/params.ts'\nimport {getPath} from '../core/path.ts'\nimport {gdrFromResource, isGdrUri, selfGdr, type GlobalDocumentReference} from '../core/refs.ts'\nimport type {Source, Spawn, Task, WorkflowDefinition} from '../define/schema.ts'\nimport {definitionLookupGroq} from '../definition-query.ts'\nimport {clientForDiscovery, discoverItems} from '../discover.ts'\nimport {buildInstanceBase, effectsContextEntry} from '../instance.ts'\nimport {randomKey} from '../keys.ts'\nimport {derivePerspectiveFromState, resolveDeclaredState} from '../state-resolution.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {EffectsContextEntry} from '../types/effects.ts'\nimport type {TaskEntry} from '../types/instance-state.ts'\nimport {WORKFLOW_INSTANCE_TYPE, type WorkflowInstance} from '../types/instance.ts'\nimport type {InitialStateValue, ResolvedStateSlot} from '../types/state-slots.ts'\nimport {type EngineContext, gdrToBareId} from './context.ts'\nimport type {MutableInstance} from './mutation.ts'\n\n/**\n * Maximum depth of the spawn ancestor chain. A child's depth is\n * `ancestors.length`. With this limit a spawned chain can reach\n * `root → 1 → 2 → 3 → 4 → 5 → 6` (six levels of nesting below root);\n * a spawn that would create a seventh level is rejected.\n *\n * Backstop against runtime spawn recursion that the deploy-time cycle\n * detector cannot see — definitions whose spawn fires conditionally on\n * subject state can produce dynamic recursion without a static cycle\n * in the definition graph.\n */\nconst MAX_SPAWN_DEPTH = 6\n\n/**\n * Resolve a spawn declaration's `forEach` against the parent instance,\n * create one child workflow instance per result row, prime each child's\n * initial stage, cascade auto-transitions on each, and return the refs.\n *\n * `spawn.forEach.groq` is the discovery query (lake fetch) — runs with\n * the parent's reserved params (`$self`, `$state`, `$parent`,\n * `$ancestors`, `$stage`, `$now`) stripped to bare for the lake.\n *\n * `spawn.forEach.as.initialState` is a typed projection from each row\n * to the child's `initialState` array. Two spawn-only Sources:\n * - `{ source: \"row\", path? }` reads from the iteration row.\n * - `{ source: \"parentState\", slotId, path? }` reads from the\n * parent's resolved workflow-scope state.\n *\n * The child receives no auto-stamped state — only what the projection\n * produces. The child's workflow definition declares which slots it\n * expects; this projection feeds them.\n */\nexport async function spawnChildren(\n ctx: EngineContext,\n mutation: MutableInstance,\n task: Task,\n spawn: Spawn,\n actor: Actor | undefined,\n): Promise<GlobalDocumentReference[]> {\n // Depth backstop. Parent's `ancestors.length` is its own depth; a\n // child would be at `parent.ancestors.length + 1`. Reject before any\n // lake work or item resolution — the mutation has not been persisted\n // yet, so throwing here is safe.\n if (ctx.instance.ancestors.length + 1 > MAX_SPAWN_DEPTH) {\n const chain = [...ctx.instance.ancestors.map((a) => a.id), selfGdr(ctx.instance)].join(' → ')\n throw new Error(\n `Spawn depth limit (${MAX_SPAWN_DEPTH}) exceeded on task \"${task.id}\" of ${ctx.instance._id}. ` +\n `Ancestor chain: ${chain}`,\n )\n }\n\n const now = ctx.now\n const rows = await resolveSpawnRows(ctx, spawn)\n const refs: GlobalDocumentReference[] = []\n\n for (const row of rows) {\n const projected = projectSpawnRow(ctx.instance, spawn, row, now)\n const {ref, body} = await prepareChildInstance({\n client: ctx.client,\n parent: ctx.instance,\n task,\n spawn,\n initialState: projected.initialState,\n effectsContext: projected.effectsContext,\n actor,\n now,\n })\n refs.push(ref)\n // Defer the write — `persist` drains `pendingCreates` into one\n // transaction with the parent's patch.\n mutation.pendingCreates.push(body)\n }\n\n return refs\n}\n\n/**\n * Run `spawn.forEach.groq` against the lake and return the rows. The\n * groq runs through the discovery client (resourceClients-aware) with\n * reserved params stripped to bare ids.\n */\nasync function resolveSpawnRows(ctx: EngineContext, spawn: Spawn): Promise<unknown[]> {\n const params = buildParams(ctx.instance, ctx.now)\n const groq = spawn.forEach.groq\n\n let value: unknown\n if (groq.includes('*')) {\n // Lake discovery — route through resourceClients in case the\n // spawn's GROQ targets a different Sanity resource than the\n // parent. We pick the resource by the first workflow-scope\n // `doc.ref` slot's GDR — typically the natural \"subject\" of the\n // workflow. Authors declaring a different routing target should\n // put that doc.ref slot first.\n const routingUri = firstDocRefGdrUri(ctx.instance.state)\n const client = clientForDiscovery(ctx.client, ctx.clientForGdr, routingUri)\n value = await discoverItems({\n client,\n groq,\n params,\n ...(ctx.instance.perspective !== undefined ? {perspective: ctx.instance.perspective} : {}),\n })\n } else {\n // Pure-param GROQ — evaluate in-process against an empty dataset.\n const tree = parse(groq, {params})\n const result = await evaluate(tree, {dataset: [ctx.instance], params, root: ctx.instance})\n value = await result.get()\n }\n\n if (Array.isArray(value)) return value\n if (value === null || value === undefined) return []\n return [value]\n}\n\n/** First workflow-scope `doc.ref` slot GDR URI, if any. Used to pick\n * the discovery client for spawn `forEach.groq`. */\nfunction firstDocRefGdrUri(slots: ResolvedStateSlot[] | undefined): string | undefined {\n if (!slots) return undefined\n for (const s of slots) {\n if (s._type === 'workflow.state.doc.ref' && s.value !== null) return s.value.id\n }\n return undefined\n}\n\n/**\n * Resolve a Source against the spawn-time context: row + parent state.\n * Returns the resolved value. Bare doc ids in `row` are NOT canonicalised\n * — the projection author is responsible for spelling out the GDR type\n * via a nested object or by using `Source.parentState` for ids that\n * already live in canonical form.\n */\nfunction resolveSpawnSource(\n source: Source,\n parent: WorkflowInstance,\n row: unknown,\n now: string,\n): unknown {\n switch (source.source) {\n case 'literal':\n return source.value\n case 'row':\n return source.path !== undefined ? getPath(row, source.path) : row\n case 'parentState': {\n const slot = parent.state?.find((s) => s.id === source.slotId)\n if (slot === undefined) return null\n return source.path !== undefined ? getPath(slot, source.path) : slot\n }\n case 'self':\n return selfGdr(parent)\n case 'stageId':\n return parent.currentStageId\n case 'now':\n return now\n case 'object': {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(source.fields)) {\n out[k] = resolveSpawnSource(v, parent, row, now)\n }\n return out\n }\n case 'actor':\n case 'param':\n case 'stateRead':\n case 'effectOutput':\n // These don't make sense at spawn time — no firing actor, no\n // action params, no in-progress mutation, no effect outputs.\n // Return null to fail loud rather than silently producing\n // misleading data.\n return null\n }\n}\n\n/**\n * Project a spawn's `forEach.as` against one row → the child's\n * `initialState` array + the seed map for the child's `effectsContext`.\n */\nfunction projectSpawnRow(\n parent: WorkflowInstance,\n spawn: Spawn,\n row: unknown,\n now: string,\n): {\n initialState: InitialStateValue[]\n effectsContext: Record<string, string | number | boolean | GlobalDocumentReference>\n} {\n const initialState: InitialStateValue[] = []\n for (const entry of spawn.forEach.as.initialState ?? []) {\n const raw = resolveSpawnSource(entry.value, parent, row, now)\n const value = canonicaliseSpawnValue(entry.type, raw, parent.workflowResource)\n initialState.push({\n type: entry.type as InitialStateValue['type'],\n id: entry.id,\n value: value as InitialStateValue['value'],\n } as InitialStateValue)\n }\n\n const effectsContext: Record<string, string | number | boolean | GlobalDocumentReference> = {}\n for (const [k, src] of Object.entries(spawn.forEach.as.effectsContext ?? {})) {\n const v = resolveSpawnSource(src, parent, row, now)\n if (v === undefined || v === null) continue\n if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') {\n effectsContext[k] = v\n } else if (typeof v === 'object' && 'id' in v && 'type' in v) {\n // GDR shape — schema-validated at create time; engine here just\n // trusts the projection author's typing.\n effectsContext[k] = v as GlobalDocumentReference\n }\n }\n return {initialState, effectsContext}\n}\n\n/**\n * Canonicalise a spawn-projected slot value for `doc.ref` / `doc.refs`\n * slots. Spawn projections naturally produce raw row data: bare doc\n * ids, `{ _ref, _type }` envelopes, or `{ id, type }` pairs where `id`\n * may be bare. The engine knows the spawning parent's resource, so it\n * canonicalises bare ids into GDR URIs rooted at that resource.\n *\n * Cross-resource spawns must spell the URI out in GROQ (or build a\n * `{ id: \"<full-uri>\", type: ... }` object via the `object` Source)\n * — the engine doesn't infer foreign resources.\n *\n * Non doc.ref / doc.refs slots pass through unchanged.\n */\nfunction canonicaliseSpawnValue(\n slotType: string,\n value: unknown,\n workflowResource: import('../core/refs.ts').WorkflowResource,\n): unknown {\n if (slotType === 'workflow.state.doc.ref') {\n return coerceSpawnGdr(value, workflowResource)\n }\n if (slotType === 'workflow.state.doc.refs') {\n if (!Array.isArray(value)) return value\n return value.map((v) => coerceSpawnGdr(v, workflowResource)).filter((v) => v !== null)\n }\n return value\n}\n\nfunction coerceSpawnGdr(\n raw: unknown,\n workflowResource: import('../core/refs.ts').WorkflowResource,\n): GlobalDocumentReference | null {\n // Canonicalise a bare doc id into a GDR URI rooted at this resource;\n // leave already-canonical URIs untouched.\n const toUri = (id: string) => (isGdrUri(id) ? id : gdrFromResource(workflowResource, id))\n\n if (raw === null || raw === undefined) return null\n if (typeof raw === 'object' && 'id' in raw && 'type' in raw) {\n const r = raw as {id: unknown; type: unknown}\n if (typeof r.id === 'string' && typeof r.type === 'string') {\n return {id: toUri(r.id), type: r.type}\n }\n }\n if (typeof raw === 'object' && '_ref' in raw) {\n const r = raw as {_ref: unknown}\n if (typeof r._ref === 'string') return {id: toUri(r._ref), type: 'document'}\n }\n if (typeof raw === 'string' && raw.length > 0) return {id: toUri(raw), type: 'document'}\n return null\n}\n\n/**\n * Resolve a logical (workflowId, version?) ref to a deployed\n * `workflow.definition` doc. Scopes the lookup to definitions sharing\n * at least one tag with the caller. Picks the highest `version` when\n * `version` is omitted or `\"latest\"`; otherwise the explicit version.\n *\n * Returns null when no matching definition exists.\n */\nasync function resolveLogicalDefinition(\n client: WorkflowClient,\n ref: {workflowId: string; version?: number | 'latest' | undefined},\n tags: string[],\n): Promise<(WorkflowDefinition & SanityDocument) | null> {\n const wantsExplicit = typeof ref.version === 'number'\n const params: Record<string, unknown> = {workflowId: ref.workflowId, engineTags: tags}\n if (wantsExplicit) params.version = ref.version\n const result = await client.fetch<(WorkflowDefinition & SanityDocument) | null>(\n definitionLookupGroq(wantsExplicit),\n params,\n )\n return result ?? null\n}\n\nasync function prepareChildInstance(args: {\n client: WorkflowClient\n parent: WorkflowInstance\n task: Task\n spawn: Spawn\n initialState: InitialStateValue[]\n effectsContext: Record<string, string | number | boolean | GlobalDocumentReference>\n actor: Actor | undefined\n now: string\n}): Promise<{ref: GlobalDocumentReference; body: WorkflowInstance}> {\n const {client, parent, task, spawn, initialState, effectsContext, actor, now} = args\n\n const definition = await resolveLogicalDefinition(client, spawn.definitionRef, parent.tags ?? [])\n if (definition === null) {\n const versionLabel =\n spawn.definitionRef.version === undefined || spawn.definitionRef.version === 'latest'\n ? 'latest'\n : `v${spawn.definitionRef.version}`\n throw new Error(\n `Spawn target workflowId=\"${spawn.definitionRef.workflowId}\" ${versionLabel} not deployed (parent ${parent._id}, task ${task.id})`,\n )\n }\n\n // Child inherits the parent's tags + workflow resource so it stays\n // visible to whichever engine spawned the parent.\n const childTags = parent.tags ?? []\n const childPrefix = childTags[0] ?? 'wf'\n const workflowResource = parent.workflowResource\n // Bare `_id` — Sanity rejects `:` in document IDs. The GDR URI form\n // (`childUri`) is what the parent's `taskEntry.spawnedInstances[]`\n // and the child's own `ancestors[]` reference.\n const childDocId = `${childPrefix}.wf-instance.${randomKey()}`\n const childUri = gdrFromResource(workflowResource, childDocId)\n const childRef: GlobalDocumentReference = {id: childUri, type: WORKFLOW_INSTANCE_TYPE}\n const ancestors = [\n ...parent.ancestors,\n {\n id: selfGdr(parent),\n type: WORKFLOW_INSTANCE_TYPE,\n } as GlobalDocumentReference,\n ]\n\n // Resolve the child's workflow-scope state declarations against the\n // caller-supplied `initialState`. The child's own state[] schema\n // dictates which slot ids/types exist; the spawn projection just\n // fills the \"init\"-sourced ones. Query/write slots resolve\n // per their own source kind.\n // Child instances inherit the parent's perspective by default — if\n // the parent reads under a release stack, child filters / spawn\n // discovery should see the same stacked view of the lake.\n const inheritedPerspective = parent.perspective\n const childState = await resolveDeclaredState({\n slotDefs: definition.state,\n initialState,\n ctx: {\n client,\n now,\n selfId: childDocId,\n tags: childTags,\n workflowResource,\n ...(inheritedPerspective !== undefined ? {perspective: inheritedPerspective} : {}),\n },\n randomKey,\n })\n // A child may carry its own `release.ref` slot (projected from the\n // spawn forEach) — that takes precedence over inheritance. Otherwise\n // it inherits the parent's perspective.\n const childPerspective = derivePerspectiveFromState(childState) ?? inheritedPerspective\n\n const effectsContextEntries: EffectsContextEntry[] = Object.entries(effectsContext).map(\n ([key, value]) => {\n if (typeof value === 'object' && value !== null && 'id' in value && 'type' in value) {\n if (!isGdrUri(value.id)) {\n throw new Error(\n `spawn.forEach.as.effectsContext[\"${key}\"]: GDR id must be a \"<scheme>:...\" URI, got ${JSON.stringify(value.id)}.`,\n )\n }\n return effectsContextEntry(key, {id: value.id, type: value.type})\n }\n return effectsContextEntry(key, value)\n },\n )\n\n const base = buildInstanceBase({\n id: childDocId,\n now,\n tags: childTags,\n workflowResource,\n workflowId: definition.workflowId,\n pinnedVersion: definition.version,\n definition,\n state: childState,\n effectsContext: effectsContextEntries,\n ancestors,\n perspective: childPerspective,\n initialStageId: definition.initialStageId,\n actor,\n })\n // Body is returned to the caller; the actual `client.create` happens\n // inside the parent's persist transaction so the parent's\n // `spawnedInstances` patch and this child create commit atomically.\n // Priming + cascade run after the transaction (per-child, single-doc).\n return {ref: childRef, body: base}\n}\n\nexport async function checkSpawnCompletion(\n client: WorkflowClient,\n entry: TaskEntry,\n spawn: Spawn,\n): Promise<boolean> {\n const refs = entry.spawnedInstances ?? []\n if (refs.length === 0) {\n // Vacuous: 0/0 children done satisfies \"all\" / \"count: 0\"; \"any\" / \"count: N>0\" fails.\n const policy = spawn.completionPolicy ?? {kind: 'all'}\n return policy.kind === 'all' || (policy.kind === 'count' && policy.n === 0)\n }\n\n // Single GROQ — fetches every child's stage info in one roundtrip\n // instead of N serial `getDocument` calls. (Previously this was the\n // engine's most expensive cascade hot path for fan-out spawns.)\n // `ref.id` is the child's GDR URI; the persistent `_id` is bare.\n const ids = refs.map((r) => (r.id.includes(':') ? gdrToBareId(r.id) : r.id))\n const children = await client.fetch<\n {_id: string; currentStageId: string; definitionSnapshot: string}[]\n >(`*[_id in $ids]{_id, currentStageId, definitionSnapshot}`, {ids})\n\n let terminalCount = 0\n for (const child of children) {\n const childDef = JSON.parse(child.definitionSnapshot) as WorkflowDefinition\n const childStage = childDef.stages.find((s) => s.id === child.currentStageId)\n if (childStage?.kind === 'terminal') terminalCount++\n }\n\n const policy = spawn.completionPolicy ?? {kind: 'all'}\n switch (policy.kind) {\n case 'all':\n // refs.length here is non-zero (handled above).\n return terminalCount === refs.length\n case 'any':\n return terminalCount >= 1\n case 'count':\n return terminalCount >= policy.n\n }\n}\n","import type {Stage, Task} from '../define/schema.ts'\nimport {randomKey} from '../keys.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {TaskId} from '../types/ids.ts'\nimport type {TaskEntry} from '../types/instance-state.ts'\nimport {\n ctxEvaluateFilter,\n type EngineContext,\n findStage,\n loadContext,\n resolveTaskStateSlots,\n} from './context.ts'\nimport {queueEffects} from './effects.ts'\nimport {\n findCurrentTasks,\n findTaskInCurrentStage,\n type MutableInstance,\n persist,\n requireMutationTaskEntry,\n startMutation,\n taskStatusChangedEntry,\n} from './mutation.ts'\nimport type {EngineCallOptions, InvokeResult} from './results.ts'\nimport {checkSpawnCompletion, spawnChildren} from './spawn.ts'\n\n/**\n * Flip a task from `pending` to `active` and queue its declared effects.\n * No-op if the task is already active or done.\n */\nexport async function invokeTask(args: {\n client: WorkflowClient\n instanceId: string\n taskId: TaskId\n options?: EngineCallOptions\n}): Promise<InvokeResult> {\n const {client, instanceId, taskId, options} = args\n const ctx = await loadContext(client, instanceId, {\n ...(options?.clock ? {clock: options.clock} : {}),\n })\n return commitInvoke(ctx, taskId, options?.actor)\n}\n\nasync function commitInvoke(\n ctx: EngineContext,\n taskId: TaskId,\n actor: Actor | undefined,\n): Promise<InvokeResult> {\n const {task} = findTaskInCurrentStage(ctx, taskId)\n const entry = findCurrentTasks(ctx.instance).find((t) => t.id === taskId)\n if (entry === undefined) {\n throw new Error(`Task \"${taskId}\" has no status entry on instance ${ctx.instance._id}`)\n }\n if (entry.status !== 'pending') {\n return {invoked: false, taskId}\n }\n\n const mutation = startMutation(ctx.instance)\n const mutEntry = requireMutationTaskEntry(mutation, taskId)\n await activateTask(ctx, mutation, task, mutEntry, actor)\n await persist(ctx, mutation)\n return {invoked: true, taskId}\n}\n\n/**\n * On activation, evaluate the task's `failWhen` then `completeWhen`\n * predicates against the current snapshot. The first truthy one\n * immediately resolves the task (failure dominates), recording a\n * system-actor status change. Returns true when the task resolved so\n * the caller short-circuits the normal active path.\n */\nasync function autoResolveOnActivate(\n ctx: EngineContext,\n mutation: MutableInstance,\n task: Task,\n entry: TaskEntry,\n now: string,\n): Promise<boolean> {\n const checks: {filter: Task['failWhen']; outcome: 'failed' | 'done'; systemId: string}[] = [\n {filter: task.failWhen, outcome: 'failed', systemId: 'engine.failWhen'},\n {filter: task.completeWhen, outcome: 'done', systemId: 'engine.completeWhen'},\n ]\n for (const {filter, outcome, systemId} of checks) {\n if (filter === undefined) continue\n if (!(await ctxEvaluateFilter(ctx, filter))) continue\n entry.status = outcome\n entry.completedAt = now\n entry.completedBy = systemId\n mutation.history.push(\n taskStatusChangedEntry({\n stageId: mutation.currentStageId,\n taskId: task.id,\n from: 'active',\n to: outcome,\n at: now,\n actor: {kind: 'system', id: systemId},\n }),\n )\n return true\n }\n return false\n}\n\nexport async function activateTask(\n ctx: EngineContext,\n mutation: MutableInstance,\n task: Task,\n entry: TaskEntry,\n actor: Actor | undefined,\n): Promise<void> {\n // One clock reading for the whole activation so startedAt, any\n // auto-resolve flip, taskActivated, and spawn stamps agree on the time.\n const now = ctx.now\n entry.status = 'active'\n entry.startedAt = now\n // Resolve task-scoped state slots declared on the task definition.\n // Skipped if the task declares none — keeps the entry shape clean.\n if (task.state !== undefined && task.state.length > 0) {\n const stage = findStage(ctx.definition, mutation.currentStageId)\n entry.state = await resolveTaskStateSlots({\n client: ctx.client,\n instance: ctx.instance,\n stage,\n task,\n now,\n })\n }\n // Auto-failure dominates auto-completion: if both predicates would\n // fire, evaluate failWhen first so the more notable signal wins.\n if (await autoResolveOnActivate(ctx, mutation, task, entry, now)) return\n mutation.history.push({\n _key: randomKey(),\n _type: 'workflow.history.taskActivated',\n at: now,\n stageId: mutation.currentStageId,\n taskId: task.id,\n ...(actor !== undefined ? {actor} : {}),\n })\n await queueEffects(\n ctx,\n mutation,\n task.effects,\n {\n kind: 'taskInvoke',\n id: task.id,\n },\n actor,\n )\n\n // If the task has a `spawns` declaration, fan out child workflow\n // instances now. The task stays `active` — propagation will flip it\n // to `done` once the spawn's completion policy is satisfied as\n // children transition.\n if (task.spawns !== undefined) {\n const refs = await spawnChildren(ctx, mutation, task, task.spawns, actor)\n entry.spawnedInstances = refs\n for (const ref of refs) {\n mutation.history.push({\n _key: randomKey(),\n _type: 'workflow.history.spawned',\n at: now,\n taskId: task.id,\n instanceRef: ref,\n })\n }\n\n // Vacuous-truth case: if the spawn yielded zero items and the\n // policy is satisfied without any children (`{ kind: \"all\" }` over\n // an empty set is true; `{ kind: \"count\", n: 0 }` likewise), mark\n // the task done immediately. Otherwise propagation would never fire\n // (no child transitions to ride on), and the task would be stuck.\n if (await checkSpawnCompletion(ctx.client, entry, task.spawns)) {\n const previousStatus = entry.status\n entry.status = 'done'\n entry.completedAt = now\n mutation.history.push(\n taskStatusChangedEntry({\n stageId: mutation.currentStageId,\n taskId: task.id,\n from: previousStatus,\n to: 'done',\n at: now,\n ...(actor !== undefined ? {actor} : {}),\n }),\n )\n }\n }\n}\n\n// Internal — task status & effects\n\nexport async function buildStageTasks(ctx: EngineContext, stage: Stage): Promise<TaskEntry[]> {\n const entries: TaskEntry[] = []\n for (const task of stage.tasks ?? []) {\n const inScope = await ctxEvaluateFilter(ctx, task.filter)\n entries.push({\n _key: randomKey(),\n id: task.id,\n status: inScope ? 'pending' : 'skipped',\n ...(task.filter !== undefined\n ? {\n filterEvaluation: {\n at: ctx.now,\n truthy: inScope,\n },\n }\n : {}),\n })\n }\n return entries\n}\n\n/** Tasks that implicitly activate when their stage is entered. */\nexport function activatesOnStageEnter(task: Task): boolean {\n return (\n task.invokeOn === 'stageEnter' ||\n task.spawns !== undefined ||\n task.completeWhen !== undefined ||\n task.failWhen !== undefined\n )\n}\n","import type {Stage, Transition} from '../define/schema.ts'\nimport {deployStageGuards, retractStageGuards} from '../guards-lifecycle.ts'\nimport {randomKey} from '../keys.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {StageId} from '../types/ids.ts'\nimport {findOpenStageEntry, type StageEntry} from '../types/instance-state.ts'\nimport {\n ctxEvaluateFilter,\n type EngineContext,\n findStage,\n loadContext,\n resolveStageStateSlots,\n} from './context.ts'\nimport {queueEffects} from './effects.ts'\nimport {deployOrRollback} from './guard-commit.ts'\nimport {\n instanceStateFields,\n materializeInstance,\n type MutableInstance,\n persist,\n stageTransitionHistory,\n startMutation,\n} from './mutation.ts'\nimport type {EngineCallOptions, TransitionResult} from './results.ts'\nimport {activatesOnStageEnter, activateTask, buildStageTasks} from './tasks.ts'\n\n/**\n * Admin override — force the instance into `targetStageId` regardless\n * of filters or declared transitions. Use cases: Kanban-style UI where\n * each column is a stage; migration scripts; manual recovery from a\n * stuck workflow. ACL gating is enforced at the API layer.\n *\n * Behaviour mirrors a successful transition: exit current stage,\n * append a fresh StageEntry for the target, fire onExit + onEnter\n * effects, auto-activate stageEnter / spawn / completeWhen tasks,\n * cascade. The history entries carry `via: \"setStage\"` so audits can\n * distinguish filtered transitions from admin overrides.\n */\nexport async function setStage(args: {\n client: WorkflowClient\n instanceId: string\n targetStageId: StageId\n reason?: string\n options?: EngineCallOptions\n}): Promise<TransitionResult> {\n const {client, instanceId, targetStageId, reason, options} = args\n const ctx = await loadContext(client, instanceId, {\n ...(options?.clock ? {clock: options.clock} : {}),\n })\n return commitSetStage(ctx, targetStageId, reason, options?.actor)\n}\n\n/**\n * Append a fresh {@link StageEntry} for `nextStage` and run the on-entry\n * lifecycle: queue `onEnter` effects, auto-activate tasks that must run on\n * stage entry (`invokeOn: \"stageEnter\"`, or those declaring `spawns` /\n * `completeWhen` / `failWhen`), and mark the instance complete if the stage is\n * terminal. The caller owns history, prior-stage exit, persistence, and guard\n * reconciliation. `at` is the single timestamp stamped on the entry.\n */\nasync function enterStage(\n ctx: EngineContext,\n mutation: MutableInstance,\n nextStage: Stage,\n actor: Actor | undefined,\n at: string,\n): Promise<void> {\n mutation.currentStageId = nextStage.id\n const nextStageEntry: StageEntry = {\n _key: randomKey(),\n id: nextStage.id,\n enteredAt: at,\n state: await resolveStageStateSlots({\n client: ctx.client,\n instance: ctx.instance,\n stage: nextStage,\n now: at,\n }),\n tasks: await buildStageTasks(ctx, nextStage),\n }\n mutation.stages.push(nextStageEntry)\n\n await queueEffects(\n ctx,\n mutation,\n nextStage.onEnter,\n {kind: 'stageEnter', id: nextStage.id},\n actor,\n )\n\n for (const task of nextStage.tasks ?? []) {\n if (!activatesOnStageEnter(task)) continue\n const entry = nextStageEntry.tasks.find((t) => t.id === task.id)\n if (entry && entry.status === 'pending') {\n await activateTask(ctx, mutation, task, entry, actor)\n }\n }\n\n if (nextStage.kind === 'terminal') {\n mutation.completedAt = at\n }\n}\n\n/**\n * Begin a stage move: snapshot the instance into a mutation, stamp one `at`\n * timestamp for the whole move, and queue the current stage's onExit effects.\n * Shared by the setStage and transition commit paths.\n */\nasync function beginStageMove(\n ctx: EngineContext,\n currentStage: Stage,\n actor: Actor | undefined,\n): Promise<{mutation: MutableInstance; at: string}> {\n const mutation = startMutation(ctx.instance)\n const at = ctx.now\n await queueEffects(\n ctx,\n mutation,\n currentStage.onExit,\n {kind: 'stageExit', id: currentStage.id},\n actor,\n )\n return {mutation, at}\n}\n\nasync function commitSetStage(\n ctx: EngineContext,\n targetStageId: StageId,\n reason: string | undefined,\n actor: Actor | undefined,\n): Promise<TransitionResult> {\n const currentStage = findStage(ctx.definition, ctx.instance.currentStageId)\n const nextStage = findStage(ctx.definition, targetStageId)\n if (currentStage.id === nextStage.id) {\n return {fired: false}\n }\n\n const {mutation, at} = await beginStageMove(ctx, currentStage, actor)\n\n const transitionId = `setStage:${currentStage.id}->${nextStage.id}`\n mutation.history.push(\n ...stageTransitionHistory({\n fromStageId: currentStage.id,\n toStageId: nextStage.id,\n at,\n transitionId,\n via: 'setStage',\n ...(actor !== undefined ? {actor} : {}),\n ...(reason !== undefined ? {reason} : {}),\n }),\n )\n\n const priorEntry = findOpenStageEntry(mutation)\n if (priorEntry !== undefined) priorEntry.exitedAt = at\n\n await enterStage(ctx, mutation, nextStage, actor, at)\n\n await persistStageMove(ctx, mutation, currentStage.id, nextStage.id)\n\n return {\n fired: true,\n fromStageId: currentStage.id,\n toStageId: nextStage.id,\n transitionId,\n }\n}\n\n/**\n * Persist a stage move, then reconcile its lake guards — deploy the entered\n * stage's, then lift the exited stage's. The two are deliberately separate, not\n * a single `reconcile`, because of rollback ordering:\n *\n * - Deploying the entered stage's lock runs *inside* the rollback scope. If it\n * fails, the move rolls back and the **exited** stage's guards are untouched —\n * the stage we return to is still enforced. (Retract-then-deploy would have\n * left the exited stage unlocked on a deploy failure.)\n * - Lifting the exited stage's guards runs *after* the move commits, resolved\n * against the pre-move `ctx.instance` so its stage-scoped Sources still\n * resolve (post-move that stage entry is `exitedAt`-stamped). A retract\n * failure leaves a stale lock on the prior stage — the documented orphan seam,\n * the safe (over-lock) direction — rather than an unlocked stage.\n */\nasync function persistStageMove(\n ctx: EngineContext,\n mutation: MutableInstance,\n exitedStageId: StageId,\n enteredStageId: StageId,\n): Promise<void> {\n await persistThenDeploy(ctx, mutation, () =>\n deployStageGuards({\n client: ctx.client,\n clientForGdr: ctx.clientForGdr,\n instance: materializeInstance(ctx.instance, mutation),\n definition: ctx.definition,\n stageId: enteredStageId,\n now: ctx.now,\n }),\n )\n await retractStageGuards({\n client: ctx.client,\n clientForGdr: ctx.clientForGdr,\n instance: ctx.instance,\n definition: ctx.definition,\n stageId: exitedStageId,\n now: ctx.now,\n })\n}\n\n/**\n * Commit a mutation, then deploy its stage's guards — rolling the commit back\n * (or screaming when it can't) if the deploy fails, so persisted state and\n * deployed guards never silently diverge. Guards deploy AFTER the commit: a\n * guard can lock the caller out of further edits, so it must follow the state\n * it enforces. When the commit was a spawn transaction it created child docs a\n * parent-only rollback can't undo, so that case screams instead of half-undoing.\n * This is the shared commit+deploy chokepoint for the transition and action paths.\n */\nexport async function persistThenDeploy(\n ctx: EngineContext,\n mutation: MutableInstance,\n deploy: () => Promise<void>,\n): Promise<void> {\n const spawned = mutation.pendingCreates.length > 0\n const committed = await persist(ctx, mutation)\n await deployOrRollback({\n client: ctx.client,\n instanceId: ctx.instance._id,\n committedRev: committed._rev,\n restore: instanceStateFields(ctx.instance),\n unset: ctx.instance.completedAt === undefined ? ['completedAt'] : [],\n reversible: !spawned,\n deploy,\n })\n}\n\n/**\n * Re-deploy the current stage's guards against post-mutation state. A guard\n * snapshots the workflow state its `match`/`metadata` Sources resolve to at\n * deploy time; when an action's ops change that state without a stage move,\n * the engine must refresh the guard so it stays coherent (the \"use the engine,\n * stay consistent\" contract). Idempotent upsert — re-resolves each guard's\n * Sources against the new state via {@link materializeInstance}.\n *\n * Caveat: refresh only upserts. If an op changes a guard's `match.idRefs`\n * *target* (not just metadata), the re-deploy writes the guard to the new\n * resource while the old one lingers — the orphan/cross-dataset seam documented\n * in `guards-lifecycle.ts`. The metadata-change case (stable idRef) is fully\n * coherent; idRef re-homing waits on the retract/GC work.\n *\n * The caller (`commitAction`) runs this through {@link persistThenDeploy}, so a\n * failed re-deploy rolls the state change back rather than leaving it stale.\n * One coherence relaxation: {@link deployStageGuards} no-ops if a concurrent\n * transition moved the instance off `stageId` between the persist and the\n * deploy. The refresh is then correctly skipped (refreshing a left stage would\n * itself be wrong) and the state op stands — `deployOrRollback` sees success,\n * so this is not a divergence, it's the newer transition taking ownership.\n */\nexport async function refreshStageGuards(\n ctx: EngineContext,\n mutation: MutableInstance,\n stageId: StageId,\n): Promise<void> {\n await deployStageGuards({\n client: ctx.client,\n clientForGdr: ctx.clientForGdr,\n instance: materializeInstance(ctx.instance, mutation),\n definition: ctx.definition,\n stageId,\n now: ctx.now,\n })\n}\n\nexport async function commitTransition(\n ctx: EngineContext,\n action: string | undefined,\n actor: Actor | undefined,\n): Promise<TransitionResult> {\n const currentStage = findStage(ctx.definition, ctx.instance.currentStageId)\n const transition = await pickTransition(ctx, currentStage, action)\n if (transition === undefined) {\n return {fired: false}\n }\n\n const {mutation, at} = await beginStageMove(ctx, currentStage, actor)\n\n // Fire transition effects.\n await queueEffects(\n ctx,\n mutation,\n transition.effects,\n {\n kind: 'transition',\n id: transition.id ?? `${currentStage.id}->${transition.to}`,\n },\n actor,\n )\n\n // Append history.\n mutation.history.push(\n ...stageTransitionHistory({\n fromStageId: currentStage.id,\n toStageId: transition.to,\n at,\n ...(transition.id !== undefined ? {transitionId: transition.id} : {}),\n ...(actor !== undefined ? {actor} : {}),\n }),\n )\n\n // Mark the prior stage exited. There can be multiple entries with\n // the same id from loop-backs — the current one is the one without\n // exitedAt set.\n const priorEntry = findOpenStageEntry(mutation)\n if (priorEntry !== undefined) priorEntry.exitedAt = at\n\n // Move to new stage and append a fresh StageEntry with its tasks.\n const nextStage = findStage(ctx.definition, transition.to)\n await enterStage(ctx, mutation, nextStage, actor, at)\n\n await persistStageMove(ctx, mutation, currentStage.id, nextStage.id)\n\n return {\n fired: true,\n fromStageId: currentStage.id,\n toStageId: transition.to,\n ...(transition.id !== undefined ? {transitionId: transition.id} : {}),\n }\n}\n\nasync function pickTransition(\n ctx: EngineContext,\n stage: Stage,\n action: string | undefined,\n): Promise<Transition | undefined> {\n const candidates = (stage.transitions ?? []).filter((t) => {\n if (action === undefined) return t.on === undefined\n return t.on === action\n })\n for (const candidate of candidates) {\n if (await ctxEvaluateFilter(ctx, candidate.filter)) return candidate\n }\n return undefined\n}\n","// Essential commit⇄cascade mutual recursion: `mutation.persist` is the single\n// transactional commit chokepoint, and committing a parent that spawned\n// children must drive those children's lifecycle (prime → cascade → propagate)\n// inline, which itself commits through `persist`. Children are primed *within*\n// the parent's commit so the parent's spawn-completion gate observes them in the\n// same pass — deferring the drive to a higher layer would break that synchronous\n// nested-workflow semantics. Resolved at call time; module init is unaffected.\n// fallow-ignore-file circular-dependencies\nimport {type Clock, wallClock} from '../clock.ts'\nimport {resolveBindings} from '../core/bindings.ts'\nimport {evaluateFilter} from '../core/eval.ts'\nimport {buildParams} from '../core/params.ts'\nimport type {ParsedGdr} from '../core/refs.ts'\nimport type {LoadedDoc} from '../core/snapshot.ts'\nimport type {Stage, Task, WorkflowDefinition} from '../define/schema.ts'\nimport {deployStageGuards} from '../guards-lifecycle.ts'\nimport {randomKey} from '../keys.ts'\nimport {hydrateSnapshot} from '../snapshot.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {PendingEffect} from '../types/effects.ts'\nimport type {StageEntry, TaskEntry} from '../types/instance-state.ts'\nimport {WORKFLOW_INSTANCE_TYPE, type WorkflowInstance} from '../types/instance.ts'\nimport {\n buildEngineContext,\n ctxEvaluateFilter,\n type EngineContext,\n findStage,\n gdrToBareId,\n loadContext,\n resolveStageStateSlots,\n} from './context.ts'\nimport {buildQueuedEffect} from './effects.ts'\nimport {deployOrRollback} from './guard-commit.ts'\nimport {\n currentTasks,\n findCurrentTasks,\n persist,\n startMutation,\n taskStatusChangedEntry,\n} from './mutation.ts'\nimport {CascadeLimitError, type EngineCallOptions, type TransitionResult} from './results.ts'\nimport {checkSpawnCompletion} from './spawn.ts'\nimport {commitTransition} from './stages.ts'\nimport {activatesOnStageEnter, activateTask} from './tasks.ts'\n\n/**\n * Re-evaluate auto-transitions. Use after any change that might unblock\n * one (e.g. after a fireAction commits).\n */\nasync function evaluateAutoTransitions(args: {\n client: WorkflowClient\n instanceId: string\n options?: EngineCallOptions\n clientForGdr?: (parsed: ParsedGdr) => WorkflowClient\n clock?: Clock\n overlay?: ReadonlyMap<string, LoadedDoc>\n}): Promise<TransitionResult> {\n const {client, instanceId, options, clientForGdr, clock, overlay} = args\n const ctx = await loadContext(client, instanceId, {\n ...(clientForGdr ? {clientForGdr} : {}),\n ...(clock ? {clock} : {}),\n ...(overlay ? {overlay} : {}),\n })\n return commitTransition(ctx, undefined, options?.actor)\n}\n\n// Initial-stage priming, cascade, propagation — used by both api.ts (for\n// fresh instances and after-call cascading) and the spawn path inside\n// activateTask. Exported so api.ts doesn't reimplement them.\n\n/**\n * Build taskStatus + queue onEnter effects + auto-activate stageEnter\n * tasks for a freshly-created instance's initial stage. Called by both\n * `workflow.startInstance` and the spawn path.\n */\nexport async function primeInitialStage(\n client: WorkflowClient,\n instanceId: string,\n actor: Actor | undefined,\n clientForGdr?: (parsed: ParsedGdr) => WorkflowClient,\n clock?: Clock,\n): Promise<void> {\n const instance = await client.getDocument<WorkflowInstance>(instanceId)\n if (!instance) return\n // Idempotency: if the initial stage entry is already on the instance,\n // skip. New instances arrive here with `stages: []`.\n if (instance.stages.length > 0 || instance.pendingEffects.length > 0) return\n\n const definition = JSON.parse(instance.definitionSnapshot) as WorkflowDefinition\n const stage = definition.stages.find((s) => s.id === instance.currentStageId)\n if (stage === undefined) return\n\n // One clock reading for the whole prime so filter `$now`, the stage\n // entry, queued effects, and the commit all agree on the time.\n const now = (clock ?? wallClock)()\n\n // Build a snapshot up-front so any `filter` on a stage-tasks entry\n // can evaluate in-memory. Same shape the cascade uses.\n const snapshot = await hydrateSnapshot({\n client,\n clientForGdr: clientForGdr ?? (() => client),\n instance,\n })\n const tasks: TaskEntry[] = []\n for (const task of stage.tasks ?? []) {\n const inScope = await evaluateFilter({\n filter: task.filter,\n definition,\n snapshot,\n params: buildParams(instance, now),\n })\n tasks.push({\n _key: randomKey(),\n id: task.id,\n status: inScope ? 'pending' : 'skipped',\n })\n }\n const initialStageEntry: StageEntry = {\n _key: randomKey(),\n id: stage.id,\n enteredAt: now,\n state: await resolveStageStateSlots({client, instance, stage, now}),\n tasks,\n }\n\n const pendingEffects: PendingEffect[] = []\n const newHistory = [...instance.history]\n for (const effect of stage.onEnter ?? []) {\n const params = await resolveBindings({\n bindings: effect.bindings,\n staticInput: effect.input,\n instance,\n now,\n ...(actor !== undefined ? {actor} : {}),\n })\n const {pending, history} = buildQueuedEffect(\n effect,\n {kind: 'stageEnter', id: stage.id},\n params,\n actor,\n now,\n )\n pendingEffects.push(pending)\n newHistory.push(history)\n }\n\n // Patch — fails fast if the instance was deleted between the\n // `create` above and this prime call. `ifRevisionId` rejects concurrent\n // priming attempts (e.g. a retried startInstance).\n const committed = await client\n .patch(instance._id)\n .set({\n stages: [initialStageEntry],\n pendingEffects,\n history: newHistory,\n lastChangedAt: now,\n })\n .ifRevisionId(instance._rev)\n .commit()\n\n // Deploy lake guards for the initial stage (no exit to retract). If the\n // deploy fails, roll the prime back to the freshly-created (unprimed) state\n // so an instance never sits primed-but-unlocked; surface the error.\n await deployOrRollback({\n client,\n instanceId: instance._id,\n committedRev: committed._rev,\n restore: {\n stages: instance.stages,\n pendingEffects: instance.pendingEffects,\n history: instance.history,\n },\n reversible: true,\n deploy: () =>\n deployStageGuards({\n client,\n clientForGdr: clientForGdr ?? (() => client),\n instance,\n definition,\n stageId: stage.id,\n now,\n }),\n })\n\n await autoActivatePrimedTasks(client, instanceId, definition, stage, actor, clientForGdr, clock)\n}\n\n/**\n * After the initial stage entry is persisted, re-load and auto-activate\n * the tasks that implicitly run on stage-entry (`invokeOn: \"stageEnter\"`,\n * spawn-bearing, or carrying a `completeWhen`/`failWhen` predicate). Each\n * activation reloads + persists independently so spawns + auto-resolution\n * see committed state.\n */\nasync function autoActivatePrimedTasks(\n client: WorkflowClient,\n instanceId: string,\n definition: WorkflowDefinition,\n stage: Stage,\n actor: Actor | undefined,\n clientForGdr?: (parsed: ParsedGdr) => WorkflowClient,\n clock?: Clock,\n): Promise<void> {\n const resolvedClientForGdr = clientForGdr ?? (() => client)\n for (const task of stage.tasks ?? []) {\n if (!activatesOnStageEnter(task)) continue\n const updated = await client.getDocument<WorkflowInstance>(instanceId)\n if (!updated) continue\n const updatedCtx = await buildEngineContext({\n client,\n clientForGdr: resolvedClientForGdr,\n instance: updated,\n definition,\n ...(clock ? {clock} : {}),\n })\n const mutation = startMutation(updated)\n const mutEntry = currentTasks(mutation).find((t) => t.id === task.id)\n if (mutEntry && mutEntry.status === 'pending') {\n await activateTask(updatedCtx, mutation, task, mutEntry, actor)\n await persist(updatedCtx, mutation)\n }\n }\n}\n\n// Backpressure for the auto-transition cascade. Ops mutate state once per\n// `fireAction` (a finite authored list — no re-entrancy, so they need no\n// per-action limit of their own), but the *transitions* an op unblocks can\n// flip-flop without end. This is the single bound that catches that runaway;\n// it throws {@link CascadeLimitError} rather than writing revisions forever.\nconst CASCADE_LIMIT = 100\n\n/**\n * Walk active task entries whose authoring definition declares a\n * `completeWhen` and/or `failWhen` filter; evaluate the filters against\n * the current snapshot and flip any matching task accordingly. Returns\n * the count flipped.\n *\n * Both predicates are evaluated on the same pass. If a single task has\n * both and both are truthy, `failWhen` wins — failure dominates so the\n * more notable signal is not silently swallowed.\n *\n * The engine never runs a clock itself — this only fires if something\n * else (a `tick`, a `fireAction`, a `completeEffect`, or `startInstance`)\n * has already kicked the cascade. A scheduler crossing a deadline calls\n * `tick` (with an injected {@link Clock} under test); state-based\n * predicates rely on the caller invoking `tick` when state changes.\n */\ntype AutoResolveCandidate = {task: Task; outcome: 'done' | 'failed'}\n\n/** For each active task carrying an auto-predicate, evaluate `failWhen`\n * then `completeWhen` (failure dominates) and collect the outcome. */\nasync function gatherAutoResolveCandidates(\n ctx: EngineContext,\n tasks: Task[],\n): Promise<AutoResolveCandidate[]> {\n const currentTasksList = findCurrentTasks(ctx.instance)\n const candidates: AutoResolveCandidate[] = []\n for (const task of tasks) {\n const entry = currentTasksList.find((e) => e.id === task.id)\n if (entry?.status !== 'active') continue\n // failWhen first — failure dominates if both fire.\n if (task.failWhen !== undefined && (await ctxEvaluateFilter(ctx, task.failWhen))) {\n candidates.push({task, outcome: 'failed'})\n continue\n }\n if (task.completeWhen !== undefined && (await ctxEvaluateFilter(ctx, task.completeWhen))) {\n candidates.push({task, outcome: 'done'})\n }\n }\n return candidates\n}\n\nasync function resolveCompleteWhen(\n client: WorkflowClient,\n instanceId: string,\n clientForGdr?: (parsed: ParsedGdr) => WorkflowClient,\n clock?: Clock,\n overlay?: ReadonlyMap<string, LoadedDoc>,\n): Promise<number> {\n const ctx = await loadContext(client, instanceId, {\n ...(clientForGdr ? {clientForGdr} : {}),\n ...(clock ? {clock} : {}),\n ...(overlay ? {overlay} : {}),\n })\n const stage = findStage(ctx.definition, ctx.instance.currentStageId)\n const tasksWithAutoPredicate = (stage.tasks ?? []).filter(\n (t) => t.completeWhen !== undefined || t.failWhen !== undefined,\n )\n if (tasksWithAutoPredicate.length === 0) return 0\n\n const candidates = await gatherAutoResolveCandidates(ctx, tasksWithAutoPredicate)\n if (candidates.length === 0) return 0\n\n const mutation = startMutation(ctx.instance)\n let count = 0\n for (const {task, outcome} of candidates) {\n const mutEntry = currentTasks(mutation).find((t) => t.id === task.id)\n if (mutEntry === undefined || mutEntry.status !== 'active') continue\n const previousStatus = mutEntry.status\n const actor: Actor = {\n kind: 'system',\n id: outcome === 'failed' ? 'engine.failWhen' : 'engine.completeWhen',\n }\n const now = ctx.now\n mutEntry.status = outcome\n mutEntry.completedAt = now\n mutEntry.completedBy = actor.id\n mutation.history.push(\n taskStatusChangedEntry({\n stageId: stage.id,\n taskId: task.id,\n from: previousStatus,\n to: outcome,\n at: now,\n actor,\n }),\n )\n count++\n }\n if (count > 0) {\n await persist(ctx, mutation)\n }\n return count\n}\n\n/**\n * Cascade auto-transitions on the given instance until it lands stably.\n * Returns the count of transitions fired during the cascade. Resolves\n * any due waits before each transition pass so a wait that became due\n * can immediately unblock an `allTasksDone`-style filter.\n */\nexport async function cascadeAutoTransitions(\n client: WorkflowClient,\n instanceId: string,\n actor: Actor | undefined,\n clientForGdr?: (parsed: ParsedGdr) => WorkflowClient,\n clock?: Clock,\n overlay?: ReadonlyMap<string, LoadedDoc>,\n): Promise<number> {\n let count = 0\n while (true) {\n await resolveCompleteWhen(client, instanceId, clientForGdr, clock, overlay)\n const result = await evaluateAutoTransitions({\n client,\n instanceId,\n ...(actor !== undefined ? {options: {actor}} : {}),\n ...(clientForGdr ? {clientForGdr} : {}),\n ...(clock ? {clock} : {}),\n ...(overlay ? {overlay} : {}),\n })\n if (!result.fired) return count\n count++\n if (count >= CASCADE_LIMIT) {\n throw new CascadeLimitError({instanceId, limit: CASCADE_LIMIT})\n }\n }\n}\n\n/**\n * Walk up an instance's ancestor chain, re-evaluating each ancestor's\n * spawn-bearing task in case its completion policy is now satisfied. If\n * a parent task flips done as a result, cascade auto-transitions on the\n * parent and recurse upward.\n *\n * This is the load-bearing primitive for nested workflows: child\n * transitions ripple up the tree, parent gates close, grand-parent\n * gates close, all the way to the root.\n */\n/** The parent whose spawn-bearing task this child has just satisfied —\n * resolved from the child's ancestor chain, or undefined when there is\n * no such parent (no ancestors, parent gone/malformed, no matching\n * spawning task, task already done, or its completion policy not yet\n * met). Isolating these guard clauses keeps {@link propagateToAncestors}\n * to the flip-and-recurse it actually performs. */\ninterface SatisfiedParentSpawn {\n parent: WorkflowInstance\n definition: WorkflowDefinition\n stage: Stage\n task: Task\n}\n\nasync function findSatisfiedParentSpawn(\n client: WorkflowClient,\n child: WorkflowInstance,\n): Promise<SatisfiedParentSpawn | undefined> {\n const parentRef = child.ancestors.at(-1)\n if (parentRef === undefined) return undefined\n // ancestors[].id is the GDR URI; the Sanity `_id` is bare.\n const parent = await client.getDocument<WorkflowInstance>(gdrToBareId(parentRef.id))\n // A misconfigured caller could put an arbitrary doc ref in ancestors[];\n // bail gracefully instead of crashing on `JSON.parse(undefined)`.\n if (!parent || parent._type !== WORKFLOW_INSTANCE_TYPE) return undefined\n if (typeof parent.definitionSnapshot !== 'string') return undefined\n\n const definition = JSON.parse(parent.definitionSnapshot) as WorkflowDefinition\n const stage = definition.stages.find((s) => s.id === parent.currentStageId)\n if (stage === undefined) return undefined\n\n // Find the task on the parent's current stage that spawned this child.\n // `spawnedInstances[].id` is the child's GDR URI; the `_id` is bare.\n const parentCurrentTasks = findCurrentTasks(parent)\n const task = (stage.tasks ?? []).find((t) => {\n if (t.spawns === undefined) return false\n const entry = parentCurrentTasks.find((e) => e.id === t.id)\n return entry?.spawnedInstances?.some((r) => gdrToBareId(r.id) === child._id) ?? false\n })\n if (task?.spawns === undefined) return undefined\n\n const entry = parentCurrentTasks.find((e) => e.id === task.id)\n if (entry === undefined || entry.status === 'done') return undefined\n if (!(await checkSpawnCompletion(client, entry, task.spawns))) return undefined\n\n return {parent, definition, stage, task}\n}\n\nexport async function propagateToAncestors(\n client: WorkflowClient,\n instanceId: string,\n actor: Actor | undefined,\n clientForGdr?: (parsed: ParsedGdr) => WorkflowClient,\n clock?: Clock,\n): Promise<void> {\n const instance = await client.getDocument<WorkflowInstance>(instanceId)\n if (!instance) return\n\n const found = await findSatisfiedParentSpawn(client, instance)\n if (found === undefined) return\n const {parent, definition, stage, task} = found\n\n // Flip the parent's task to done and persist.\n const ctx = await buildEngineContext({\n client,\n clientForGdr: clientForGdr ?? (() => client),\n instance: parent,\n definition,\n ...(clock ? {clock} : {}),\n })\n const mutation = startMutation(parent)\n const mutEntry = currentTasks(mutation).find((e) => e.id === task.id)\n if (mutEntry === undefined) return\n const previousStatus = mutEntry.status\n const now = ctx.now\n mutEntry.status = 'done'\n mutEntry.completedAt = now\n mutation.history.push(\n taskStatusChangedEntry({\n stageId: stage.id,\n taskId: task.id,\n from: previousStatus,\n to: 'done',\n at: now,\n ...(actor !== undefined ? {actor} : {}),\n }),\n )\n await persist(ctx, mutation)\n\n // Cascade auto-transitions on the parent. This may transition it to\n // a new stage, which itself may unblock the grandparent's task.\n await cascadeAutoTransitions(client, parent._id, actor, clientForGdr, clock)\n\n // Recurse: propagate from the parent upward.\n await propagateToAncestors(client, parent._id, actor, clientForGdr, clock)\n}\n","/**\n * Permissions — GROQ-filter-based grant evaluation.\n *\n * Sanity ACLs come back as `Grant[]`. Each grant has a GROQ `filter`\n * and a list of `permissions` it confers. Whether a permission is\n * allowed on a given document is \"does any grant whose filter matches\n * the document carry that permission?\". Most-permissive wins; multiple\n * grants compose.\n *\n * Filters are evaluated with groq-js (already a dependency for transition\n * filter evaluation) so the engine doesn't ship a second predicate engine.\n */\n\nimport {evaluate, parse} from 'groq-js'\n\nimport type {Grant} from './types/authorization.ts'\nimport type {DocumentValuePermission} from './types/enums.ts'\n\n// Parsed-filter cache, keyed by the filter string. AST is cheap to\n// reuse; the evaluation against a document is what we want to keep\n// uncached because the document changes much more often than the filter.\nconst parsedFilters = new Map<string, ReturnType<typeof parse>>()\n\n/**\n * Evaluate a grant's GROQ filter against a single document with the\n * supplied identity. Returns true iff the document survives the filter.\n *\n * The implementation parses `*[<filter>]` once per filter string,\n * evaluates against a singleton dataset, and asks the result for its\n * length — `length === 1` means the doc passed.\n */\nexport async function matchesFilter(args: {\n document: {_id?: string; _type?: string; [key: string]: unknown}\n filter: string\n userId?: string\n}): Promise<boolean> {\n const {document, filter, userId} = args\n if (!parsedFilters.has(filter)) {\n parsedFilters.set(filter, parse(`*[${filter}]`))\n }\n const ast = parsedFilters.get(filter)!\n const result = await evaluate(ast, {\n dataset: [document],\n ...(userId !== undefined ? {identity: userId} : {}),\n })\n const data = await result.get()\n return Array.isArray(data) && data.length === 1\n}\n\n/**\n * Does the supplied `grants` set grant `permission` on `document` for\n * the given user? Walks each grant; a grant counts iff its filter\n * matches AND it lists the permission. Most-permissive wins.\n */\nexport async function grantsPermissionOn(args: {\n document?: {_id?: string; _type?: string; [key: string]: unknown}\n grants: Grant[]\n permission: DocumentValuePermission\n userId?: string\n}): Promise<boolean> {\n const {document, grants, permission, userId} = args\n if (!document || grants.length === 0) return false\n\n for (const grant of grants) {\n if (!grant.permissions.includes(permission)) continue\n if (\n await matchesFilter({\n document,\n filter: grant.filter,\n ...(userId !== undefined ? {userId} : {}),\n })\n ) {\n return true\n }\n }\n return false\n}\n\n/**\n * Convenience: fetch the grants for a given resource via the supplied\n * client:\n *\n * GET <resourcePath> → Grant[]\n *\n * `resourcePath` is caller-supplied so the same helper works for\n * project ACLs (`/projects/<id>/datasets/<dataset>/acl`) and for a\n * dedicated workflow-collaboration resource. The client must support\n * the `request<T>({url})` method `@sanity/client` exposes.\n */\nexport async function fetchGrants(args: {\n client: {request: <T>(opts: {url: string; signal?: AbortSignal}) => Promise<T>}\n resourcePath: string\n signal?: AbortSignal\n}): Promise<Grant[]> {\n const {client, resourcePath, signal} = args\n return client.request<Grant[]>({url: resourcePath, ...(signal ? {signal} : {})})\n}\n","/**\n * Access state — the cohesive (actor + grants) pair the engine\n * relies on for every authorization decision: one provider, one\n * cached resolution.\n *\n * Resolution strategy:\n *\n * 1. **Override.** If the caller supplies an `access` object on the\n * verb (or the bench's `createBench({ access })`), it wins — no\n * network calls. This is the only path that fires for the test\n * bench, whose `TestClient` has no token-bearing `request` method.\n * 2. **Token.** Otherwise the engine resolves both halves from the\n * supplied `@sanity/client`:\n * - `actor` ← `client.request({ url: \"/users/me\" })`\n * - `grants` ← `client.request({ url: grantsFromPath })`\n * Run in parallel; cached per-client (and per-path for grants) via\n * WeakMap so concurrent verb calls share one fetch.\n * 3. **Refusal.** If the client can't make HTTP requests (`request`\n * undefined) and no override was supplied, the engine throws a\n * clear error pointing at the bench / explicit override.\n *\n * Grants-fetch failure degrades open (gate is skipped, real Sanity\n * write boundary still enforces). Actor-fetch failure is fatal — the\n * engine refuses to stamp history without an identity.\n */\n\nimport {fetchGrants} from './permissions.ts'\nimport type {Actor} from './types/actor.ts'\nimport type {Grant} from './types/authorization.ts'\nimport type {WorkflowClient} from './types/client.ts'\n\n/** The options bag accepted by {@link WorkflowClient.request}. */\ntype RequestOptions = Parameters<NonNullable<WorkflowClient['request']>>[0]\n\n/**\n * Sanity's `/users/me` response shape — subset of `@sanity/types`'s\n * `CurrentUser`. Declared locally so the engine doesn't take a\n * runtime dep on `@sanity/types` for a single type.\n */\ninterface SanityCurrentUser {\n id: string\n name?: string\n email?: string\n /** @deprecated singular `role` on legacy responses */\n role?: string\n roles?: {name: string; title?: string; description?: string}[]\n}\n\n/**\n * The engine's view of \"who am I, what can I do?\". `actor` is who\n * the engine stamps onto history / `completedBy` / `Source.actor`.\n * `grants` (when present) gates `permission-denied`; when absent the\n * gate is skipped and the real Sanity write boundary takes over.\n *\n * This is the RESOLVED shape — `actor` is guaranteed. For the\n * partial-override shape callers pass on verb args, see\n * `WorkflowAccessOverride`.\n */\nexport interface WorkflowAccess {\n actor: Actor\n grants?: Grant[]\n}\n\n/**\n * Partial override accepted by every public verb's `access?:`\n * argument. Any field present wins; missing halves token-resolve.\n *\n * `{ actor, grants }` — bench's all-access default; both halves\n * injected, no token round-trip.\n * `{ actor }` — \"act as another user\"; grants come from\n * `grantsFromPath` (or the gate is skipped).\n * `{ grants }` — \"preview with restricted permissions\"; actor\n * comes from `/users/me`.\n * omitted entirely — both halves token-resolved.\n */\nexport type WorkflowAccessOverride = Partial<WorkflowAccess>\n\nexport interface ResolveAccessArgs {\n /**\n * Partial override. Any field set here wins outright; any field\n * left unset falls through to token resolution.\n *\n * - `override.actor` set + `override.grants` set → returned as-is.\n * - `override.actor` set + `override.grants` unset → actor from\n * override; grants fetched from `grantsFromPath` (or undefined).\n * - `override.actor` unset + `override.grants` set → actor from\n * `/users/me`; grants from override.\n * - `override` undefined entirely → both halves fetched.\n *\n * The test bench passes a fully-populated `{ actor, grants }` so\n * the underlying TestClient (no `request` method) never hits the\n * token path. Admin/preview tooling passes one or the other.\n */\n override?: {actor?: Actor; grants?: Grant[]}\n /**\n * Where the engine should fetch grants from the supplied client\n * when `override.grants` isn't given, e.g. a Canvas resource at\n * `/canvases/<resourceId>/acl` or a dataset at\n * `/projects/<id>/datasets/<ds>/acl`.\n */\n grantsFromPath?: string\n}\n\n// Actor cache is per-client. /users/me doesn't vary by path; one\n// fetch per client lifetime suffices.\nconst actorCache = new WeakMap<object, Promise<Actor | undefined>>()\n\n// Grants cache is per-(client, path). Multiple consumers in one\n// process can share the same client across different resources.\nconst grantsCache = new WeakMap<object, Map<string, Promise<Grant[] | undefined>>>()\n\n/**\n * Resolve the engine's `WorkflowAccess` for a client. Override wins\n * outright; otherwise both halves are fetched in parallel and\n * cached. Throws if neither path yields an actor — the engine\n * refuses to operate without an identity.\n */\nexport async function resolveAccess(\n client: WorkflowClient,\n args: ResolveAccessArgs = {},\n): Promise<WorkflowAccess> {\n const overrideActor = args.override?.actor\n const overrideGrants = args.override?.grants\n\n // Fast path: bench supplies both halves; no token needed.\n if (overrideActor !== undefined && overrideGrants !== undefined) {\n return {actor: overrideActor, grants: overrideGrants}\n }\n\n // Reaching here, the fast path above ruled out \"both halves supplied\",\n // so at least one half needs the client. A client with no `request`\n // can't fetch either: throw if the missing half is the actor, otherwise\n // degrade open on grants (the production \"endpoint unreachable\" path).\n //\n // Wrap `request` once so every downstream call site (actor + grants)\n // invokes it AS a method on `client`. `@sanity/client` >= 7.22 reads a\n // private field through `this`, so a detached `const fn = client.request;\n // fn(...)` loses `this` and throws before issuing the request. The\n // wrapper stays lazy: a plain `.bind` here would dereference `request`\n // eagerly even when an override supplies the only half we need, tripping\n // clients (e.g. the in-memory bench) whose `request` is a throw-on-use\n // stub. `=== undefined` preserves the probe for clients with no `request`.\n const requestFn: NonNullable<WorkflowClient['request']> | undefined =\n client.request === undefined ? undefined : <T>(opts: RequestOptions) => client.request!<T>(opts)\n if (requestFn === undefined) {\n if (overrideActor === undefined) {\n throw new Error(\n \"workflow: no actor available. The engine resolves the actor from the client's token \" +\n \"via `client.request({ url: '/users/me' })`. Supply a real `@sanity/client` configured \" +\n 'with a token, or pass an explicit `access.actor` override (the test bench provides ' +\n 'one by default).',\n )\n }\n return {actor: overrideActor}\n }\n\n const actorPromise =\n overrideActor !== undefined ? Promise.resolve(overrideActor) : cachedActor(client, requestFn)\n\n const grantsPromise = resolveGrants(overrideGrants, args.grantsFromPath, client, requestFn)\n\n const [actor, grants] = await Promise.all([actorPromise, grantsPromise])\n if (actor === undefined) {\n throw new Error(\n 'workflow: failed to resolve actor from `/users/me`. The client is configured but the ' +\n 'endpoint returned no usable identity — check the token, or pass `access.actor` explicitly.',\n )\n }\n return {actor, ...(grants !== undefined ? {grants} : {})}\n}\n\nfunction cachedActor(\n client: WorkflowClient,\n requestFn: NonNullable<WorkflowClient['request']>,\n): Promise<Actor | undefined> {\n const cached = actorCache.get(client)\n if (cached !== undefined) return cached\n\n // Evict on failure so a transient `/users/me` error (401/503/network)\n // doesn't poison the per-client cache for its lifetime — the next call\n // retries instead of permanently throwing \"failed to resolve actor\".\n const pending = fetchActor(requestFn).catch((err) => {\n if (actorCache.get(client) === pending) actorCache.delete(client)\n throw err\n })\n actorCache.set(client, pending)\n return pending\n}\n\nfunction resolveGrants(\n overrideGrants: Grant[] | undefined,\n grantsFromPath: string | undefined,\n client: WorkflowClient,\n requestFn: NonNullable<WorkflowClient['request']>,\n): Promise<Grant[] | undefined> {\n if (overrideGrants !== undefined) return Promise.resolve(overrideGrants)\n if (grantsFromPath !== undefined) return cachedGrants(client, requestFn, grantsFromPath)\n return Promise.resolve(undefined)\n}\n\nfunction cachedGrants(\n client: WorkflowClient,\n requestFn: NonNullable<WorkflowClient['request']>,\n resourcePath: string,\n): Promise<Grant[] | undefined> {\n let byPath = grantsCache.get(client)\n if (byPath === undefined) {\n byPath = new Map()\n grantsCache.set(client, byPath)\n }\n let cached = byPath.get(resourcePath)\n if (cached === undefined) {\n cached = fetchGrantsCached(requestFn, resourcePath)\n byPath.set(resourcePath, cached)\n }\n return cached\n}\n\nasync function fetchActor(\n requestFn: <T>(opts: {\n url?: string\n uri?: string\n signal?: AbortSignal\n tag?: string\n }) => Promise<T>,\n): Promise<Actor | undefined> {\n // `@sanity/client.request` distinguishes `uri` (project-API path,\n // resolved against the apiHost — e.g. `https://api.sanity.io/v1/users/me`)\n // from `url` (raw URL). `/users/me` is a global endpoint accessed via\n // `uri`. Studio itself uses `uri: '/users/me'` in its authStore\n // (sanity-v3 `createAuthStore.ts`). Using `url` here makes the\n // request hit the project-scoped endpoint, which returns empty for\n // the global user — causing \"no usable identity\" errors in studio.\n let user: SanityCurrentUser\n try {\n user = await requestFn<SanityCurrentUser>({\n uri: '/users/me',\n tag: 'workflow.access.resolve-actor',\n })\n } catch (err) {\n // Surface the request failure with its cause intact so the eventual\n // throw is diagnosable — and let it propagate so the per-client cache\n // is evicted and the next call retries (transient 401/503/network).\n throw new Error(\n \"workflow: /users/me request failed. The engine resolves the actor from the client's token \" +\n 'via `client.request({ uri: \"/users/me\" })`. Check the token/connectivity, or pass an ' +\n 'explicit `access.actor` override.',\n {cause: err},\n )\n }\n // A well-formed response that carries no usable identity is NOT an\n // error worth retrying — return undefined so the caller throws its\n // \"no usable identity\" message.\n if (!user || typeof user.id !== 'string' || user.id.length === 0) return undefined\n const roleNames = user.roles?.map((r) => r.name).filter((n): n is string => Boolean(n)) ?? []\n return {\n kind: 'user',\n id: user.id,\n ...(roleNames.length > 0 ? {roles: roleNames} : {}),\n }\n}\n\nasync function fetchGrantsCached(\n requestFn: NonNullable<WorkflowClient['request']>,\n resourcePath: string,\n): Promise<Grant[] | undefined> {\n try {\n return await fetchGrants({client: {request: requestFn}, resourcePath})\n } catch (err) {\n console.warn(\n `workflow: failed to fetch grants from \"${resourcePath}\"; skipping permission gate. ` +\n `Original error: ${err instanceof Error ? err.message : String(err)}`,\n )\n return undefined\n }\n}\n","/**\n * `workflow.evaluate` — the third concept.\n *\n * Reads an instance and projects \"what can this actor do right now,\n * and why not the rest?\" as a structured `WorkflowEvaluation`. Pure\n * read; never writes. Different actors see different evaluations of\n * the same instance.\n *\n * Used internally by `fireAction` to gate writes and externally by\n * UIs to render disabled-with-reason buttons.\n */\n\nimport {resolveAccess, type WorkflowAccessOverride} from './access.ts'\nimport {type Clocked, wallClock} from './clock.ts'\nimport {evaluateFilter} from './core/eval.ts'\nimport {buildParams} from './core/params.ts'\nimport type {ParsedGdr, WorkflowResource} from './core/refs.ts'\nimport type {HydratedSnapshot} from './core/snapshot.ts'\nimport type {Action, Assignee, Task, WorkflowDefinition} from './define/schema.ts'\nimport {grantsPermissionOn} from './permissions.ts'\nimport {hydrateSnapshot} from './snapshot.ts'\nimport {validateTags} from './tags.ts'\nimport type {Actor} from './types/actor.ts'\nimport type {Grant} from './types/authorization.ts'\nimport type {WorkflowClient} from './types/client.ts'\nimport type {TaskStatus} from './types/enums.ts'\nimport type {\n ActionEvaluation,\n DisabledReason,\n StageEvaluation,\n TaskEvaluation,\n TransitionEvaluation,\n WorkflowEvaluation,\n} from './types/evaluation.ts'\nimport {findOpenStageEntry, type TaskEntry} from './types/instance-state.ts'\nimport type {WorkflowInstance} from './types/instance.ts'\n\nconst WILDCARD_ROLE = '*'\n\nexport interface EvaluateArgs {\n client: WorkflowClient\n /** Engine-scope tags — required. */\n tags: string[]\n /** Engine workflow resource — required. */\n workflowResource: WorkflowResource\n instanceId: string\n /**\n * Optional access-state override. By default the engine resolves\n * `(actor, grants)` from the supplied client's token via\n * `/users/me` (+ `grantsFromPath`). The bench supplies its\n * `ALL_ACCESS` default here; admin tooling can use this for\n * \"view as another user\" or \"preview with restricted grants\" flows.\n */\n access?: WorkflowAccessOverride\n /**\n * URL path on the supplied client where the engine should fetch\n * grants when `access.grants` isn't supplied. Required for\n * production usage; omitting it means the engine skips the\n * `permission-denied` gate (graceful degradation — the real Sanity\n * write boundary still enforces).\n *\n * Canvas resource example: `/canvases/<resourceId>/acl`.\n * Project/dataset example: `/projects/<id>/datasets/<dataset>/acl`.\n *\n * Result is cached per `(client, path)` for the lifetime of the\n * process — grants don't change often, and tearing them down per\n * call would mean a network round-trip on every fireAction.\n */\n grantsFromPath?: string\n /**\n * Optional resource-aware client routing — see\n * `StartInstanceArgs.resourceClients`. When the workflow's subject\n * (or any ancestor) lives in a different resource than the engine's\n * client, this resolver decides which client to read it through.\n * The evaluation hydrates a GDR-keyed snapshot from those reads and\n * runs `_id`-scoped filters locally in groq-js — same model as the\n * cascade path.\n */\n resourceClients?: (parsed: ParsedGdr) => WorkflowClient | undefined\n}\n\nexport async function evaluateInstance(args: Clocked<EvaluateArgs>): Promise<WorkflowEvaluation> {\n const {client, tags, instanceId, resourceClients} = args\n // One clock reading for the whole projection so every filter's `$now`\n // agrees (and matches a frozen bench timeline). Pure read — never persisted.\n const now = (args.clock ?? wallClock)()\n validateTags(tags)\n // Resolve actor + grants together (one cached round-trip per client).\n // Caller can short-circuit by passing `access` (bench / impersonation\n // / preview). Caching lives in access.ts — same WeakMap pattern.\n const {actor, grants} = await resolveAccess(client, {\n ...(args.access !== undefined ? {override: args.access} : {}),\n ...(args.grantsFromPath !== undefined ? {grantsFromPath: args.grantsFromPath} : {}),\n })\n\n const instance = await client.getDocument<WorkflowInstance>(instanceId)\n if (!instance) {\n throw new Error(`Workflow instance \"${instanceId}\" not found`)\n }\n if (!tags.some((t) => instance.tags?.includes(t))) {\n throw new Error(`Workflow instance \"${instanceId}\" not visible to this engine (tag mismatch)`)\n }\n\n const definition = parseDefinitionSnapshot(instance)\n const clientForGdr =\n resourceClients !== undefined\n ? (parsed: ParsedGdr) => resourceClients(parsed) ?? client\n : () => client\n // Build the GDR-keyed snapshot ONCE; the pure evaluation threads it\n // through every filter check (groq-js, zero lake reads).\n const snapshot: HydratedSnapshot = await hydrateSnapshot({client, clientForGdr, instance})\n\n return evaluateFromSnapshot({\n instance,\n definition,\n actor,\n snapshot,\n now,\n ...(grants !== undefined ? {grants} : {}),\n })\n}\n\nexport interface EvaluateFromSnapshotArgs {\n instance: WorkflowInstance\n definition: WorkflowDefinition\n actor: Actor\n /**\n * Resolved grants for the actor. Omit to skip the `permission-denied`\n * gate (graceful degradation — the real lake write boundary still\n * enforces).\n */\n grants?: Grant[]\n /**\n * The in-memory snapshot to evaluate against. The caller assembles it\n * from whatever source — a fetch (see {@link evaluateInstance}) or a\n * live store. The `_id` of every doc must be in GDR-URI form, as\n * {@link buildSnapshot} produces.\n */\n snapshot: HydratedSnapshot\n /**\n * The `$now` reading every filter in this projection shares. Omit to\n * use {@link wallClock}; a reactive consumer (or the bench) passes its\n * own clock reading for a stable/deterministic timeline.\n */\n now?: string\n}\n\n/**\n * The pure projection at the heart of {@link evaluateInstance}: given an\n * instance, its definition, the resolved actor/grants, and a snapshot,\n * compute \"what can this actor do right now, and why not the rest.\" No\n * I/O — feed it a fresh snapshot (e.g. rebuilt from a live store on\n * change) for reactive re-evaluation. Best-effort by design: the lake's\n * mutation guards + ACL are the real enforcement.\n */\nexport async function evaluateFromSnapshot(\n args: EvaluateFromSnapshotArgs,\n): Promise<WorkflowEvaluation> {\n const {instance, definition, actor, grants, snapshot} = args\n const now = args.now ?? wallClock()\n const stage = definition.stages.find((s) => s.id === instance.currentStageId)\n if (stage === undefined) {\n throw new Error(\n `Instance \"${instance._id}\" currentStageId \"${instance.currentStageId}\" not in definition`,\n )\n }\n\n const currentTaskEntries = findOpenStageEntry(instance)?.tasks ?? []\n\n const taskEvaluations: TaskEvaluation[] = []\n for (const task of stage.tasks ?? []) {\n taskEvaluations.push(\n await evaluateTask({\n task,\n statusEntry: currentTaskEntries.find((t) => t.id === task.id),\n instance,\n definition,\n actor,\n grants,\n snapshot,\n now,\n }),\n )\n }\n\n const transitionEvaluations: TransitionEvaluation[] = []\n for (const transition of stage.transitions ?? []) {\n transitionEvaluations.push({\n transition,\n filterSatisfied: await evaluateFilter({\n filter: transition.filter,\n definition,\n snapshot,\n params: buildParams(instance, now),\n }),\n })\n }\n\n const currentStage: StageEvaluation = {\n stage,\n tasks: taskEvaluations,\n transitions: transitionEvaluations,\n }\n\n const pendingOnYou = taskEvaluations.filter((t) => t.pendingOnActor)\n const canInteract = taskEvaluations.some((t) => t.actions.some((a) => a.allowed))\n\n return {\n instance,\n definition,\n actor,\n currentStage,\n pendingOnYou,\n canInteract,\n }\n}\n\ninterface EvaluateTaskArgs {\n task: Task\n statusEntry: TaskEntry | undefined\n instance: WorkflowInstance\n definition: WorkflowDefinition\n actor: Actor\n grants: Grant[] | undefined\n snapshot: HydratedSnapshot\n now: string\n}\n\nasync function evaluateTask(args: EvaluateTaskArgs): Promise<TaskEvaluation> {\n const {task, statusEntry, instance, definition, actor, grants, snapshot, now} = args\n const status: TaskStatus = statusEntry?.status ?? 'pending'\n\n const actions: ActionEvaluation[] = []\n for (const action of task.actions ?? []) {\n actions.push(\n await evaluateAction({\n action,\n task,\n ...(statusEntry !== undefined ? {statusEntry} : {}),\n status,\n instance,\n definition,\n actor,\n ...(grants !== undefined ? {grants} : {}),\n snapshot,\n now,\n }),\n )\n }\n\n return {\n task,\n status,\n // \"pending on actor\" treats both `pending` and `active` as waiting on\n // the assignee — pending tasks just haven't been auto-invoked yet, but\n // they're still inbox items.\n pendingOnActor:\n (status === 'active' || status === 'pending') && actorIsAssignee(actor, task.assignees ?? []),\n actions,\n }\n}\n\n// Internal — per-action verdict\n\ninterface EvaluateActionArgs {\n action: Action\n task: Task\n statusEntry?: TaskEntry\n status: TaskStatus\n instance: WorkflowInstance\n definition: WorkflowDefinition\n actor: Actor\n grants?: Grant[]\n snapshot: HydratedSnapshot\n now: string\n}\n\nasync function evaluateAction(args: EvaluateActionArgs): Promise<ActionEvaluation> {\n const {action, task, status, instance, definition, actor, grants, snapshot, now} = args\n\n // Gates are checked in order; the first failing one wins. Order is\n // chosen so the most informative reason surfaces first (instance-level\n // → stage-level → task-level → actor-level → permission-level →\n // filter-level).\n const syncReason =\n lifecycleReason(instance, definition, status) ?? actorReason(action, task, actor)\n if (syncReason !== undefined) return disabled(action, syncReason)\n\n const asyncReason =\n (await permissionReason(action, instance, actor, grants)) ??\n (await filterReason(action, instance, definition, snapshot, now))\n if (asyncReason !== undefined) return disabled(action, asyncReason)\n\n return {action, allowed: true}\n}\n\nfunction lifecycleReason(\n instance: WorkflowInstance,\n definition: WorkflowDefinition,\n status: TaskStatus,\n): DisabledReason | undefined {\n if (instance.completedAt !== undefined) {\n return {kind: 'instance-completed', completedAt: instance.completedAt}\n }\n if (definition.stages.find((s) => s.id === instance.currentStageId)?.kind === 'terminal') {\n return {kind: 'stage-terminal', stageId: instance.currentStageId}\n }\n if (status === 'done' || status === 'skipped' || status === 'failed') {\n return {kind: 'task-not-active', status}\n }\n return undefined\n}\n\nfunction actorReason(action: Action, task: Task, actor: Actor): DisabledReason | undefined {\n const actorRoles = actor.roles ?? []\n if (action.roles !== undefined && action.roles.length > 0) {\n const wildcard = actorRoles.includes(WILDCARD_ROLE)\n const match = wildcard || action.roles.some((r) => actorRoles.includes(r))\n if (!match) {\n return {kind: 'role-required', required: [...action.roles], actorRoles: [...actorRoles]}\n }\n }\n if (action.requireAssignment === true && !actorIsAssignee(actor, task.assignees ?? [])) {\n return {kind: 'not-assigned', assignees: [...(task.assignees ?? [])], actorId: actor.id}\n }\n return undefined\n}\n\nasync function permissionReason(\n action: Action,\n instance: WorkflowInstance,\n actor: Actor,\n grants: Grant[] | undefined,\n): Promise<DisabledReason | undefined> {\n if (grants === undefined) return undefined\n const permission = action.requiredPermission ?? 'update'\n const allowed = await grantsPermissionOn({\n document: instance,\n grants,\n permission,\n userId: actor.id,\n })\n if (allowed) return undefined\n return {kind: 'permission-denied', permission, matchingGrants: grants.length}\n}\n\nasync function filterReason(\n action: Action,\n instance: WorkflowInstance,\n definition: WorkflowDefinition,\n snapshot: HydratedSnapshot,\n now: string,\n): Promise<DisabledReason | undefined> {\n if (action.filter === undefined) return undefined\n const truthy = await evaluateFilter({\n filter: action.filter,\n definition,\n snapshot,\n params: buildParams(instance, now),\n })\n if (truthy) return undefined\n return {kind: 'filter-failed', filter: action.filter}\n}\n\nfunction disabled(action: Action, reason: DisabledReason): ActionEvaluation {\n return {action, allowed: false, disabledReason: reason}\n}\n\n// Internal — actor / assignee helpers\n\nfunction actorIsAssignee(actor: Actor, assignees: Assignee[]): boolean {\n if (assignees.length === 0) return false\n const actorRoles = actor.roles ?? []\n const wildcard = actorRoles.includes(WILDCARD_ROLE)\n for (const assignee of assignees) {\n if (assignee.kind === 'user' && assignee.id === actor.id) return true\n if (assignee.kind === 'role') {\n if (wildcard || actorRoles.includes(assignee.role)) return true\n }\n }\n return false\n}\n\nexport function parseDefinitionSnapshot(instance: WorkflowInstance): WorkflowDefinition {\n try {\n return JSON.parse(instance.definitionSnapshot) as WorkflowDefinition\n } catch (err) {\n throw new Error(\n `Failed to parse definitionSnapshot on instance \"${instance._id}\": ${\n err instanceof Error ? err.message : String(err)\n }`,\n {cause: err},\n )\n }\n}\n","/**\n * Shell-side guard housekeeping reads. The engine never reads its guards back\n * during normal operation — these exist for coherency refresh and DX/cleanup.\n *\n * Scope applies the same \"if it's in the workflow, we pull it in\" principle as\n * {@link hydrateSnapshot}, but deliberately broader: it spans the resource the\n * instance lives in AND the resource of every `doc.ref` / `doc.refs` GDR the\n * instance holds in state across ALL stages — not just the current one as\n * snapshot hydration does. Retract lifts a guard's predicate rather than\n * deleting it, so prior-stage resources still hold guard docs that housekeeping\n * must find. We query each resource for guards stamped with this instance's\n * {@link MutationGuardDoc.sourceInstanceId}.\n */\n\nimport {parseGdr, type ParsedGdr, type WorkflowResource} from './core/refs.ts'\nimport {collectSlotDocUris, resourceFromParsed} from './snapshot.ts'\nimport {GUARD_DOC_TYPE, type MutationGuardDoc} from './types/authorization.ts'\nimport type {WorkflowClient} from './types/client.ts'\nimport type {WorkflowInstance} from './types/instance.ts'\n\nconst resourceKey = (r: WorkflowResource): string => `${r.type}.${r.id}`\n\n/** Every guard in one resource, regardless of which workflow registered it. */\nexport function guardsForResource(client: WorkflowClient): Promise<MutationGuardDoc[]> {\n return client.fetch<MutationGuardDoc[]>(`*[_type == $t] | order(_id asc)`, {t: GUARD_DOC_TYPE})\n}\n\nexport interface GuardsForInstanceArgs {\n client: WorkflowClient\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient\n instance: WorkflowInstance\n}\n\n/**\n * All guards this instance registered, unioned across every resource it\n * touches. Dedups resources by resource key and results by `_id`.\n */\nexport async function guardsForInstance(args: GuardsForInstanceArgs): Promise<MutationGuardDoc[]> {\n const {client, clientForGdr, instance} = args\n\n const clientsByResource = new Map<string, WorkflowClient>([\n [resourceKey(instance.workflowResource), client],\n ])\n\n const stateUris = [\n ...collectSlotDocUris(instance.state),\n ...instance.stages.flatMap((stage) => collectSlotDocUris(stage.state)),\n ]\n for (const uri of stateUris) {\n const parsed = tryParseGdr(uri)\n if (parsed === undefined) continue\n const key = resourceKey(resourceFromParsed(parsed))\n if (!clientsByResource.has(key)) clientsByResource.set(key, clientForGdr(parsed))\n }\n\n const perResource = await Promise.all(\n [...clientsByResource.values()].map((c) =>\n c.fetch<MutationGuardDoc[]>(`*[_type == $t && sourceInstanceId == $id]`, {\n t: GUARD_DOC_TYPE,\n id: instance._id,\n }),\n ),\n )\n\n return dedupById(perResource.flat())\n}\n\nfunction tryParseGdr(uri: string): ParsedGdr | undefined {\n try {\n return parseGdr(uri)\n } catch {\n return undefined\n }\n}\n\nfunction dedupById(guards: MutationGuardDoc[]): MutationGuardDoc[] {\n const byId = new Map(guards.map((g) => [g._id, g]))\n return [...byId.values()].sort((a, b) => a._id.localeCompare(b._id))\n}\n","import type {SanityDocument} from '@sanity/types'\n\nimport type {WorkflowResource} from '../core/refs.ts'\nimport type {WorkflowDefinition} from '../define/schema.ts'\nimport {definitionLookupGroq} from '../definition-query.ts'\nimport {canonicalTag} from '../tags.ts'\nimport type {WorkflowClient} from '../types/client.ts'\n\n/**\n * Mint the Sanity document `_id` for a workflow.definition. Bare form\n * — no GDR scheme prefix — because Sanity rejects `:` in document\n * IDs. Cross-resource references can construct the full GDR URI from\n * `(workflowResource, _id)` on demand.\n */\nexport function definitionDocId(\n _workflowResource: WorkflowResource,\n prefix: string,\n workflowId: string,\n version: number,\n): string {\n return `${prefix}.${workflowId}.v${version}`\n}\n\n/**\n * Topologically sort definitions so spawn-children land before their\n * parents. Refs pointing outside the batch are validated against the\n * lake — if a ref points neither to a doc in the batch nor to an\n * already-deployed definition, throw before any write.\n *\n * Cycles error.\n */\nexport async function sortByDependencies(\n client: WorkflowClient,\n definitions: WorkflowDefinition[],\n tags: string[],\n workflowResource: WorkflowResource,\n): Promise<WorkflowDefinition[]> {\n const prefix = canonicalTag(tags)\n // Track every workflowId in this batch + the versions per id. Logical\n // refs match on workflowId alone (or workflowId + version when explicit).\n const byWorkflowId = new Map<string, WorkflowDefinition[]>()\n for (const def of definitions) {\n const list = byWorkflowId.get(def.workflowId) ?? []\n list.push(def)\n byWorkflowId.set(def.workflowId, list)\n }\n const findInBatch = (ref: LogicalRef) => findRefInBatch(byWorkflowId, ref)\n\n await assertCrossBatchRefsDeployed(client, definitions, {\n tags,\n workflowResource,\n prefix,\n findInBatch,\n })\n\n return topoSortDefinitions(definitions, {workflowResource, prefix, findInBatch})\n}\n\ninterface LogicalRef {\n workflowId: string\n version?: number | 'latest'\n}\n\n/** Find the definition in the batch satisfying a logical ref: an exact\n * version match, or the highest version when the ref omits one. */\nfunction findRefInBatch(\n byWorkflowId: Map<string, WorkflowDefinition[]>,\n ref: LogicalRef,\n): WorkflowDefinition | undefined {\n const candidates = byWorkflowId.get(ref.workflowId)\n if (candidates === undefined || candidates.length === 0) return undefined\n if (typeof ref.version === 'number') return candidates.find((c) => c.version === ref.version)\n return candidates.reduce<WorkflowDefinition | undefined>(\n (best, c) => (best === undefined || c.version > best.version ? c : best),\n undefined,\n )\n}\n\n/**\n * For every spawn ref not satisfied within the batch, confirm a matching\n * `workflow.definition` is already deployed and visible to this engine's\n * tags. Throws listing every unresolved ref. No-op when all resolve.\n */\nasync function assertCrossBatchRefsDeployed(\n client: WorkflowClient,\n definitions: WorkflowDefinition[],\n ctx: {\n tags: string[]\n workflowResource: WorkflowResource\n prefix: string\n findInBatch: (ref: LogicalRef) => WorkflowDefinition | undefined\n },\n): Promise<void> {\n const missing: {from: string; ref: string}[] = []\n for (const def of definitions) {\n const fromId = definitionDocId(ctx.workflowResource, ctx.prefix, def.workflowId, def.version)\n for (const ref of refsOf(def)) {\n if (ctx.findInBatch(ref) !== undefined) continue // satisfied within batch\n const label = await resolveDeployedRefLabel(client, ref, ctx.tags)\n if (label !== undefined) missing.push({from: fromId, ref: label})\n }\n }\n if (missing.length === 0) return\n const lines = missing.map((m) => ` - ${m.from} → ${m.ref} (neither in batch nor deployed)`)\n throw new Error(\n `workflow.deployDefinitions: ${missing.length} unresolved reference${missing.length === 1 ? '' : 's'}:\\n` +\n lines.join('\\n'),\n )\n}\n\n/** Look up a logical ref in the lake. Returns undefined when a matching\n * deployed definition is visible to `tags`, or a human-readable label\n * for the unresolved ref otherwise. */\nasync function resolveDeployedRefLabel(\n client: WorkflowClient,\n ref: LogicalRef,\n tags: string[],\n): Promise<string | undefined> {\n const wantsExplicit = typeof ref.version === 'number'\n const params: Record<string, unknown> = {workflowId: ref.workflowId, engineTags: tags}\n if (wantsExplicit) params.version = ref.version\n const doc = await client.fetch<(SanityDocument & {tags?: string[]}) | null>(\n definitionLookupGroq(wantsExplicit),\n params,\n )\n if (doc) return undefined\n return wantsExplicit ? `${ref.workflowId} v${ref.version}` : ref.workflowId\n}\n\n/** Children-before-parents topological sort over in-batch spawn refs.\n * Throws on a dependency cycle. */\nfunction topoSortDefinitions(\n definitions: WorkflowDefinition[],\n ctx: {\n workflowResource: WorkflowResource\n prefix: string\n findInBatch: (ref: LogicalRef) => WorkflowDefinition | undefined\n },\n): WorkflowDefinition[] {\n const visited = new Set<string>()\n const visiting = new Set<string>()\n const ordered: WorkflowDefinition[] = []\n\n const visit = (def: WorkflowDefinition): void => {\n const id = definitionDocId(ctx.workflowResource, ctx.prefix, def.workflowId, def.version)\n if (visited.has(id)) return\n if (visiting.has(id)) {\n throw new Error(`workflow.deployDefinitions: dependency cycle involving \"${id}\"`)\n }\n visiting.add(id)\n for (const ref of refsOf(def)) {\n const child = ctx.findInBatch(ref)\n if (child !== undefined) visit(child)\n }\n visiting.delete(id)\n visited.add(id)\n ordered.push(def)\n }\n\n for (const def of definitions) visit(def)\n return ordered\n}\n\n// Collect every spawn ref a definition depends on as a logical\n// `{ workflowId, version? }` reference. Hoisted out of\n// sortByDependencies so it doesn't re-capture closure on each call.\nfunction refsOf(def: WorkflowDefinition): LogicalRef[] {\n const out: LogicalRef[] = []\n for (const stage of def.stages) {\n for (const task of stage.tasks ?? []) {\n const ref = task.spawns?.definitionRef\n if (ref !== undefined) {\n out.push({\n workflowId: ref.workflowId,\n ...(ref.version !== undefined ? {version: ref.version} : {}),\n })\n }\n }\n }\n return out\n}\n\n/**\n * Compare a deployed definition document to what we'd write next. Skip\n * Sanity-managed system fields (`_rev`, `_createdAt`, `_updatedAt`) —\n * those always differ. Everything else must match exactly for the\n * deploy to be a no-op.\n */\nexport function isDefinitionUnchanged(\n existing: Record<string, unknown>,\n expected: Record<string, unknown>,\n): boolean {\n return (\n stableStringify(stripSystemFields(existing)) === stableStringify(stripSystemFields(expected))\n )\n}\n\nexport function stripSystemFields(doc: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(doc)) {\n if (k === '_rev' || k === '_createdAt' || k === '_updatedAt') continue\n out[k] = v\n }\n return out\n}\n\n/**\n * Stable JSON.stringify with sorted keys so object key order can't\n * cause a false \"changed\" diff.\n */\nfunction stableStringify(value: unknown): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value)\n if (Array.isArray(value)) return `[${value.map(stableStringify).join(',')}]`\n const entries = Object.entries(value as Record<string, unknown>).toSorted(([a], [b]) =>\n a.localeCompare(b),\n )\n return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${stableStringify(v)}`).join(',')}}`\n}\n\nexport async function loadDefinition(\n client: WorkflowClient,\n workflowId: string,\n version: number | undefined,\n tags: string[],\n): Promise<WorkflowDefinition> {\n if (version !== undefined) {\n const doc = await client.fetch<(WorkflowDefinition & {tags?: string[]}) | null>(\n definitionLookupGroq(true),\n {workflowId, version, engineTags: tags},\n )\n if (!doc) {\n throw new Error(`Workflow definition ${workflowId} v${version} not deployed`)\n }\n return doc\n }\n const latest = await client.fetch<WorkflowDefinition | null>(definitionLookupGroq(false), {\n workflowId,\n engineTags: tags,\n })\n if (!latest) {\n throw new Error(`No deployed definition for workflow ${workflowId}`)\n }\n return latest\n}\n","import {getPath} from '../core/path.ts'\nimport {validateSlotAppendItem, validateSlotValue} from '../core/slot-validation.ts'\nimport {resolveStaticSource} from '../core/source.ts'\nimport type {Action, ActionParam, Op, OpPredicate, Source} from '../define/schema.ts'\nimport {randomKey} from '../keys.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {StateScope} from '../types/enums.ts'\nimport type {StageId, TaskId} from '../types/ids.ts'\nimport {findOpenStageEntry} from '../types/instance-state.ts'\nimport type {ResolvedStateSlot} from '../types/state-slots.ts'\nimport type {MutableInstance} from './mutation.ts'\nimport {ActionParamsInvalidError, type OpAppliedSummary} from './results.ts'\n\n// Action commit: param validation + op runner.\n\n/**\n * Op types that mutate workflow state (vs `workflow.op.status.set`, which only\n * flips task status). `satisfies` ties the list to the {@link Op} union, so a\n * rename or typo breaks compilation here instead of silently turning a\n * downstream state-change gate into a no-op.\n */\nconst STATE_OP_TYPES = [\n 'workflow.op.state.set',\n 'workflow.op.state.append',\n 'workflow.op.state.updateWhere',\n 'workflow.op.state.removeWhere',\n] as const satisfies readonly Op['type'][]\n\n/** Whether an applied op mutated state (and so may have invalidated a guard). */\nexport function isStateOp(summary: OpAppliedSummary): boolean {\n return (STATE_OP_TYPES as readonly string[]).includes(summary.opType)\n}\n\nexport function validateActionParams(\n action: Action,\n taskId: TaskId,\n callerParams: Record<string, unknown> | undefined,\n): Record<string, unknown> {\n const declared = action.params ?? []\n const params = callerParams ?? {}\n const issues: {paramId: string; reason: string}[] = []\n\n for (const decl of declared) {\n const value = params[decl.id]\n const present = decl.id in params && value !== undefined && value !== null\n if (decl.required === true && !present) {\n issues.push({paramId: decl.id, reason: 'required but missing'})\n continue\n }\n if (!present) continue\n const typeOk = checkParamType(value, decl)\n if (!typeOk) {\n issues.push({\n paramId: decl.id,\n reason: `expected paramType=${decl.paramType}, got ${typeof value}`,\n })\n }\n }\n if (issues.length > 0) {\n throw new ActionParamsInvalidError({action: action.id, taskId, issues})\n }\n return params\n}\n\n/** True when `value` is a non-null object carrying a string-typed `field`. */\nfunction hasStringField(value: unknown, field: string): boolean {\n return (\n typeof value === 'object' &&\n value !== null &&\n field in value &&\n typeof (value as Record<string, unknown>)[field] === 'string'\n )\n}\n\nfunction checkParamType(value: unknown, decl: ActionParam): boolean {\n switch (decl.paramType) {\n case 'string':\n case 'url':\n case 'dateTime':\n return typeof value === 'string'\n case 'number':\n return typeof value === 'number' && Number.isFinite(value)\n case 'boolean':\n return typeof value === 'boolean'\n case 'actor':\n return hasStringField(value, 'kind')\n case 'doc.ref':\n return hasStringField(value, 'id')\n case 'doc.refs':\n return (\n Array.isArray(value) &&\n value.every((v) => checkParamType(v, {...decl, paramType: 'doc.ref'}))\n )\n case 'json':\n return true\n default:\n return false\n }\n}\n\ninterface RunOpsArgs {\n ops: Op[] | undefined\n mutation: MutableInstance\n stageId: StageId\n taskId: TaskId\n actionName: string\n params: Record<string, unknown>\n actor: Actor | undefined\n /** GDR URI of the instance the ops run against, for `Source.self`. */\n self: string\n /** Shell-supplied clock reading (ISO) — `now` op-source + history `at`. */\n now: string\n}\n\nexport async function runActionOps(args: RunOpsArgs): Promise<OpAppliedSummary[]> {\n const {ops, mutation, stageId, taskId, actionName, params, actor, self, now} = args\n if (ops === undefined || ops.length === 0) return []\n const summaries: OpAppliedSummary[] = []\n for (const op of ops) {\n const summary = applyOp(op, {mutation, stageId, taskId, params, actor, self, now})\n summaries.push(summary)\n mutation.history.push({\n _key: randomKey(),\n _type: 'workflow.history.opApplied',\n at: now,\n stageId,\n taskId,\n actionId: actionName,\n opType: summary.opType,\n ...(summary.target !== undefined ? {target: summary.target} : {}),\n ...(summary.resolved !== undefined ? {resolved: summary.resolved} : {}),\n ...(actor !== undefined ? {actor} : {}),\n })\n }\n return summaries\n}\n\ninterface OpContext {\n mutation: MutableInstance\n stageId: StageId\n taskId: TaskId\n params: Record<string, unknown>\n actor: Actor | undefined\n /** GDR URI of the instance, for `Source.self`. */\n self: string\n /** Shell-supplied clock reading (ISO) backing `source: \"now\"`. */\n now: string\n}\n\nfunction applyOp(op: Op, ctx: OpContext): OpAppliedSummary {\n switch (op.type) {\n case 'workflow.op.state.set':\n return applyStateSet(op, ctx)\n case 'workflow.op.state.append':\n return applyStateAppend(op, ctx)\n case 'workflow.op.state.updateWhere':\n return applyStateUpdateWhere(op, ctx)\n case 'workflow.op.state.removeWhere':\n return applyStateRemoveWhere(op, ctx)\n case 'workflow.op.status.set':\n return applyStatusSet(op, ctx)\n }\n}\n\nfunction applyStateSet(\n op: Extract<Op, {type: 'workflow.op.state.set'}>,\n ctx: OpContext,\n): OpAppliedSummary {\n const value = resolveOpSource(op.value, ctx)\n const slot = locateSlot(ctx, op.target, /*createIfMissing*/ true)\n if (slot !== undefined) {\n // Validate the resolved value against the slot's declared shape.\n // Wrong-shape writes throw `SlotValueShapeError` — the engine\n // aborts the action before persisting.\n validateSlotValue({slotType: slot._type, slotId: slot.id, value})\n slot.value = value as never\n }\n return {opType: op.type, target: op.target, resolved: {value}}\n}\n\nfunction applyStateAppend(\n op: Extract<Op, {type: 'workflow.op.state.append'}>,\n ctx: OpContext,\n): OpAppliedSummary {\n const item = resolveOpSource(op.item, ctx)\n const slot = locateSlot(ctx, op.target, /*createIfMissing*/ true)\n if (slot !== undefined) {\n validateSlotAppendItem({slotType: slot._type, slotId: slot.id, item})\n const current = Array.isArray(slot.value) ? slot.value : []\n slot.value = [...current, withRowKey(item)] as never\n }\n return {opType: op.type, target: op.target, resolved: {item}}\n}\n\n/** Stamp a `_key` onto a plain-object row that lacks one; scalars and\n * arrays pass through unchanged. */\nfunction withRowKey(item: unknown): unknown {\n if (typeof item === 'object' && item !== null && !Array.isArray(item) && !('_key' in item)) {\n return {_key: randomKey(), ...(item as Record<string, unknown>)}\n }\n return item\n}\n\nfunction applyStateUpdateWhere(\n op: Extract<Op, {type: 'workflow.op.state.updateWhere'}>,\n ctx: OpContext,\n): OpAppliedSummary {\n const slot = locateSlot(ctx, op.target, /*createIfMissing*/ false)\n const resolvedMerge: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(op.merge)) {\n resolvedMerge[k] = resolveOpSource(v, ctx)\n }\n if (slot !== undefined && Array.isArray(slot.value)) {\n slot.value = (slot.value as Record<string, unknown>[]).map((row) =>\n evalOpPredicate(op.where, row, ctx) ? {...row, ...resolvedMerge} : row,\n ) as never\n }\n return {opType: op.type, target: op.target, resolved: {merge: resolvedMerge}}\n}\n\nfunction applyStateRemoveWhere(\n op: Extract<Op, {type: 'workflow.op.state.removeWhere'}>,\n ctx: OpContext,\n): OpAppliedSummary {\n const slot = locateSlot(ctx, op.target, /*createIfMissing*/ false)\n if (slot !== undefined && Array.isArray(slot.value)) {\n slot.value = (slot.value as Record<string, unknown>[]).filter(\n (row) => !evalOpPredicate(op.where, row, ctx),\n ) as never\n }\n return {opType: op.type, target: op.target}\n}\n\nfunction applyStatusSet(\n op: Extract<Op, {type: 'workflow.op.status.set'}>,\n ctx: OpContext,\n): OpAppliedSummary {\n const entry = findOpenStageEntry(ctx.mutation)?.tasks.find((t) => t.id === op.taskId)\n if (entry !== undefined) entry.status = op.status\n return {opType: op.type, resolved: {taskId: op.taskId, status: op.status}}\n}\n\nfunction locateSlot(\n ctx: OpContext,\n target: {scope: StateScope; slotId: string},\n createIfMissing: boolean,\n): ResolvedStateSlot | undefined {\n let host: ResolvedStateSlot[] | undefined\n if (target.scope === 'workflow') {\n host = ctx.mutation.state\n } else if (target.scope === 'stage') {\n host = findOpenStageEntry(ctx.mutation)?.state\n } else {\n const task = findOpenStageEntry(ctx.mutation)?.tasks.find((t) => t.id === ctx.taskId)\n host = task?.state\n if (host === undefined && task !== undefined && createIfMissing) {\n task.state = []\n host = task.state\n }\n }\n if (host === undefined) {\n throw new Error(\n `Op target scope \"${target.scope}\" has no state container on this instance — declare the slot or check stage/task identity`,\n )\n }\n let slot = host.find((s) => s.id === target.slotId)\n if (slot === undefined && createIfMissing) {\n // No declared slot — synthesize a `value.string`-shaped entry as a\n // conservative default. Authors are expected to declare slots on\n // the definition; this fallback exists so ad-hoc tests don't have\n // to.\n slot = {\n _key: randomKey(),\n _type: 'workflow.state.value.string',\n id: target.slotId,\n value: null,\n } as ResolvedStateSlot\n host.push(slot)\n }\n return slot\n}\n\nfunction resolveOpSource(src: Source, ctx: OpContext): unknown {\n const staticValue = resolveStaticSource(src, ctx)\n if (staticValue.handled) return staticValue.value\n switch (src.source) {\n case 'self':\n // The instance's own GDR URI — matches `$self` in filters and\n // `Source.self` in spawn sources. A GDR string an op can stamp into\n // a value slot (or compose via `Source.object`), instead of the old\n // silent `undefined`.\n return ctx.self\n case 'stageId':\n return ctx.stageId\n case 'stateRead': {\n const value = readSlotFromMutation(ctx, src.scope, src.slotId)\n return src.path !== undefined ? getPath(value, src.path) : value\n }\n case 'effectOutput': {\n const entry = ctx.mutation.effectsContext.find((e) => e.id === src.contextId)\n if (entry === undefined) return null\n const v = src.path !== undefined ? getPath(entry.value, src.path) : entry.value\n return v === undefined ? null : v\n }\n case 'object': {\n const out: Record<string, unknown> = {}\n for (const [field, fieldSrc] of Object.entries(src.fields)) {\n out[field] = resolveOpSource(fieldSrc, ctx)\n }\n return out\n }\n case 'row':\n case 'parentState':\n // Spawn-only sources (resolved by resolveSpawnSource); not in scope here.\n return undefined\n default:\n // literal / param / actor / now resolved above by resolveStaticSource.\n return undefined\n }\n}\n\nfunction slotValue(slots: ResolvedStateSlot[] | undefined, slotId: string): unknown {\n return slots?.find((s) => s.id === slotId)?.value\n}\n\nfunction readSlotFromMutation(ctx: OpContext, scope: StateScope, slotId: string): unknown {\n if (scope === 'workflow') return slotValue(ctx.mutation.state, slotId)\n const stageEntry = findOpenStageEntry(ctx.mutation)\n if (scope === 'stage') return slotValue(stageEntry?.state, slotId)\n const task = stageEntry?.tasks.find((t) => t.id === ctx.taskId)\n return slotValue(task?.state, slotId)\n}\n\nfunction evalOpPredicate(p: OpPredicate, row: Record<string, unknown>, ctx: OpContext): boolean {\n if ('all' in p) return p.all.every((sub) => evalOpPredicate(sub, row, ctx))\n if ('any' in p) return p.any.some((sub) => evalOpPredicate(sub, row, ctx))\n const target = resolveOpSource(p.equals, ctx)\n return row[p.field] === target\n}\n","import {selfGdr} from '../core/refs.ts'\nimport type {Action, Stage, Task} from '../define/schema.ts'\nimport {randomKey} from '../keys.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {TaskStatus} from '../types/enums.ts'\nimport type {StageId, TaskId} from '../types/ids.ts'\nimport type {TaskEntry} from '../types/instance-state.ts'\nimport {ctxEvaluateFilter, type EngineContext, loadContext} from './context.ts'\nimport {queueEffects} from './effects.ts'\nimport {\n findCurrentTasks,\n findTaskInCurrentStage,\n type MutableInstance,\n requireMutationTaskEntry,\n startMutation,\n taskStatusChangedEntry,\n} from './mutation.ts'\nimport {isStateOp, runActionOps, validateActionParams} from './ops.ts'\nimport {\n type ActionResult,\n CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS,\n ConcurrentFireActionError,\n type EngineCallOptions,\n isRevisionConflict,\n} from './results.ts'\nimport {persistThenDeploy, refreshStageGuards} from './stages.ts'\n\n/**\n * Fire an action against an active task. The runtime applies the\n * declared `setStatus` flip and queues the action's effects.\n *\n * Each attempt reloads the instance (fresh `_rev`) and commits through\n * `persist`'s `ifRevisionId` guard, so two clients firing the same task\n * can't silently clobber each other. A commit that loses the race\n * reloads and retries across {@link CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS} attempts,\n * then throws {@link ConcurrentFireActionError}. Reloading also re-gates\n * the action, so a retry whose task the winning writer already completed\n * fails with the normal \"task must be active\" error rather than retrying.\n */\nexport async function fireAction(args: {\n client: WorkflowClient\n instanceId: string\n taskId: TaskId\n action: string\n /** Caller-supplied action params (validated against `Action.params[]`). */\n params?: Record<string, unknown>\n options?: EngineCallOptions\n}): Promise<ActionResult> {\n const {client, instanceId, taskId, action, params, options} = args\n for (let attempt = 1; attempt <= CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS; attempt++) {\n const ctx = await loadContext(client, instanceId, {\n ...(options?.clock ? {clock: options.clock} : {}),\n })\n try {\n return await commitAction(ctx, taskId, action, params, options?.actor)\n } catch (error) {\n if (!isRevisionConflict(error)) throw error\n // Lost the optimistic-locking race — reload and retry.\n }\n }\n throw new ConcurrentFireActionError({\n instanceId,\n taskId,\n action,\n attempts: CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS,\n })\n}\n\n/**\n * Resolve and gate an action fire: locate the task + action in the\n * current stage, check the action filter, require the live task entry to\n * be `active`, and validate caller params. Throws on any failure so no\n * mutation begins. Returns the pieces the commit needs.\n */\nasync function resolveActionCommit(\n ctx: EngineContext,\n taskId: TaskId,\n actionName: string,\n callerParams: Record<string, unknown> | undefined,\n): Promise<{stage: Stage; task: Task; action: Action; params: Record<string, unknown>}> {\n const {stage, task} = findTaskInCurrentStage(ctx, taskId)\n const action = (task.actions ?? []).find((a) => a.id === actionName)\n if (action === undefined) {\n throw new Error(`Action \"${actionName}\" not declared on task \"${taskId}\"`)\n }\n\n const filterOk = await ctxEvaluateFilter(ctx, action.filter)\n if (!filterOk) {\n throw new Error(`Action \"${actionName}\" filter rejected on task \"${taskId}\"`)\n }\n\n const entry = findCurrentTasks(ctx.instance).find((t) => t.id === taskId)\n if (entry === undefined || entry.status !== 'active') {\n throw new Error(\n `Task \"${taskId}\" must be active to fire action \"${actionName}\"; status is ${entry?.status ?? 'missing'}`,\n )\n }\n\n // Validate caller params against `action.params[]` before any\n // mutation. The action does not commit if validation fails.\n const params = validateActionParams(action, taskId, callerParams)\n return {stage, task, action, params}\n}\n\n/** Apply an action's declared `setStatus` to the live task entry,\n * recording the status change. No-op (returns undefined) when the\n * action omits `setStatus` — e.g. claim/assign actions that keep the\n * task active. Returns the new status when applied. */\nfunction applyActionSetStatus(\n action: Action,\n mutation: MutableInstance,\n mutEntry: TaskEntry,\n stageId: StageId,\n taskId: TaskId,\n actor: Actor | undefined,\n now: string,\n): TaskStatus | undefined {\n if (action.setStatus === undefined) return undefined\n const initialStatus = mutEntry.status\n const newStatus = action.setStatus\n mutEntry.status = newStatus\n mutEntry.completedAt = now\n if (actor) mutEntry.completedBy = actor.id\n mutation.history.push(\n taskStatusChangedEntry({\n stageId,\n taskId,\n from: initialStatus,\n to: newStatus,\n at: now,\n ...(actor !== undefined ? {actor} : {}),\n }),\n )\n return newStatus\n}\n\nasync function commitAction(\n ctx: EngineContext,\n taskId: TaskId,\n actionName: string,\n callerParams: Record<string, unknown> | undefined,\n actor: Actor | undefined,\n): Promise<ActionResult> {\n const {stage, task, action, params} = await resolveActionCommit(\n ctx,\n taskId,\n actionName,\n callerParams,\n )\n\n const mutation = startMutation(ctx.instance)\n const mutEntry = requireMutationTaskEntry(mutation, taskId)\n // One clock reading for the whole commit so the actionFired entry, ops,\n // status flip, and queued effects all agree on the time.\n const now = ctx.now\n\n // 1. Action commit: record the actionFired entry first so ops/effects\n // have a consistent audit trail order.\n mutation.history.push({\n _key: randomKey(),\n _type: 'workflow.history.actionFired',\n at: now,\n stageId: stage.id,\n taskId,\n actionId: actionName,\n ...(actor !== undefined ? {actor} : {}),\n })\n\n // 2. Run ops inline. Sources resolve against the in-progress\n // mutation so a later op can read a value an earlier op wrote.\n // Ops can flip task status via `workflow.op.status.set`.\n const ranOps = await runActionOps({\n ops: action.ops,\n mutation,\n stageId: stage.id,\n taskId,\n actionName,\n params,\n actor,\n self: selfGdr(ctx.instance),\n now,\n })\n\n // 3. Apply the action's declared `setStatus`, if any.\n const newStatus = applyActionSetStatus(action, mutation, mutEntry, stage.id, taskId, actor, now)\n\n // 4. Queue external effects with resolved Sources (caller params +\n // actor pinned for this commit).\n await queueEffects(\n ctx,\n mutation,\n action.effects,\n {\n kind: 'action',\n id: `${task.id}:${actionName}`,\n },\n actor,\n params,\n )\n\n // Ops may have changed state a guard reads; refresh this stage's guards so\n // they stay coherent without a transition (skipped when no state op ran). A\n // failed refresh rolls the commit back rather than leaving guards stale.\n await persistThenDeploy(ctx, mutation, () =>\n ranOps.some(isStateOp) ? refreshStageGuards(ctx, mutation, stage.id) : Promise.resolve(),\n )\n\n return {\n fired: true,\n taskId,\n action: actionName,\n ...(newStatus !== undefined ? {newStatus} : {}),\n ...(ranOps.length > 0 ? {ranOps} : {}),\n }\n}\n","// Workflow evaluation — the third concept. Derived projection of\n// (instance + definition + actor + grants + lake state) answering\n// \"what can this actor do right now, and why not the rest?\".\n//\n// Not stored. Computed by `workflow.evaluate`. Different actors see\n// different evaluations of the same instance.\n\nimport type {\n Action,\n Assignee,\n Filter,\n Stage,\n Task,\n Transition,\n WorkflowDefinition,\n} from '../define/schema.ts'\nimport type {Actor} from './actor.ts'\nimport type {DocumentValuePermission, TaskStatus} from './enums.ts'\nimport type {ActionName, StageId, TaskId} from './ids.ts'\nimport type {WorkflowInstance} from './instance.ts'\n\nexport type DisabledReason =\n | {\n kind: 'role-required'\n required: string[]\n actorRoles: string[]\n }\n | {\n kind: 'not-assigned'\n assignees: Assignee[]\n actorId: string\n }\n | {\n kind: 'permission-denied'\n permission: DocumentValuePermission\n matchingGrants: number\n }\n | {\n kind: 'filter-failed'\n filter: Filter\n detail?: string\n }\n | {\n kind: 'task-not-active'\n status: Exclude<TaskStatus, 'active' | 'pending'>\n }\n | {kind: 'stage-terminal'; stageId: StageId}\n | {kind: 'instance-completed'; completedAt: string}\n | {\n /**\n * A deployed lake mutation guard denied (or, in optimistic engine-side\n * preview, would deny) the write. Surfacing this is an engine *preview* —\n * not proof of lake enforcement.\n */\n kind: 'mutation-guard-denied'\n guardIds: string[]\n detail?: string\n }\n\nexport interface ActionEvaluation {\n action: Action\n allowed: boolean\n /** Present iff `allowed === false`. The first failing gate wins. */\n disabledReason?: DisabledReason\n}\n\nexport interface TaskEvaluation {\n task: Task\n status: TaskStatus\n /** Whether this task is the current actor's responsibility right now. */\n pendingOnActor: boolean\n actions: ActionEvaluation[]\n}\n\nexport interface TransitionEvaluation {\n transition: Transition\n /** Result of evaluating the transition's filter at read time. */\n filterSatisfied: boolean\n}\n\nexport interface StageEvaluation {\n stage: Stage\n tasks: TaskEvaluation[]\n transitions: TransitionEvaluation[]\n}\n\nexport interface WorkflowEvaluation {\n instance: WorkflowInstance\n definition: WorkflowDefinition\n actor: Actor\n currentStage: StageEvaluation\n /** Active tasks where the actor is in `task.assignees`. */\n pendingOnYou: TaskEvaluation[]\n /** True if at least one action on any active task is allowed. */\n canInteract: boolean\n}\n\n// Typed error thrown by fireAction when the requested action's verdict\n// is `allowed: false`. Carries the structured reason so UIs can render\n// a precise message instead of parsing a string.\n\nexport class ActionDisabledError extends Error {\n readonly reason: DisabledReason\n readonly taskId: TaskId\n readonly action: ActionName\n\n constructor(args: {taskId: TaskId; action: ActionName; reason: DisabledReason}) {\n super(formatDisabledReason(args.taskId, args.action, args.reason))\n this.name = 'ActionDisabledError'\n this.reason = args.reason\n this.taskId = args.taskId\n this.action = args.action\n }\n}\n\ntype DisabledReasonDetail = {\n [K in DisabledReason['kind']]: (reason: Extract<DisabledReason, {kind: K}>) => string\n}\n\nconst disabledReasonDetail: DisabledReasonDetail = {\n 'role-required': (r) =>\n `requires one of [${r.required.join(', ')}]; actor has [${r.actorRoles.join(', ') || '(none)'}]`,\n 'not-assigned': (r) => `actor \"${r.actorId}\" is not in the task assignees`,\n 'permission-denied': (r) => `actor lacks \"${r.permission}\" permission on the workflow instance`,\n 'filter-failed': (r) => `action filter returned false${r.detail ? ` (${r.detail})` : ''}`,\n 'task-not-active': (r) => `task status is \"${r.status}\"`,\n 'stage-terminal': (r) => `stage \"${r.stageId}\" is terminal`,\n 'instance-completed': (r) => `instance completed at ${r.completedAt}`,\n 'mutation-guard-denied': (r) =>\n `blocked by mutation guard(s) [${r.guardIds.join(', ')}]${r.detail ? ` (${r.detail})` : ''}`,\n}\n\nfunction formatDisabledReason(taskId: TaskId, action: ActionName, reason: DisabledReason): string {\n const detail = (disabledReasonDetail[reason.kind] as (r: DisabledReason) => string)(reason)\n return `Action \"${taskId}:${action}\" is not allowed: ${detail}`\n}\n","import {resolveAccess, type WorkflowAccessOverride} from '../access.ts'\nimport type {Clock} from '../clock.ts'\nimport {extractDocumentId, type GlobalDocumentReference, type ParsedGdr} from '../core/refs.ts'\nimport type {LoadedDoc} from '../core/snapshot.ts'\nimport {fireAction as engineFireAction} from '../engine/actions.ts'\nimport {cascadeAutoTransitions, propagateToAncestors} from '../engine/cascade.ts'\nimport {invokeTask as engineInvokeTask} from '../engine/tasks.ts'\nimport {effectsContextEntry} from '../instance.ts'\nimport {validateTags} from '../tags.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {EffectsContextEntry} from '../types/effects.ts'\nimport {ActionDisabledError, type WorkflowEvaluation} from '../types/evaluation.ts'\nimport {findOpenStageEntry} from '../types/instance-state.ts'\nimport type {WorkflowInstance} from '../types/instance.ts'\nimport type {ResourceClientResolver} from './types.ts'\n\n// Internal helpers\n\n/**\n * Resolve a spawn `instanceRef.id` to the bare doc `_id` used by GROQ.\n * A misconfigured caller could write a malformed GDR URI into history;\n * {@link extractDocumentId} throws on those, so skip them (return no id)\n * instead of crashing the whole {@link workflow.children} call.\n */\nexport function bareIdFromSpawnRef(uri: string): string[] {\n if (!uri.includes(':')) return [uri]\n try {\n return [extractDocumentId(uri)]\n } catch {\n return []\n }\n}\n\n/**\n * Shared verb preamble: validate tags, resolve the calling actor from\n * the access override (or the client's token), and build the\n * cross-resource routing function. Every `workflow.*` verb opens this\n * way.\n */\nexport async function resolveOperationContext(args: {\n client: WorkflowClient\n tags: string[]\n resourceClients?: ResourceClientResolver\n access?: WorkflowAccessOverride\n grantsFromPath?: string\n}): Promise<{\n access: Awaited<ReturnType<typeof resolveAccess>>\n actor: Awaited<ReturnType<typeof resolveAccess>>['actor']\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient\n}> {\n validateTags(args.tags)\n const access = await resolveAccess(args.client, {\n ...(args.access !== undefined ? {override: args.access} : {}),\n ...(args.grantsFromPath !== undefined ? {grantsFromPath: args.grantsFromPath} : {}),\n })\n return {\n access,\n actor: access.actor,\n clientForGdr: buildClientForGdr(args.client, args.resourceClients),\n }\n}\n\nexport async function cascade(\n client: WorkflowClient,\n instanceId: string,\n actor: Actor | undefined,\n clientForGdr?: (parsed: ParsedGdr) => WorkflowClient,\n clock?: Clock,\n overlay?: ReadonlyMap<string, LoadedDoc>,\n): Promise<number> {\n // The overlay is this instance's held content — pass it only to the\n // instance's own cascade. Ancestor propagation operates on other\n // instances with their own content, so it must refetch (no overlay).\n const count = await cascadeAutoTransitions(\n client,\n instanceId,\n actor,\n clientForGdr,\n clock,\n overlay,\n )\n await propagateToAncestors(client, instanceId, actor, clientForGdr, clock)\n return count\n}\n\n/**\n * Build the routing function from a resolver. Falls back to using the\n * default client when the resolver is absent or returns undefined.\n */\nexport function buildClientForGdr(\n defaultClient: WorkflowClient,\n resolver: ResourceClientResolver | undefined,\n): (parsed: ParsedGdr) => WorkflowClient {\n if (resolver === undefined) return () => defaultClient\n return (parsed) => resolver(parsed) ?? defaultClient\n}\n\nexport async function reload(\n client: WorkflowClient,\n instanceId: string,\n tags: string[],\n): Promise<WorkflowInstance> {\n const doc = await client.getDocument<WorkflowInstance>(instanceId)\n if (!doc) throw new Error(`Workflow instance ${instanceId} not found`)\n if (!intersectsTags(doc.tags, tags)) {\n throw new Error(`Workflow instance ${instanceId} not visible to this engine (tag mismatch)`)\n }\n return doc\n}\n\nexport function intersectsTags(\n docTags: string[] | undefined | null,\n engineTags: string[],\n): boolean {\n if (!docTags || docTags.length === 0) return false\n return engineTags.some((t) => docTags.includes(t))\n}\n\nexport function toEffectsContextEntries(\n ctx: Record<string, string | number | boolean | GlobalDocumentReference>,\n): EffectsContextEntry[] {\n return Object.entries(ctx).map(([id, value]) => effectsContextEntry(id, value))\n}\n\n/**\n * Soft-gate before any action write: throw {@link ActionDisabledError} if the\n * evaluation says the action is disabled. The lake mutation boundary is the\n * real enforcement; this surfaces a structured `reason` to the caller first.\n */\nexport function assertActionAllowed(\n evaluation: WorkflowEvaluation,\n taskId: string,\n action: string,\n): void {\n const actionEval = evaluation.currentStage.tasks\n .find((t) => t.task.id === taskId)\n ?.actions.find((a) => a.action.id === action)\n if (actionEval?.allowed === false && actionEval.disabledReason) {\n throw new ActionDisabledError({taskId, action, reason: actionEval.disabledReason})\n }\n}\n\n/**\n * Auto-invoke the task if it's still pending, then fire the action. Both the\n * `pending` check ({@link findOpenStageEntry}) and the fire operate on the\n * supplied instance; returns the action's `ranOps` (if any).\n */\nexport async function applyAction(args: {\n client: WorkflowClient\n instance: WorkflowInstance\n taskId: string\n action: string\n params?: Record<string, unknown>\n actor: Actor\n clock?: Clock\n}): Promise<Awaited<ReturnType<typeof engineFireAction>>['ranOps']> {\n const {client, instance, taskId, action, params, actor, clock} = args\n const options = {actor, ...(clock !== undefined ? {clock} : {})}\n const pending =\n findOpenStageEntry(instance)?.tasks.find((t) => t.id === taskId)?.status === 'pending'\n if (pending) {\n await engineInvokeTask({client, instanceId: instance._id, taskId, options})\n }\n const result = await engineFireAction({\n client,\n instanceId: instance._id,\n taskId,\n action,\n ...(params !== undefined ? {params} : {}),\n options,\n })\n return result.ranOps\n}\n","/**\n * The workflow API — a single coherent SDK surface, five methods.\n *\n * The model:\n *\n * - **`deployDefinition`** — once at deploy time. Persists the definition.\n * - **`startInstance`** — once per workflow run. Pins a snapshot, seeds\n * `effectsContext` (stable params for effect handlers), enters the\n * initial stage. Cascades.\n * - **`fireAction`** — the universal \"something happened\" call. Editors\n * fire actions on tasks. Runtimes fire actions on tasks in response\n * to webhooks, timer firings, etc. External signals funnel through\n * this; nothing else.\n * - **`completeEffect`** — the runtime reports a queued effect's\n * outcome. Optionally carries `outputs` that get merged into\n * `effectsContext` so a downstream effect's bindings can reference\n * them (effect chains). The only path that mutates `effectsContext`\n * after start.\n * - **`tick`** — re-evaluate auto-transitions and resolve due waits.\n * Used after any change that might unblock a filter: a content\n * mutation in the lake, a timer crossing a `completeWhen` deadline,\n * a sibling workflow completing, etc. The runtime decides which\n * instances might need a tick; the engine just re-evaluates.\n *\n * What's NOT in the API:\n *\n * - No `requestTransition`. Workflow authors should not have a way to\n * \"force\" a stage transition outside of filters firing. If you want\n * \"cancel from anywhere,\" model cancellation as a task with an action\n * that flips it to `failed`, plus an auto-transition filtered on\n * `anyTaskFailed`. Same audit trail as everything else; same\n * mechanism.\n * - No `setContext`. `effectsContext` is set at start, then mutated\n * only by completed effects' `outputs`. External signals belong on\n * tasks (via `fireAction`) or in the lake (as document mutations\n * that filters can read).\n * - No `invokeTask`. Tasks auto-activate on stage entry. Editor's first\n * `fireAction` against a pending task auto-invokes it before\n * applying the action.\n *\n * What filters can read:\n *\n * - Task state on the instance (`*[_id == $self][0].stages[id == $stage && !defined(exitedAt)][0].tasks[...]`)\n * - Document content in the lake (`*[_type == \"...\" && ...]`)\n * - Reserved params: `$self`, `$subject`, `$parent`, `$ancestors`, `$now`\n *\n * What filters must NOT read:\n *\n * - `effectsContext`. That field is for effect handler params only.\n *\n * The boundary keeps each thing doing one job: tasks are workflow state,\n * the lake is content state, effectsContext is handler fuel.\n */\n\nimport type {SanityDocument} from '@sanity/types'\nimport {evaluate as evaluateGroq, parse as parseGroq} from 'groq-js'\n\nimport {type Clocked, wallClock} from '../clock.ts'\nimport {buildParams} from '../core/params.ts'\nimport type {WorkflowResource} from '../core/refs.ts'\nimport {\n WORKFLOW_DEFINITION_TYPE,\n type StateSlot,\n type WorkflowDefinition,\n} from '../define/schema.ts'\nimport {primeInitialStage} from '../engine/cascade.ts'\nimport {completeEffect as engineCompleteEffect} from '../engine/effects.ts'\nimport {setStage as engineSetStage} from '../engine/stages.ts'\nimport {type EvaluateArgs, evaluateInstance} from '../evaluate.ts'\nimport {guardsForInstance as queryGuardsForInstance} from '../guards-query.ts'\nimport {buildInstanceBase} from '../instance.ts'\nimport {randomKey} from '../keys.ts'\nimport {\n fetchGrants as permFetchGrants,\n grantsPermissionOn as permGrantsPermissionOn,\n matchesFilter as permMatchesFilter,\n} from '../permissions.ts'\nimport {hydrateSnapshot} from '../snapshot.ts'\nimport {derivePerspectiveFromState, resolveDeclaredState} from '../state-resolution.ts'\nimport {canonicalTag, tagScopeFilter, validateTags} from '../tags.ts'\nimport type {MutationGuardDoc} from '../types/authorization.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {PendingEffect} from '../types/effects.ts'\nimport type {WorkflowEvaluation} from '../types/evaluation.ts'\nimport type {HistoryEntry} from '../types/history.ts'\nimport {findOpenStageEntry} from '../types/instance-state.ts'\nimport type {WorkflowInstance} from '../types/instance.ts'\nimport {\n definitionDocId,\n isDefinitionUnchanged,\n loadDefinition,\n sortByDependencies,\n} from './deploy.ts'\nimport {\n applyAction,\n assertActionAllowed,\n bareIdFromSpawnRef,\n buildClientForGdr,\n cascade,\n intersectsTags,\n reload,\n resolveOperationContext,\n toEffectsContextEntries,\n} from './operations.ts'\nimport type {\n CompleteEffectArgs,\n DeployDefinitionResult,\n DeployDefinitionsArgs,\n DeployDefinitionsResult,\n DispatchResult,\n FireActionArgs,\n OperationArgs,\n ResourceClientResolver,\n SetStageArgs,\n StartInstanceArgs,\n} from './types.ts'\nimport {validateDefinition} from './validate.ts'\n\n/**\n * The four-method workflow API.\n */\nexport const workflow = {\n /**\n * Persist a workflow definition to the lake. Stored as a\n * `workflow.definition` document with id\n * `workflow.definition.<workflowId>.v<version>`. Subsequent versions\n * are stored alongside earlier ones — `startInstance` picks the\n * highest version by default.\n */\n /**\n * Deploy a set of workflow definitions as one call. The SDK figures\n * out the dependency order itself (children before parents that spawn\n * them via `task.spawns.definitionRef`), idempotently writes any\n * definition whose content has changed, and reports a per-definition\n * outcome (`created` / `updated` / `unchanged`).\n *\n * Refs may point inside the batch OR at already-deployed definitions\n * in the lake — both are valid. A ref pointing at neither errors with\n * a clear message naming the missing target.\n *\n * Cycles in the dependency graph error before any write happens.\n */\n deployDefinitions: async (args: DeployDefinitionsArgs): Promise<DeployDefinitionsResult> => {\n const {client, tags, workflowResource, definitions} = args\n validateTags(tags)\n\n // 1. Validate each definition's GROQ + structural invariants\n // individually. Fail fast before we touch the lake.\n for (const def of definitions) {\n validateDefinition(def)\n }\n\n // 2. Build the dependency graph and topologically sort.\n // Children-before-parents; refs pointing outside the batch are\n // validated against the lake once.\n const ordered = await sortByDependencies(client, definitions, tags, workflowResource)\n\n // 3. Compare against the existing doc to skip unchanged definitions,\n // then write everything that DID change in a single same-resource\n // transaction. All-or-nothing — if one definition's rev check\n // fails, none of the batch lands.\n const results: DeployDefinitionResult[] = []\n const prefix = canonicalTag(tags)\n const tx = client.transaction()\n let hasWrites = false\n for (const def of ordered) {\n const id = definitionDocId(workflowResource, prefix, def.workflowId, def.version)\n const expected = {\n ...def,\n _id: id,\n _type: WORKFLOW_DEFINITION_TYPE,\n tags,\n }\n // `getDocument` returns the doc, or null/undefined when missing\n // (different clients return different falsy sentinels). Use a\n // truthy check rather than `=== null` to cover both.\n const existing = await client.getDocument<typeof expected & SanityDocument>(id)\n if (\n existing &&\n intersectsTags(existing.tags, tags) &&\n isDefinitionUnchanged(existing, expected)\n ) {\n results.push({workflowId: def.workflowId, version: def.version, status: 'unchanged'})\n continue\n }\n if (existing) {\n // Patch with rev check — fail fast if another deploy raced us.\n //\n // `set()` is a *partial* update: it overwrites the listed fields\n // but leaves any extra top-level fields untouched. That's wrong\n // for definition deploys, where a schema change can rename or\n // drop a field (e.g. `name` → `title`) and stale values would\n // otherwise linger on the deployed doc forever. Compute the\n // top-level keys that exist on `existing` but not on `expected`\n // and chain an `.unset()` so the deployed shape matches source.\n // Sanity-managed `_*` fields stay (we can't unset them anyway).\n const expectedKeys = new Set(Object.keys(expected))\n const toUnset = Object.keys(existing).filter(\n (k) => !k.startsWith('_') && !expectedKeys.has(k),\n )\n const patch = client.patch(id).set(expected).ifRevisionId(existing._rev)\n if (toUnset.length > 0) patch.unset(toUnset)\n tx.patch(patch)\n } else {\n // Net-new — `create` errors on collision instead of clobbering.\n tx.create(expected)\n }\n hasWrites = true\n results.push({\n workflowId: def.workflowId,\n version: def.version,\n status: existing ? 'updated' : 'created',\n })\n }\n if (hasWrites) await tx.commit()\n\n return {results}\n },\n\n /**\n * Spawn a new workflow instance from a deployed definition.\n *\n * Pins the snapshot at start-time, seeds `effectsContext`, enters\n * the initial stage (which builds taskStatus, queues onEnter\n * effects, auto-activates tasks). Then cascades auto-transitions\n * until stable. Returns the resulting instance.\n */\n startInstance: async (args: Clocked<StartInstanceArgs>): Promise<WorkflowInstance> => {\n const {\n client,\n tags,\n workflowResource,\n workflowId,\n version,\n initialState,\n ancestors,\n effectsContext,\n instanceId,\n perspective,\n } = args\n const {actor, clientForGdr} = await resolveOperationContext(args)\n const clock = args.clock ?? wallClock\n\n const definition = await loadDefinition(client, workflowId, version, tags)\n // Bare `_id` — Sanity rejects `:` in document IDs, so we don't\n // use a GDR URI here. Cross-resource references build the GDR\n // URI from `(workflowResource, _id)` on demand.\n const id = instanceId ?? `${canonicalTag(tags)}.wf-instance.${randomKey()}`\n\n const initialStage = definition.stages.find((s) => s.id === definition.initialStageId)\n if (initialStage === undefined) {\n throw new Error(\n `Initial stage \"${definition.initialStageId}\" missing in ${workflowId} v${definition.version}`,\n )\n }\n\n const now = clock()\n const effectsContextEntries = effectsContext ? toEffectsContextEntries(effectsContext) : []\n // Workflow-scope state slots resolve in declaration order. Later\n // slots can read earlier ones via `$state.<slotId>` in their GROQ.\n // There's no privileged slot name — `$state` exposes every\n // declared slot keyed by its author-chosen id.\n const resolvedState = await resolveDeclaredState({\n slotDefs: (definition as WorkflowDefinition & {state?: StateSlot[]}).state ?? [],\n initialState: initialState ?? [],\n ctx: {\n client,\n now,\n selfId: id,\n tags,\n workflowResource,\n ...(perspective !== undefined ? {perspective} : {}),\n },\n randomKey,\n })\n\n // Perspective resolution: an explicit `perspective` arg wins;\n // otherwise derive it from a populated `release.ref` slot. This is\n // what makes a release-targeting workflow self-describing — the\n // caller fills the slot and the engine figures out the read\n // perspective, rather than every caller having to pass it.\n const effectivePerspective = perspective ?? derivePerspectiveFromState(resolvedState)\n\n const base = buildInstanceBase({\n id,\n now,\n tags,\n workflowResource,\n workflowId: definition.workflowId,\n pinnedVersion: definition.version,\n definition,\n state: resolvedState,\n effectsContext: effectsContextEntries,\n ancestors: ancestors ?? [],\n perspective: effectivePerspective,\n initialStageId: definition.initialStageId,\n actor,\n })\n // Net-new doc: `create` errors loud if `_id` collides instead of\n // silently wiping an existing instance. Use the caller-supplied\n // `instanceId` at your own risk — collisions surface here.\n await client.create(base)\n\n await primeInitialStage(client, id, actor, clientForGdr, clock)\n await cascade(client, id, actor, clientForGdr, clock)\n\n return reload(client, id, tags)\n },\n\n /**\n * Fire an action against a task. If the task is pending, it is\n * auto-invoked first (pending → active) so callers don't have to know\n * the lifecycle. Cascades auto-transitions and propagates to ancestors\n * after the action commits.\n *\n * This is the universal \"something happened\" call. Editors fire it.\n * Runtimes fire it in response to webhooks, effect completions, and\n * timer firings. External signals never bypass this.\n */\n fireAction: async (args: Clocked<FireActionArgs>): Promise<DispatchResult> => {\n const {\n client,\n tags,\n workflowResource,\n instanceId,\n taskId,\n action,\n params,\n idempotent,\n resourceClients,\n } = args\n const {access, actor, clientForGdr} = await resolveOperationContext(args)\n const clock = args.clock ?? wallClock\n\n const before = await reload(client, instanceId, tags)\n const taskEntry = findOpenStageEntry(before)?.tasks.find((t) => t.id === taskId)\n if (taskEntry === undefined && idempotent === true) {\n return {instance: before, cascaded: 0, fired: false}\n }\n\n // Soft-gate via evaluation. We project the instance from the\n // actor's perspective and check the requested action's verdict\n // before invoking the engine. If denied, the structured\n // ActionDisabledError surfaces `reason` directly.\n //\n // Reuse the already-resolved `access` (no second token/grant\n // round-trip) by passing it through as the override.\n const evaluation = await evaluateInstance({\n client,\n tags,\n workflowResource,\n instanceId,\n access,\n clock,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n })\n assertActionAllowed(evaluation, taskId, action)\n\n const ranOps = await applyAction({\n client,\n instance: before,\n taskId,\n action,\n actor,\n clock,\n ...(params !== undefined ? {params} : {}),\n })\n\n const cascaded = await cascade(client, instanceId, actor, clientForGdr, clock)\n return {\n instance: await reload(client, instanceId, tags),\n cascaded,\n fired: true,\n ...(ranOps !== undefined ? {ranOps} : {}),\n }\n },\n\n /**\n * Report a queued effect's outcome. Drains it from `pendingEffects`,\n * appends an `effectHistory` entry, and (if `outputs` are supplied\n * and the effect succeeded) upserts those values into\n * `effectsContext` by key — so downstream effect bindings can\n * reference them. Cascades after.\n */\n completeEffect: async (args: Clocked<CompleteEffectArgs>): Promise<DispatchResult> => {\n const {client, tags, instanceId, effectKey, status, outputs, detail, error, durationMs} = args\n const {actor, clientForGdr} = await resolveOperationContext(args)\n const clock = args.clock ?? wallClock\n await engineCompleteEffect({\n client,\n instanceId,\n effectKey,\n status,\n ...(outputs !== undefined ? {outputs} : {}),\n ...(detail !== undefined ? {detail} : {}),\n ...(error !== undefined ? {error} : {}),\n ...(durationMs !== undefined ? {durationMs} : {}),\n options: {...(actor !== undefined ? {actor} : {}), clock},\n })\n const cascaded = await cascade(client, instanceId, actor, clientForGdr, clock)\n return {\n instance: await reload(client, instanceId, tags),\n cascaded,\n fired: true,\n }\n },\n\n /**\n * Re-evaluate auto-transitions and resolve due waits until stable.\n *\n * Used by the runtime after any event that might affect the workflow\n * but isn't itself a task action: a subject doc was patched, a sibling\n * workflow completed, the clock crossed a `completeWhen` deadline, etc.\n * The runtime doesn't need to know what changed — it just nudges\n * affected instances and the engine re-evaluates.\n */\n tick: async (args: Clocked<OperationArgs>): Promise<DispatchResult> => {\n const {client, tags, instanceId} = args\n const {actor, clientForGdr} = await resolveOperationContext(args)\n const clock = args.clock ?? wallClock\n await reload(client, instanceId, tags)\n const cascaded = await cascade(client, instanceId, actor, clientForGdr, clock)\n return {\n instance: await reload(client, instanceId, tags),\n cascaded,\n fired: cascaded > 0,\n }\n },\n\n /**\n * Admin override — force the instance into `targetStageId` regardless\n * of filters or declared transitions. ACL gating should be enforced\n * upstream; this verb performs the mechanical move.\n */\n setStage: async (args: Clocked<SetStageArgs>): Promise<DispatchResult> => {\n const {client, tags, instanceId, targetStageId, reason} = args\n const {actor, clientForGdr} = await resolveOperationContext(args)\n const clock = args.clock ?? wallClock\n await reload(client, instanceId, tags)\n const result = await engineSetStage({\n client,\n instanceId,\n targetStageId,\n ...(reason !== undefined ? {reason} : {}),\n options: {...(actor !== undefined ? {actor} : {}), clock},\n })\n const cascaded = result.fired\n ? await cascade(client, instanceId, actor, clientForGdr, clock)\n : 0\n return {\n instance: await reload(client, instanceId, tags),\n cascaded,\n fired: result.fired,\n }\n },\n\n /**\n * Fetch a workflow instance by id, scoped to the engine's tags.\n * Throws when the instance doesn't exist or isn't visible to this\n * engine.\n */\n getInstance: async (args: {\n client: WorkflowClient\n tags: string[]\n workflowResource: WorkflowResource\n instanceId: string\n }): Promise<WorkflowInstance> => {\n const {client, tags, instanceId} = args\n validateTags(tags)\n return reload(client, instanceId, tags)\n },\n\n guardsForInstance: async (args: {\n client: WorkflowClient\n tags: string[]\n workflowResource: WorkflowResource\n instanceId: string\n resourceClients?: ResourceClientResolver\n }): Promise<MutationGuardDoc[]> => {\n const {client, tags, instanceId, resourceClients} = args\n validateTags(tags)\n const instance = await reload(client, instanceId, tags)\n return queryGuardsForInstance({\n client,\n clientForGdr: buildClientForGdr(client, resourceClients),\n instance,\n })\n },\n\n /**\n * Run a caller-supplied GROQ query with the engine's tags bound as\n * `$engineTags`. This does NOT rewrite the query — arbitrary GROQ\n * can't be safely tag-scoped after the fact — so the CALLER MUST\n * filter on `$engineTags` (e.g.\n * `count(tags[@ in $engineTags]) > 0`). To guard against accidental\n * cross-tenant reads, a query that never references `$engineTags` is\n * rejected before it reaches the lake. Caller is responsible for type\n * narrowing the result.\n */\n query: async <T = unknown>(args: {\n client: WorkflowClient\n tags: string[]\n workflowResource: WorkflowResource\n groq: string\n params?: Record<string, unknown>\n }): Promise<T> => {\n const {client, tags, groq, params} = args\n validateTags(tags)\n if (!groq.includes('$engineTags')) {\n throw new Error(\n `workflow.query: query must filter on $engineTags to stay tag-scoped (e.g. \"count(tags[@ in $engineTags]) > 0\"); got: ${groq}`,\n )\n }\n return client.fetch<T>(groq, {...params, engineTags: tags})\n },\n\n /**\n * Snapshot-aware GROQ — runs against the same in-memory view that\n * filters see for a given instance.\n *\n * Hydrates the instance's snapshot (instance + subject + ancestors\n * + every doc declared by a `doc.ref` / `doc.refs` slot in scope),\n * then evaluates the supplied GROQ in groq-js against that dataset.\n * Reserved params are auto-bound: `$self`, `$subject`, `$parent`,\n * `$ancestors`, `$stage`, `$now` — all in GDR URI form to match the\n * snapshot's keying.\n *\n * Use when an external consumer (a UI, a debug pane, a test) wants\n * to ask \"what does the engine see for this workflow right now?\"\n * without re-implementing hydration. Pure read — never writes.\n */\n queryInScope: async <T = unknown>(\n args: Clocked<{\n client: WorkflowClient\n tags: string[]\n workflowResource: WorkflowResource\n resourceClients?: ResourceClientResolver\n instanceId: string\n groq: string\n params?: Record<string, unknown>\n }>,\n ): Promise<T> => {\n const {client, tags, instanceId, groq, params, resourceClients} = args\n const clock = args.clock ?? wallClock\n validateTags(tags)\n const instance = await reload(client, instanceId, tags)\n const clientForGdr = buildClientForGdr(client, resourceClients)\n const snapshot = await hydrateSnapshot({client, clientForGdr, instance})\n const reserved = buildParams(instance, clock())\n const tree = parseGroq(groq, {params: {...reserved, ...params}})\n const evaluated = await evaluateGroq(tree, {\n dataset: snapshot.docs,\n params: {...reserved, ...params},\n })\n return (await evaluated.get()) as T\n },\n\n /**\n * List every pending effect on the instance. Returns the same entries\n * the runtime would see — claimed and unclaimed alike.\n */\n listPendingEffects: async (args: {\n client: WorkflowClient\n tags: string[]\n workflowResource: WorkflowResource\n instanceId: string\n }): Promise<PendingEffect[]> => {\n const inst = await reload(args.client, args.instanceId, args.tags)\n return inst.pendingEffects\n },\n\n /**\n * Filter pending effects on the instance by criteria. `claimed`\n * filters on claim presence; `names` restricts to specific effect\n * names. Both filters compose (AND).\n */\n findPendingEffects: async (args: {\n client: WorkflowClient\n tags: string[]\n workflowResource: WorkflowResource\n instanceId: string\n claimed?: boolean\n names?: string[]\n }): Promise<PendingEffect[]> => {\n const inst = await reload(args.client, args.instanceId, args.tags)\n return inst.pendingEffects.filter((e) => {\n if (args.claimed === true && e.claim === undefined) return false\n if (args.claimed === false && e.claim !== undefined) return false\n if (args.names !== undefined && !args.names.includes(e.effectId)) return false\n return true\n })\n },\n\n /**\n * Project the instance from a given actor's perspective. Returns a\n * `WorkflowEvaluation` with per-action verdicts (`allowed` + a\n * structured `disabledReason`). Pure read; never writes.\n *\n * Used by UIs to render disabled-with-reason buttons and by\n * `fireAction` to gate writes via the same logic.\n */\n evaluate: async (args: Clocked<EvaluateArgs>): Promise<WorkflowEvaluation> => {\n return evaluateInstance(args)\n },\n\n /**\n * Materialised spawned children of a parent instance.\n *\n * Walks `history` for `workflow.history.spawned` events — the durable\n * record. (The per-task `spawnedInstances` field on the active stage\n * only exists while that stage is current; history survives.) Strips\n * the GDR URI on each `instanceRef` to a bare `_id`, fetches the\n * instances, drops any that aren't visible to this engine's tags, and\n * returns them sorted by `startedAt` ascending.\n *\n * Pass `taskId` to restrict to a single spawning task on the parent.\n */\n children: async (args: {\n client: WorkflowClient\n tags: string[]\n workflowResource: WorkflowResource\n instanceId: string\n taskId?: string\n }): Promise<WorkflowInstance[]> => {\n const {client, tags, instanceId, taskId} = args\n validateTags(tags)\n const parent = await reload(client, instanceId, tags)\n const isSpawned = (\n h: HistoryEntry,\n ): h is Extract<HistoryEntry, {_type: 'workflow.history.spawned'}> =>\n h._type === 'workflow.history.spawned'\n const ids = parent.history\n .filter(isSpawned)\n .filter((h) => taskId === undefined || h.taskId === taskId)\n .flatMap((h) => bareIdFromSpawnRef(h.instanceRef.id))\n if (ids.length === 0) return []\n // Single GROQ — server-side filters by id set + engine tags, sorts\n // by startedAt. Beats N `getDocument` roundtrips for fan-outs.\n //\n // Visibility: this assumes spawn writes were committed with default\n // `visibility: \"sync\"` (which is what @sanity/client does and what\n // the engine relies on everywhere else). If a write path ever opts\n // into `async`, this query will silently miss freshly-spawned\n // children — but every other GROQ in the engine has the same\n // assumption, so we're not making things worse here.\n return client.fetch<WorkflowInstance[]>(\n `*[_id in $ids && ${tagScopeFilter()}] | order(startedAt asc)`,\n {ids, engineTags: tags},\n )\n },\n\n /**\n * Permission helpers — Sanity ACL grants evaluated against documents\n * via GROQ. Used by `workflow.evaluate` to soft-gate actions when the\n * caller supplies grants.\n */\n permissions: {\n matchesFilter: permMatchesFilter,\n grantsPermissionOn: permGrantsPermissionOn,\n fetchGrants: permFetchGrants,\n },\n}\n","import type {WorkflowAccessOverride} from '../access.ts'\nimport type {GlobalDocumentReference, WorkflowResource} from '../core/refs.ts'\nimport {WORKFLOW_DEFINITION_TYPE, type Effect, type WorkflowDefinition} from '../define/schema.ts'\nimport {isRevisionConflict} from '../engine/results.ts'\nimport {tagScopeFilter, validateTags} from '../tags.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {PendingEffect} from '../types/effects.ts'\nimport type {WorkflowInstance} from '../types/instance.ts'\nimport {reload} from './operations.ts'\nimport type {\n DrainEffectsResult,\n EffectHandler,\n EngineLogger,\n LoggerFactory,\n MissingHandlerDeployInfo,\n MissingHandlerInfo,\n MissingHandlerPolicy,\n ResourceClientResolver,\n VerifyDeployedDefinitionsResult,\n} from './types.ts'\nimport {workflow} from './workflow.ts'\n\nexport async function verifyDeployedDefinitionsInternal(args: {\n client: WorkflowClient\n tags: string[]\n effectHandlers: Record<string, EffectHandler>\n missingHandler: MissingHandlerPolicy\n logger: LoggerFactory\n}): Promise<VerifyDeployedDefinitionsResult> {\n const {client, tags, effectHandlers, missingHandler, logger} = args\n validateTags(tags)\n const log = logger('verifyDeployedDefinitions')\n const definitions = await client.fetch<(WorkflowDefinition & {_id: string})[]>(\n `*[_type == \"${WORKFLOW_DEFINITION_TYPE}\" && ${tagScopeFilter()}] | order(workflowId asc, version asc)`,\n {engineTags: tags},\n )\n\n const seen: {workflowId: string; version: number; _id: string}[] = []\n const missingByName = new Map<string, {definitionId: string; locations: Set<string>}>()\n for (const def of definitions) {\n seen.push({workflowId: def.workflowId, version: def.version, _id: def._id})\n walkEffectNames(def, (name, location) => {\n if (effectHandlers[name] !== undefined) return\n const key = `${name}@@${def._id}`\n let bucket = missingByName.get(key)\n if (bucket === undefined) {\n bucket = {definitionId: def._id, locations: new Set()}\n missingByName.set(key, bucket)\n }\n bucket.locations.add(location)\n })\n }\n\n const missing: VerifyDeployedDefinitionsResult['missing'] = []\n for (const [key, bucket] of missingByName.entries()) {\n const name = key.split('@@')[0]!\n missing.push({\n name,\n definitionId: bucket.definitionId,\n locations: [...bucket.locations].toSorted(),\n })\n }\n\n for (const m of missing) {\n const info: MissingHandlerDeployInfo = {\n phase: 'deploy',\n name: m.name,\n locations: m.locations,\n definitionId: m.definitionId,\n }\n const verdict = await applyMissingHandler(missingHandler, info, log)\n if (verdict === 'fail') {\n throw new Error(\n `verifyDeployedDefinitions: missing handler for \"${m.name}\" referenced by ${m.definitionId} at ${m.locations.join(', ')}`,\n )\n }\n }\n\n return {definitions: seen, missing}\n}\n\n/** Walk every external effect reference in a definition, invoking the\n * visitor with each name + a structural location string. */\nfunction walkEffectNames(\n def: WorkflowDefinition & {_id?: string},\n visit: (id: string, location: string) => void,\n): void {\n const visitEffects = (effects: Effect[] | undefined, location: string) => {\n for (const e of effects ?? []) visit(e.id, location)\n }\n for (const stage of def.stages ?? []) {\n visitEffects(stage.onEnter, `stage[${stage.id}].onEnter`)\n visitEffects(stage.onExit, `stage[${stage.id}].onExit`)\n for (const t of stage.tasks ?? []) {\n visitEffects(t.effects, `stage[${stage.id}].task[${t.id}].effects`)\n for (const a of t.actions ?? []) {\n visitEffects(a.effects, `stage[${stage.id}].task[${t.id}].action[${a.id}].effects`)\n }\n }\n for (const tr of stage.transitions ?? []) {\n visitEffects(tr.effects, `stage[${stage.id}].transition[${tr.to}].effects`)\n }\n }\n}\n\n// drainEffects — three-write claim protocol per pending entry.\n//\n// 1. CLAIM: load instance (rev R0). Stamp `claim` on an unclaimed entry.\n// Persist via patch().set().ifRevisionId(R0). On rev mismatch\n// (someone else committed), restart and pick a different entry.\n// 2. DISPATCH: invoke the registered handler in a try/catch.\n// 3. COMPLETE: call `completeEffect` which moves the entry from\n// `pendingEffects[]` to `effectHistory[]` and cascades.\n//\n// Returns drained / failed / skipped buckets. Skipped means missing\n// handler (subject to the engine's missingHandler policy).\n\nexport async function drainEffectsInternal(args: {\n client: WorkflowClient\n tags: string[]\n workflowResource: WorkflowResource\n resourceClients?: ResourceClientResolver\n instanceId: string\n effectHandlers: Record<string, EffectHandler>\n missingHandler: MissingHandlerPolicy\n logger: LoggerFactory\n /** Identity override for the drainer. Defaults to a system actor. */\n access?: WorkflowAccessOverride\n}): Promise<DrainEffectsResult> {\n const {\n client,\n tags,\n workflowResource,\n resourceClients,\n instanceId,\n effectHandlers,\n missingHandler,\n logger,\n } = args\n const drainerActor: Actor = args.access?.actor ?? {kind: 'system', id: 'engine.drainEffects'}\n // The completion call goes through workflow.completeEffect which\n // also accepts WorkflowAccessOverride; we hand it the drainer's\n // identity (override.actor or the system fallback) and pass any\n // explicit grants through verbatim.\n const completionAccess: WorkflowAccessOverride = {\n actor: drainerActor,\n ...(args.access?.grants !== undefined ? {grants: args.access.grants} : {}),\n }\n validateTags(tags)\n const log = logger('drainEffects')\n const drained: PendingEffect[] = []\n const failed: PendingEffect[] = []\n const skipped: PendingEffect[] = []\n // Keys of entries we've decided to skip (missing handler, policy\n // allows). We never claim them, so a plain `continue` would re-pick\n // the same entry forever — exclude them from the candidate search so\n // later entries that DO have handlers still drain.\n const skippedKeys = new Set<string>()\n\n while (true) {\n const before = await reload(client, instanceId, tags)\n const candidate = before.pendingEffects.find(\n (e) => e.claim === undefined && !skippedKeys.has(e._key),\n )\n if (candidate === undefined) break\n\n const handler = effectHandlers[candidate.effectId]\n if (handler === undefined) {\n await assertSkippableOrThrow(missingHandler, candidate, instanceId, log)\n skipped.push(candidate)\n skippedKeys.add(candidate._key)\n continue\n }\n\n const claimed = await claimPendingEffect(client, before, candidate._key, drainerActor)\n if (!claimed) continue // 409 — re-read and retry a fresh candidate.\n\n const {outputs, dispatchError} = await dispatchEffect(handler, candidate, {\n client,\n instanceId,\n logger,\n })\n\n await reportEffectOutcome({\n client,\n tags,\n workflowResource,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n instanceId,\n effectKey: candidate._key,\n access: completionAccess,\n outputs,\n dispatchError,\n })\n\n if (dispatchError === undefined) drained.push(candidate)\n else failed.push(candidate)\n }\n\n return {drained, failed, skipped}\n}\n\n/** Report a dispatched effect's outcome through `workflow.completeEffect`,\n * translating the dispatch result into the `done`/`failed` status +\n * optional outputs/error the API expects. */\nasync function reportEffectOutcome(args: {\n client: WorkflowClient\n tags: string[]\n workflowResource: WorkflowResource\n resourceClients?: ResourceClientResolver\n instanceId: string\n effectKey: string\n access: WorkflowAccessOverride\n outputs: Record<string, string | number | boolean | GlobalDocumentReference> | undefined\n dispatchError: {message: string; stack?: string} | undefined\n}): Promise<void> {\n const {outputs, dispatchError, resourceClients, ...rest} = args\n await workflow.completeEffect({\n ...rest,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n status: dispatchError === undefined ? 'done' : 'failed',\n ...(outputs !== undefined ? {outputs} : {}),\n ...(dispatchError !== undefined ? {error: dispatchError} : {}),\n })\n}\n\n/** Apply the missing-handler policy to an unhandled candidate. Throws\n * when the policy resolves to `fail`; returns when the entry may be\n * skipped. */\nasync function assertSkippableOrThrow(\n missingHandler: MissingHandlerPolicy,\n candidate: PendingEffect,\n instanceId: string,\n log: EngineLogger,\n): Promise<void> {\n const policyResult = await applyMissingHandler(\n missingHandler,\n {phase: 'drain', name: candidate.effectId, effectKey: candidate._key, instanceId},\n log,\n )\n if (policyResult === 'fail') {\n throw new Error(\n `drainEffects: no handler registered for \"${candidate.effectId}\" (effectKey=${candidate._key}, instanceId=${instanceId})`,\n )\n }\n}\n\n/**\n * Claim a single pending entry by stamping `claim` conditional on the\n * instance's current `_rev`. Returns false on a 409 rev mismatch (a\n * concurrent writer raced us) so the caller re-reads and retries.\n */\nasync function claimPendingEffect(\n client: WorkflowClient,\n instance: WorkflowInstance,\n effectKey: string,\n drainerActor: Actor,\n): Promise<boolean> {\n const claim = {\n _type: 'workflow.pendingEffect.claim' as const,\n claimedAt: new Date().toISOString(),\n claimedBy: drainerActor,\n }\n try {\n await client\n .patch(instance._id)\n .ifRevisionId(instance._rev)\n .set({[`pendingEffects[_key==\"${effectKey}\"].claim`]: claim})\n .commit()\n return true\n } catch (error) {\n // Only a lost rev race means \"another drainer claimed it\" — re-read and\n // try a fresh candidate. A real error (network, malformed patch) must\n // surface rather than masquerade as a benign claim miss.\n if (!isRevisionConflict(error)) throw error\n return false\n }\n}\n\n/** Invoke a handler, capturing its `outputs` or shaping a thrown error\n * into the `{message, stack?}` envelope `completeEffect` expects. */\nasync function dispatchEffect(\n handler: EffectHandler,\n candidate: PendingEffect,\n ctx: {client: WorkflowClient; instanceId: string; logger: LoggerFactory},\n): Promise<{\n outputs?: Record<string, string | number | boolean | GlobalDocumentReference>\n dispatchError?: {message: string; stack?: string}\n}> {\n try {\n const result = await handler(candidate.params, {\n client: ctx.client,\n instanceId: ctx.instanceId,\n effectKey: candidate._key,\n log: (message, extra) => ctx.logger(`effect.${candidate.effectId}`).info(message, extra),\n })\n return result?.outputs !== undefined ? {outputs: result.outputs} : {}\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n const stack = err instanceof Error && err.stack !== undefined ? err.stack : undefined\n return {dispatchError: stack !== undefined ? {message, stack} : {message}}\n }\n}\n\nasync function applyMissingHandler(\n policy: MissingHandlerPolicy,\n info: MissingHandlerInfo,\n log: EngineLogger,\n): Promise<'fail' | 'skip'> {\n if (policy === 'fail') return 'fail'\n if (policy === 'skip') {\n log.warn(`Missing effect handler \"${info.name}\" — skipping`, {info})\n return 'skip'\n }\n try {\n await policy(info)\n return 'skip'\n } catch {\n return 'fail'\n }\n}\n","/**\n * Reactive instance session — the engine held \"live\" on document state the\n * consumer pushes. Opt in with `engine.instance(instanceDoc)`. The session\n * holds the instance + an owned content snapshot you {@link InstanceSession.update};\n * `evaluate`/`tick`/`fireAction` run against the held state — content you've\n * pushed is never refetched.\n *\n * Observation-agnostic: the consumer (Studio / SDK / a Function) observes in\n * its own store semantics and feeds values in via `update`. The session never\n * subscribes and never ticks on its own.\n *\n * Discipline:\n * - `update` is **last-write-wins**, scoped to the watch-set: it replaces the\n * held content (deep-copied → decoupled from the consumer's live objects),\n * and a self-doc updates the held instance.\n * - It is **gated**: an `update` that arrives while a `tick`/`fireAction` is\n * committing is buffered and applied once the commit settles (single-writer).\n * - Each operation **captures** the held content at entry and runs against\n * that snapshot for its whole duration — no mutation or field-swap leaks in.\n * - `tick`/`fireAction` commit through the lake (`ifRevisionId` + guards); a\n * conflict surfaces (no internal retry). The instance reloads its own writes;\n * only content comes from the overlay.\n */\n\nimport type {SanityDocument} from '@sanity/types'\n\nimport {resolveAccess, type WorkflowAccessOverride} from '../access.ts'\nimport type {Clock} from '../clock.ts'\nimport {gdrFromResource} from '../core/refs.ts'\nimport {buildSnapshot, type HydratedSnapshot, type LoadedDoc} from '../core/snapshot.ts'\nimport {evaluateFromSnapshot, parseDefinitionSnapshot} from '../evaluate.ts'\nimport {subscriptionDocumentsForInstance, type WatchSet} from '../subscription-documents.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {Grant} from '../types/authorization.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {WorkflowEvaluation} from '../types/evaluation.ts'\nimport type {WorkflowInstance} from '../types/instance.ts'\nimport {applyAction, assertActionAllowed, buildClientForGdr, cascade, reload} from './operations.ts'\nimport type {DispatchResult, ResourceClientResolver} from './types.ts'\n\nexport interface InstanceSession {\n /** The watch-set to feed via {@link InstanceSession.update}, derived from the\n * held instance. Recompute after the instance changes (a new stage changes it). */\n readonly subscriptionDocuments: WatchSet\n /** Replace the held content with the current values the consumer observed\n * (last-write-wins, scoped). A doc whose id is the instance itself updates\n * the held instance. Buffered if a commit is in flight. */\n update(docs: LoadedDoc[]): void\n /** Best-effort projection against the held content. No network (async only\n * because filter evaluation runs on groq-js). */\n evaluate(): Promise<WorkflowEvaluation>\n /** Advance the instance against the held content: cascade auto-transitions,\n * deploy guards, queue effects, commit with `ifRevisionId`. */\n tick(): Promise<DispatchResult>\n /** Fire an action against a task, gated on the held content, then cascade. */\n fireAction(args: {\n taskId: string\n action: string\n params?: Record<string, unknown>\n }): Promise<DispatchResult>\n}\n\nexport interface CreateInstanceSessionArgs {\n client: WorkflowClient\n tags: string[]\n instance: WorkflowInstance\n resourceClients?: ResourceClientResolver\n /** Resolved actor/grants. Omit to token-resolve from the client. */\n access?: WorkflowAccessOverride\n grantsFromPath?: string\n /** Clock for `$now` / time-based filters; omit for wall-clock. The bench\n * passes a frozen clock for deterministic reactive evaluation. */\n clock?: Clock\n}\n\nexport function createInstanceSession(args: CreateInstanceSessionArgs): InstanceSession {\n const {client, tags, clock} = args\n const clientForGdr = buildClientForGdr(client, args.resourceClients)\n\n // Held state. Validate at construction the same way `update` validates a\n // pushed self-doc — the instance often comes from a consumer's live store\n // (a reactive adapter), so a malformed doc must fail hard here too.\n let instance = asHeldInstance(args.instance)\n let overlay = new Map<string, LoadedDoc>()\n // Single-writer gate: an update that lands during a commit is buffered\n // (last-write-wins — only the newest buffered set matters) and applied when\n // the commit settles.\n let committing = false\n let buffered: LoadedDoc[] | undefined\n\n const selfUri = (): string => gdrFromResource(instance.workflowResource, instance._id)\n\n const applyUpdate = (docs: LoadedDoc[]): void => {\n const next = new Map<string, LoadedDoc>()\n for (const ld of docs) {\n // Deep-copy so the held content is decoupled from the consumer's live\n // store objects — a later mutation there can't leak into an operation.\n const owned: LoadedDoc = {doc: structuredClone(ld.doc), resource: ld.resource}\n const uri = gdrFromResource(owned.resource, owned.doc._id)\n if (uri === selfUri()) {\n instance = asHeldInstance(owned.doc)\n continue\n }\n next.set(uri, owned)\n }\n overlay = next\n }\n\n const access = (): Promise<{actor: Actor; grants?: Grant[]}> =>\n resolveAccess(client, {\n ...(args.access !== undefined ? {override: args.access} : {}),\n ...(args.grantsFromPath !== undefined ? {grantsFromPath: args.grantsFromPath} : {}),\n })\n\n const snapshotFrom = (held: ReadonlyMap<string, LoadedDoc>): HydratedSnapshot =>\n buildSnapshot({docs: [{doc: instance, resource: instance.workflowResource}, ...held.values()]})\n\n const evaluateWith = async (\n held: ReadonlyMap<string, LoadedDoc>,\n ): Promise<WorkflowEvaluation> => {\n const {actor, grants} = await access()\n return evaluateFromSnapshot({\n instance,\n definition: parseDefinitionSnapshot(instance),\n actor,\n snapshot: snapshotFrom(held),\n ...(clock !== undefined ? {now: clock()} : {}),\n ...(grants !== undefined ? {grants} : {}),\n })\n }\n\n // Run a commit single-writer: capture the held content, hold it for the whole\n // op, buffer any concurrent update, apply the buffered one when done.\n const commit = async (\n run: (actor: Actor, held: ReadonlyMap<string, LoadedDoc>) => Promise<DispatchResult>,\n ): Promise<DispatchResult> => {\n committing = true\n const held = new Map(overlay)\n try {\n const {actor} = await access()\n return await run(actor, held)\n } finally {\n committing = false\n if (buffered !== undefined) {\n const next = buffered\n buffered = undefined\n applyUpdate(next)\n }\n }\n }\n\n return {\n get subscriptionDocuments() {\n return subscriptionDocumentsForInstance(instance)\n },\n\n update(docs) {\n if (committing) {\n buffered = docs\n return\n }\n applyUpdate(docs)\n },\n\n evaluate() {\n return evaluateWith(overlay)\n },\n\n tick() {\n return commit(async (actor, held) => {\n const cascaded = await cascade(client, instance._id, actor, clientForGdr, clock, held)\n instance = await reload(client, instance._id, tags)\n return {instance, cascaded, fired: cascaded > 0}\n })\n },\n\n fireAction({taskId, action, params}) {\n return commit(async (actor, held) => {\n // Soft-gate on the held content — the same projection the UI rendered.\n assertActionAllowed(await evaluateWith(held), taskId, action)\n // Apply the action against the instance (reloading its own writes);\n // content stays overlaid in the cascade below.\n const ranOps = await applyAction({\n client,\n instance,\n taskId,\n action,\n actor,\n ...(clock !== undefined ? {clock} : {}),\n ...(params !== undefined ? {params} : {}),\n })\n const cascaded = await cascade(client, instance._id, actor, clientForGdr, clock, held)\n instance = await reload(client, instance._id, tags)\n return {instance, cascaded, fired: true, ...(ranOps !== undefined ? {ranOps} : {})}\n })\n },\n }\n}\n\n/**\n * Validate a pushed self-doc before it becomes the held instance. The doc comes\n * from the consumer's live store, so a malformed push must fail hard at the\n * boundary rather than silently corrupting the state that drives\n * `evaluate`/`subscriptionDocuments`.\n */\nfunction asHeldInstance(doc: SanityDocument): WorkflowInstance {\n const candidate = doc as Partial<WorkflowInstance>\n if (\n candidate._type !== 'workflow.instance' ||\n typeof candidate.currentStageId !== 'string' ||\n !Array.isArray(candidate.stages)\n ) {\n throw new Error(`update: self-doc ${doc._id} is not a valid workflow.instance`)\n }\n return doc as WorkflowInstance\n}\n","import type {WorkflowAccessOverride} from '../access.ts'\nimport type {Clock} from '../clock.ts'\nimport type {WorkflowResource} from '../core/refs.ts'\nimport {type EvaluateArgs, evaluateInstance} from '../evaluate.ts'\nimport {subscriptionDocumentsForInstance, type WatchSet} from '../subscription-documents.ts'\nimport {validateTags} from '../tags.ts'\nimport type {MutationGuardDoc} from '../types/authorization.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {PendingEffect} from '../types/effects.ts'\nimport type {WorkflowInstance} from '../types/instance.ts'\nimport {drainEffectsInternal, verifyDeployedDefinitionsInternal} from './drain.ts'\nimport {createInstanceSession, type InstanceSession} from './instance-session.ts'\nimport type {\n CompleteEffectArgs,\n DeployDefinitionsArgs,\n DeployDefinitionsResult,\n DispatchResult,\n DrainEffectsResult,\n EffectHandler,\n EngineLogger,\n FireActionArgs,\n LoggerFactory,\n MissingHandlerPolicy,\n OperationArgs,\n ResourceClientResolver,\n SetStageArgs,\n StartInstanceArgs,\n VerifyDeployedDefinitionsResult,\n} from './types.ts'\nimport {workflow} from './workflow.ts'\n\n// createEngine factory.\n//\n// Pre-binds `client`, `tags`, `workflowResource` (and optional\n// `effectHandlers`, `missingHandler`, `loggerFactory`) so callers don't\n// repeat them on every call. Exposes the same verb surface as the\n// `workflow.*` namespace; the namespace stays for callers that want the\n// raw, unbound functions.\n\nexport interface CreateEngineArgs {\n client: WorkflowClient\n workflowResource: WorkflowResource\n tags: string[]\n /**\n * Optional routing for cross-resource reads. When the engine needs\n * a doc whose GDR points at a resource other than its own, it calls\n * the resolver; if the resolver returns a client, that one is used.\n * Otherwise the engine's default `client` is used (best for\n * single-resource setups — most demos).\n */\n resourceClients?: ResourceClientResolver\n effectHandlers?: Record<string, EffectHandler>\n missingHandler?: MissingHandlerPolicy\n loggerFactory?: LoggerFactory\n /**\n * Deterministic-time seam, pinned once for this engine and threaded\n * into every verb it drives — `$now`, the `now` op-source, and the\n * timestamps the engine stamps all read from it. Omit (the default) to\n * use real wall-clock time; production never sets this. The test bench\n * (`@sanity/workflow-engine-test`) wraps this same seam as `setNow` /\n * `advance`. Deliberately engine-construction config, NOT a per-verb\n * option.\n */\n clock?: Clock\n}\n\ntype Bound<\n Args extends {client: WorkflowClient; tags: string[]; workflowResource: WorkflowResource},\n> = Omit<Args, 'client' | 'tags' | 'workflowResource'>\n\nexport interface Engine {\n /** Engine-scoped bindings — exposed for the few advanced consumers\n * (e.g. test bench, drain workers) that need them; the verbs already\n * thread them through internally. */\n readonly client: WorkflowClient\n readonly tags: readonly string[]\n readonly workflowResource: WorkflowResource\n readonly effectHandlers: Readonly<Record<string, EffectHandler>>\n readonly missingHandler: MissingHandlerPolicy\n readonly logger: LoggerFactory\n\n deployDefinitions: (args: Bound<DeployDefinitionsArgs>) => Promise<DeployDefinitionsResult>\n startInstance: (args: Bound<StartInstanceArgs>) => Promise<WorkflowInstance>\n fireAction: (args: Bound<FireActionArgs>) => Promise<DispatchResult>\n completeEffect: (args: Bound<CompleteEffectArgs>) => Promise<DispatchResult>\n tick: (args: Bound<OperationArgs>) => Promise<DispatchResult>\n evaluateInstance: (args: Bound<EvaluateArgs>) => ReturnType<typeof evaluateInstance>\n\n /** Admin override — bypass filters/transitions and force the stage. */\n setStage: (args: Bound<SetStageArgs>) => Promise<DispatchResult>\n /** Fetch a workflow instance by id. */\n getInstance: (args: {instanceId: string}) => Promise<WorkflowInstance>\n /** The reactive {@link WatchSet} for an instance — every document whose\n * change should re-evaluate it (the instance, its ancestors, and the docs\n * named by `doc.ref`/`doc.refs`/`release.ref` slots on the workflow scope\n * + current stage) as exploded {@link SubscriptionDocument}s, plus the\n * instance's read perspective. Fetches the instance, then derives. A\n * reactive adapter that already holds the live instance calls the pure\n * `subscriptionDocumentsForInstance` directly instead, to avoid the re-fetch. */\n subscriptionDocumentsForInstance: (args: {instanceId: string}) => Promise<WatchSet>\n /** Opt into reactivity: bind the engine to an instance doc and get a stateful\n * {@link InstanceSession}. Push the docs it lists in `subscriptionDocuments`\n * via `update`, then `evaluate`/`tick`/`fireAction` against the held state —\n * pushed content is never refetched. The session never observes or ticks on\n * its own; the consumer drives it. */\n instance: (\n instanceDoc: WorkflowInstance,\n opts?: {access?: WorkflowAccessOverride; grantsFromPath?: string},\n ) => InstanceSession\n /** Every lake mutation guard this instance registered, unioned across the\n * instance's own resource and the resource of each `doc.ref`/`doc.refs`\n * GDR it holds in state. For coherency refresh and housekeeping. */\n guardsForInstance: (args: {instanceId: string}) => Promise<MutationGuardDoc[]>\n /** Spawned children of a parent instance, optionally filtered by the\n * spawning task. Sorted by `startedAt` asc. */\n children: (args: {instanceId: string; taskId?: string}) => Promise<WorkflowInstance[]>\n /** GROQ query against the engine's workflow resource. `$engineTags`\n * is bound for tag-aware filtering. */\n query: <T = unknown>(args: {groq: string; params?: Record<string, unknown>}) => Promise<T>\n /** Snapshot-aware GROQ — runs against the same in-memory view the\n * engine's filters see for the supplied instance. Reserved params\n * (`$self`, `$subject`, `$ancestors`, `$now`, `$stage`) are bound\n * in GDR URI form to match the snapshot's keying. */\n queryInScope: <T = unknown>(args: {\n instanceId: string\n groq: string\n params?: Record<string, unknown>\n }) => Promise<T>\n /** List every pending effect on an instance. */\n listPendingEffects: (args: {instanceId: string}) => Promise<PendingEffect[]>\n /** Filter pending effects by claimed status and/or effect names. */\n findPendingEffects: (args: {\n instanceId: string\n claimed?: boolean\n names?: string[]\n }) => Promise<PendingEffect[]>\n /** Dispatch unclaimed effects through registered handlers. The\n * drainer's identity defaults to a `{ kind: \"system\", id: \"engine.drainEffects\" }`\n * actor; pass `access` to override (e.g. impersonate a real user\n * whose grants you want the dispatch to respect). */\n drainEffects: (args: {\n instanceId: string\n access?: WorkflowAccessOverride\n }) => Promise<DrainEffectsResult>\n /**\n * Inspect every workflow.definition in the engine's tags and apply\n * the configured missingHandler policy at `phase: \"deploy\"` for any\n * effect name without a registered handler. Catches \"definition\n * shipped, handler removed\" misconfigurations at startup instead of\n * three days later when the effect fires.\n *\n * Returns the list of (definitionId, name, locations) tuples it saw.\n * Throws if missingHandler resolved as \"fail\" for any of them.\n */\n verifyDeployedDefinitions: () => Promise<VerifyDeployedDefinitionsResult>\n}\n\n/**\n * Default LoggerFactory — writes through the global `console`. Exposed\n * so callers outside `createEngine` (drive scripts, the\n * drain-effects helper) can use the same logger shape the engine uses\n * internally. Returns a fresh `EngineLogger` per call; the `name`\n * shows up as a `[name]` prefix on every line.\n */\nexport const defaultLoggerFactory: LoggerFactory = (name) => ({\n // info/warn/error all go to stderr — these are diagnostic, not\n // program output. Keeps stdout reserved for the caller's own data\n // so progress markers (process.stdout.write) and logger lines\n // don't interleave on the same line.\n info: (message, extra) => console.error(`[${name}] ${message}`, extra !== undefined ? extra : ''),\n warn: (message, extra) => console.warn(`[${name}] ${message}`, extra !== undefined ? extra : ''),\n error: (message, extra) =>\n console.error(`[${name}] ${message}`, extra !== undefined ? extra : ''),\n})\n\n/**\n * No-op logger. Default for library callers that don't want any\n * output unless explicitly opted in.\n */\nexport const silentLogger: EngineLogger = {\n info: () => {},\n warn: () => {},\n error: () => {},\n}\n\n/**\n * Construct an engine bound to a workflow resource + tags. The returned\n * object exposes the same verbs as the `workflow.*` namespace, minus\n * the boilerplate config arguments (client / tags / workflowResource)\n * which are pinned at construction.\n *\n * Effect handlers + missingHandler are stored for future drain wiring\n * (Step 10). They have no effect on `fireAction` / `tick` /\n * `completeEffect` today — those still expect the runtime to dispatch\n * effects and report back via `completeEffect`.\n */\nexport function createEngine(args: CreateEngineArgs): Engine {\n const {client, workflowResource, tags, resourceClients, clock} = args\n validateTags(tags)\n const effectHandlers = args.effectHandlers ?? {}\n const missingHandler = args.missingHandler ?? 'fail'\n const logger = args.loggerFactory ?? defaultLoggerFactory\n\n const bind = <\n A extends {client: WorkflowClient; tags: string[]; workflowResource: WorkflowResource},\n >(\n rest: Omit<A, 'client' | 'tags' | 'workflowResource'>,\n ): A =>\n ({\n client,\n tags,\n workflowResource,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n ...(clock !== undefined ? {clock} : {}),\n ...rest,\n }) as A\n\n return {\n client,\n tags,\n workflowResource,\n effectHandlers,\n missingHandler,\n logger,\n deployDefinitions: (rest) => workflow.deployDefinitions(bind<DeployDefinitionsArgs>(rest)),\n startInstance: (rest) => workflow.startInstance(bind<StartInstanceArgs>(rest)),\n fireAction: (rest) => workflow.fireAction(bind<FireActionArgs>(rest)),\n completeEffect: (rest) => workflow.completeEffect(bind<CompleteEffectArgs>(rest)),\n tick: (rest) => workflow.tick(bind<OperationArgs>(rest)),\n evaluateInstance: (rest) => evaluateInstance(bind<EvaluateArgs>(rest)),\n\n setStage: (rest) => workflow.setStage(bind<SetStageArgs>(rest)),\n getInstance: ({instanceId}) =>\n workflow.getInstance({client, tags, workflowResource, instanceId}),\n subscriptionDocumentsForInstance: ({instanceId}) =>\n workflow\n .getInstance({client, tags, workflowResource, instanceId})\n .then(subscriptionDocumentsForInstance),\n instance: (instanceDoc, opts) =>\n createInstanceSession({\n client,\n tags,\n instance: instanceDoc,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n ...(clock !== undefined ? {clock} : {}),\n ...(opts?.access !== undefined ? {access: opts.access} : {}),\n ...(opts?.grantsFromPath !== undefined ? {grantsFromPath: opts.grantsFromPath} : {}),\n }),\n guardsForInstance: ({instanceId}) =>\n workflow.guardsForInstance({\n client,\n tags,\n workflowResource,\n instanceId,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n }),\n children: ({instanceId, taskId}) =>\n workflow.children({\n client,\n tags,\n workflowResource,\n instanceId,\n ...(taskId !== undefined ? {taskId} : {}),\n }),\n query: ({groq, params}) =>\n workflow.query({\n client,\n tags,\n workflowResource,\n groq,\n ...(params !== undefined ? {params} : {}),\n }),\n queryInScope: ({instanceId, groq, params}) =>\n workflow.queryInScope({\n client,\n tags,\n workflowResource,\n instanceId,\n groq,\n ...(params !== undefined ? {params} : {}),\n ...(clock !== undefined ? {clock} : {}),\n }),\n listPendingEffects: ({instanceId}) =>\n workflow.listPendingEffects({client, tags, workflowResource, instanceId}),\n findPendingEffects: ({instanceId, claimed, names}) =>\n workflow.findPendingEffects({\n client,\n tags,\n workflowResource,\n instanceId,\n ...(claimed !== undefined ? {claimed} : {}),\n ...(names !== undefined ? {names} : {}),\n }),\n drainEffects: ({instanceId, access}) =>\n drainEffectsInternal({\n client,\n tags,\n workflowResource,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n instanceId,\n effectHandlers,\n missingHandler,\n logger,\n ...(access !== undefined ? {access} : {}),\n }),\n verifyDeployedDefinitions: () =>\n verifyDeployedDefinitionsInternal({\n client,\n tags,\n effectHandlers,\n missingHandler,\n logger,\n }),\n }\n}\n","/**\n * Display metadata for every `workflow.*` `_type` literal the engine\n * persists (history entries, state-slot kinds, ops, effects-context\n * entry kinds, authoring-shape discriminators). Each entry exposes\n *\n * - `title` — short label for chips, badges, headings\n * - `description` — longer prose for tooltips / inspector panes\n *\n * UIs that render a workflow.instance audit log should NEVER show\n * `workflow.history.transitionFired` raw — they look it up here and\n * render `\"Transition fired\"` instead.\n *\n * Stable, additive surface: adding a new `_type` to the engine must\n * also add an entry here.\n */\n\nexport interface DisplayMetadata {\n readonly title: string\n readonly description: string\n}\n\n/**\n * History-entry `_type` discriminators. Order roughly matches the\n * order a typical run produces them in a single fire-action commit.\n */\nexport const HISTORY_DISPLAY: Record<string, DisplayMetadata> = {\n 'workflow.history.stageEntered': {\n title: 'Stage entered',\n description: 'The instance crossed into a new stage.',\n },\n 'workflow.history.stageExited': {\n title: 'Stage exited',\n description: 'The instance left a stage on the way to the next one.',\n },\n 'workflow.history.taskActivated': {\n title: 'Task activated',\n description: 'A task flipped from `pending` to `active` and its onEnter effects queued.',\n },\n 'workflow.history.taskStatusChanged': {\n title: 'Task status changed',\n description: \"An action or op flipped a task's status (active → done / skipped / failed).\",\n },\n 'workflow.history.actionFired': {\n title: 'Action fired',\n description:\n 'An action was invoked against a task — ops ran, status may have flipped, effects queued.',\n },\n 'workflow.history.transitionFired': {\n title: 'Transition fired',\n description: 'A transition committed and the instance moved to a new stage.',\n },\n 'workflow.history.effectQueued': {\n title: 'Effect queued',\n description: 'A pending effect was added to the queue, waiting for a drainer to dispatch it.',\n },\n 'workflow.history.effectCompleted': {\n title: 'Effect completed',\n description:\n 'A drainer ran an effect handler to completion (done or failed) and merged its outputs into effectsContext.',\n },\n 'workflow.history.spawned': {\n title: 'Spawned child',\n description: 'A `task.spawns` declaration spawned a child workflow instance.',\n },\n 'workflow.history.opApplied': {\n title: 'Op applied',\n description:\n 'An inline state-mutation op (state.set / state.append / status.set / etc.) ran during an action commit.',\n },\n}\n\n/**\n * State-slot `_type` discriminators. The slot's variant defines what\n * shape `value` takes (single GDR vs array, scalar vs notes log).\n */\nexport const STATE_SLOT_DISPLAY: Record<string, DisplayMetadata> = {\n 'workflow.state.doc.ref': {\n title: 'Document reference',\n description: 'Single GDR pointer at a document in this or another resource.',\n },\n 'workflow.state.doc.refs': {\n title: 'Document references',\n description: 'Ordered list of GDR pointers — multi-doc selection.',\n },\n 'workflow.state.query': {\n title: 'Query result',\n description:\n 'Snapshot of a GROQ projection captured at slot-resolve time; resolvedAt is stamped on the value.',\n },\n 'workflow.state.value.string': {\n title: 'String value',\n description: 'Free-form string slot.',\n },\n 'workflow.state.value.url': {\n title: 'URL value',\n description: 'Validated URL slot.',\n },\n 'workflow.state.value.number': {\n title: 'Number value',\n description: 'Numeric slot.',\n },\n 'workflow.state.value.boolean': {\n title: 'Boolean value',\n description: 'True/false slot.',\n },\n 'workflow.state.value.dateTime': {\n title: 'Date / time value',\n description: 'ISO-timestamp slot.',\n },\n 'workflow.state.checklist': {\n title: 'Checklist',\n description: 'Append-only list of checkable items; ops add/update/remove entries.',\n },\n 'workflow.state.notes': {\n title: 'Notes log',\n description: 'Append-only structured-note log (signoffs, comments, audit rows).',\n },\n 'workflow.state.assignees': {\n title: 'Assignees',\n description: 'Ordered list of typed (user|role) assignees.',\n },\n}\n\n/**\n * Op `_type` discriminators.\n */\nexport const OP_DISPLAY: Record<string, DisplayMetadata> = {\n 'workflow.op.state.set': {\n title: 'Set slot',\n description: \"Overwrite a state slot's value with a resolved Source.\",\n },\n 'workflow.op.state.append': {\n title: 'Append to slot',\n description:\n 'Push a resolved item onto an array-typed slot (notes, checklist, assignees, refs).',\n },\n 'workflow.op.state.updateWhere': {\n title: 'Update matching rows',\n description: 'Merge fields into rows of an array-typed slot that match the predicate.',\n },\n 'workflow.op.state.removeWhere': {\n title: 'Remove matching rows',\n description: 'Drop rows of an array-typed slot that match the predicate.',\n },\n 'workflow.op.status.set': {\n title: 'Set task status',\n description: \"Flip a task's status explicitly (action.setStatus is the more common path).\",\n },\n}\n\n/**\n * EffectsContext entry kinds.\n */\nexport const EFFECTS_CONTEXT_DISPLAY: Record<string, DisplayMetadata> = {\n 'effectsContext.string': {\n title: 'String',\n description: 'Stable string parameter for effect handlers.',\n },\n 'effectsContext.number': {\n title: 'Number',\n description: 'Stable numeric parameter for effect handlers.',\n },\n 'effectsContext.boolean': {\n title: 'Boolean',\n description: 'Stable boolean parameter for effect handlers.',\n },\n 'effectsContext.ref': {\n title: 'GDR reference',\n description: 'Stable GDR pointer parameter for effect handlers.',\n },\n 'effectsContext.json': {\n title: 'JSON',\n description: 'Stable JSON payload for effect handlers.',\n },\n}\n\n/**\n * Authoring-shape discriminators (used when declaring a workflow).\n */\nexport const AUTHORING_DISPLAY: Record<string, DisplayMetadata> = {\n 'workflow.stage': {\n title: 'Stage',\n description: 'A bucket of tasks the workflow is currently in.',\n },\n 'workflow.task': {\n title: 'Task',\n description: 'A unit of work inside a stage; carries actions and may spawn children.',\n },\n 'workflow.action': {\n title: 'Action',\n description: 'An invocable transition on a task — runs ops, queues effects, may flip status.',\n },\n 'workflow.action.param': {\n title: 'Action param',\n description: 'Caller-supplied parameter on an action; validated before any commit.',\n },\n 'workflow.transition': {\n title: 'Transition',\n description: 'An edge between stages, gated by a filter.',\n },\n 'workflow.predicate': {\n title: 'Predicate',\n description: 'Named GROQ filter, reusable across transitions / tasks / actions.',\n },\n 'workflow.effect': {\n title: 'Effect',\n description:\n 'Externally-dispatched side effect; queued on commit, drained by a runtime, completed asynchronously.',\n },\n 'workflow.spawn': {\n title: 'Spawn',\n description: 'Declares a task that fans out one or more child workflow instances.',\n },\n 'workflow.pendingEffect': {\n title: 'Pending effect',\n description: 'An effect that has been queued but not yet dispatched.',\n },\n 'workflow.pendingEffect.claim': {\n title: 'Claim',\n description: \"A drainer's lock on a pending effect while it dispatches.\",\n },\n 'workflow.definition': {\n title: 'Workflow definition',\n description: 'An immutable workflow blueprint pinned by `workflowId` + `version`.',\n },\n 'workflow.instance': {\n title: 'Workflow instance',\n description: 'A running (or finished) workflow against a subject.',\n },\n}\n\n/**\n * Single combined map for callers that don't care which family the\n * key belongs to (e.g. an audit row showing any `_type`).\n */\nexport const DISPLAY: Record<string, DisplayMetadata> = {\n ...HISTORY_DISPLAY,\n ...STATE_SLOT_DISPLAY,\n ...OP_DISPLAY,\n ...EFFECTS_CONTEXT_DISPLAY,\n ...AUTHORING_DISPLAY,\n}\n\n/**\n * Lookup helper. Returns a friendly title for any known `_type`, or\n * the original key when unknown so UIs degrade gracefully.\n */\nexport function displayTitle(typeKey: string | undefined): string {\n if (!typeKey) return ''\n return DISPLAY[typeKey]?.title ?? typeKey\n}\n\n/**\n * Same idea but returns the description, or undefined when unknown.\n */\nexport function displayDescription(typeKey: string | undefined): string | undefined {\n if (!typeKey) return undefined\n return DISPLAY[typeKey]?.description\n}\n"],"names":["v","parseGroq","slotValue","tree","gdrUri","doc","randomKey","policy","engineInvokeTask","engineFireAction","engineCompleteEffect","engineSetStage","queryGuardsForInstance","evaluateGroq"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/core/path.ts","../src/core/refs.ts","../src/guard-bindings.ts","../src/api/validate.ts","../src/clock.ts","../src/types/authorization.ts","../src/core/guards.ts","../src/types/instance-state.ts","../src/core/params.ts","../src/guards-lifecycle.ts","../src/keys.ts","../src/core/eval.ts","../src/core/snapshot.ts","../src/types/instance.ts","../src/subscription-documents.ts","../src/snapshot.ts","../src/core/state-validation.ts","../src/state-resolution.ts","../src/engine/context.ts","../src/core/bindings.ts","../src/instance.ts","../src/engine/results.ts","../src/engine/guard-commit.ts","../src/engine/history-entries.ts","../src/tags.ts","../src/definition-query.ts","../src/discover.ts","../src/engine/spawn.ts","../src/core/source.ts","../src/engine/ops.ts","../src/engine/tasks.ts","../src/engine/stages.ts","../src/engine/cascade.ts","../src/engine/mutation.ts","../src/engine/effects.ts","../src/engine/abort.ts","../src/permissions.ts","../src/access.ts","../src/guards-query.ts","../src/evaluate.ts","../src/api/deploy.ts","../src/engine/actions.ts","../src/types/evaluation.ts","../src/api/operations.ts","../src/api/workflow.ts","../src/api/drain.ts","../src/api/instance-session.ts","../src/api/engine-factory.ts","../src/display.ts"],"sourcesContent":["/**\n * Walk a dot-separated property path into a value, returning `undefined` at\n * the first non-object link. Pure; shared by binding resolution, state-entry\n * path dives, and op-predicate field reads.\n */\nexport function getPath(value: unknown, path: string): unknown {\n let current: unknown = value\n for (const part of path.split('.')) {\n if (current === undefined || current === null || typeof current !== 'object') return undefined\n current = (current as Record<string, unknown>)[part]\n }\n return current\n}\n","/**\n * Global Document References (GDR).\n *\n * Every cross-document reference in the engine API uses this shape so\n * workflow state can live in one Sanity resource while subjects /\n * ancestors / effect-binding refs point at docs in *different* resources.\n *\n * Resource schemes mirror `@sanity/client`'s `ClientConfigResource`\n * discriminator. A GDR id is a typed URI:\n *\n * dataset:<projectId>:<dataset>:<documentId>\n * canvas:<resourceId>:<documentId>\n * media-library:<resourceId>:<documentId>\n * dashboard:<resourceId>:<documentId>\n *\n * The `type` field carries the doc's schema `_type` so consumers don't\n * need a separate lookup to know what they're pointing at.\n */\n\nexport type GdrScheme = 'dataset' | 'canvas' | 'media-library' | 'dashboard'\n\n/**\n * Typed GDR URI string. The compiler rejects bare doc ids (`\"doc-1\"`)\n * — only `<scheme>:<...id-parts>` values typecheck. Construct one via\n * `gdrUri()` / `gdrFromResource()` / `refDataset()` etc., or by hand\n * with the scheme prefix baked in (`` `dataset:proj:ds:${docId}` `` ).\n *\n * Combined with schema validation at the API boundary, this is the\n * type + runtime guarantee that no bare-string id reaches the\n * snapshot, state entry, or filter layer.\n */\nexport type GdrUri = `${GdrScheme}:${string}`\n\nexport interface GlobalDocumentReference {\n /** URI: `<scheme>:<...id-parts>` */\n id: GdrUri\n /** Document `_type` (schema name) */\n type: string\n}\n\nexport interface ParsedGdr {\n scheme: GdrScheme\n /** For `dataset`: `<projectId>` */\n projectId?: string\n /** For `dataset`: `<dataset>` */\n dataset?: string\n /** For `canvas` / `media-library` / `dashboard`: `<resourceId>` */\n resourceId?: string\n /** The trailing `<documentId>` part — what `_id` of the target doc is */\n documentId: string\n}\n\nconst KNOWN_SCHEMES = new Set<string>(['dataset', 'canvas', 'media-library', 'dashboard'])\n\n/**\n * Parse a GDR URI into its scheme + addressing parts. Throws on\n * unknown scheme or malformed shape.\n */\nexport function parseGdr(uri: string): ParsedGdr {\n const colon = uri.indexOf(':')\n if (colon < 0) {\n throw new Error(\n `Invalid GDR \"${uri}\": must be a URI of form \"<scheme>:<...id-parts>\". Known schemes: dataset, canvas, media-library, dashboard.`,\n )\n }\n const scheme = uri.slice(0, colon)\n const rest = uri.slice(colon + 1)\n if (!KNOWN_SCHEMES.has(scheme)) {\n throw new Error(\n `Invalid GDR \"${uri}\": unknown scheme \"${scheme}\". Known: dataset, canvas, media-library, dashboard.`,\n )\n }\n const parts = rest.split(':')\n if (parts.some((part) => part.length === 0)) {\n throw new Error(\n `Invalid GDR \"${uri}\": id parts must be non-empty (no leading, trailing, or doubled \":\").`,\n )\n }\n if (scheme === 'dataset') {\n if (parts.length !== 3) {\n throw new Error(\n `Invalid GDR \"${uri}\": dataset scheme requires <projectId>:<dataset>:<documentId> (3 parts after scheme); got ${parts.length}.`,\n )\n }\n return {\n scheme: 'dataset',\n projectId: parts[0]!,\n dataset: parts[1]!,\n documentId: parts[2]!,\n }\n }\n // canvas / media-library / dashboard share <resourceId>:<documentId>\n if (parts.length !== 2) {\n throw new Error(\n `Invalid GDR \"${uri}\": ${scheme} scheme requires <resourceId>:<documentId> (2 parts after scheme); got ${parts.length}.`,\n )\n }\n return {\n scheme: scheme as GdrScheme,\n resourceId: parts[0]!,\n documentId: parts[1]!,\n }\n}\n\n/** Compose a GDR URI from parts. Inverse of `parseGdr`. */\nexport function gdrUri(\n parts:\n | {scheme: 'dataset'; projectId: string; dataset: string; documentId: string}\n | {\n scheme: 'canvas' | 'media-library' | 'dashboard'\n resourceId: string\n documentId: string\n },\n): GdrUri {\n if (parts.scheme === 'dataset') {\n return `dataset:${parts.projectId}:${parts.dataset}:${parts.documentId}` as GdrUri\n }\n return `${parts.scheme}:${parts.resourceId}:${parts.documentId}` as GdrUri\n}\n\n/**\n * Extract the bare document `_id` from a GDR URI — what\n * `*[_id == $docId]` in GROQ needs.\n */\nexport function extractDocumentId(gdrUriString: string): string {\n return parseGdr(gdrUriString).documentId\n}\n\n/** Make a GDR pointer to a project-dataset doc. */\nexport function refDataset(\n projectId: string,\n dataset: string,\n documentId: string,\n type: string,\n): GlobalDocumentReference {\n return {id: gdrUri({scheme: 'dataset', projectId, dataset, documentId}), type}\n}\n\n/** Make a GDR pointer to a Canvas-resource doc. */\nexport function refCanvas(\n resourceId: string,\n documentId: string,\n type: string,\n): GlobalDocumentReference {\n return {id: gdrUri({scheme: 'canvas', resourceId, documentId}), type}\n}\n\n/** Make a GDR pointer to a Media-Library-resource doc. */\nexport function refMediaLibrary(\n resourceId: string,\n documentId: string,\n type: string,\n): GlobalDocumentReference {\n return {id: gdrUri({scheme: 'media-library', resourceId, documentId}), type}\n}\n\n/** Make a GDR pointer to a Dashboard-resource doc. */\nexport function refDashboard(\n resourceId: string,\n documentId: string,\n type: string,\n): GlobalDocumentReference {\n return {id: gdrUri({scheme: 'dashboard', resourceId, documentId}), type}\n}\n\n/**\n * The resource a Sanity client is configured against — mirrors\n * `@sanity/client`'s `ClientConfigResource` discriminator. For\n * `dataset`, `id` is `<projectId>.<dataset>`. For the others, `id` is\n * the resource id.\n */\nexport type WorkflowResource =\n | {type: 'dataset'; id: string}\n | {type: 'canvas'; id: string}\n | {type: 'media-library'; id: string}\n | {type: 'dashboard'; id: string}\n\n/**\n * Split a dataset resource id (`<projectId>.<dataset>`) into its parts — the\n * one parser for the format, shared by {@link gdrFromResource} and the React\n * adapters' store routing. Throws on a malformed id: missing separator, or an\n * empty project / dataset part.\n */\nexport function datasetResourceParts(id: string): {projectId: string; dataset: string} {\n const dot = id.indexOf('.')\n if (dot <= 0 || dot === id.length - 1) {\n throw new Error(`Invalid dataset resource id \"${id}\": expected \"<projectId>.<dataset>\".`)\n }\n return {projectId: id.slice(0, dot), dataset: id.slice(dot + 1)}\n}\n\n/**\n * Build a GDR URI from a workflow resource config + a document id\n * within that resource. This is how the engine mints `_id`s for\n * definitions / instances / ancestor refs into its own resource.\n */\nexport function gdrFromResource(res: WorkflowResource, documentId: string): GdrUri {\n if (res.type === 'dataset') {\n const {projectId, dataset} = datasetResourceParts(res.id)\n return gdrUri({scheme: 'dataset', projectId, dataset, documentId})\n }\n return gdrUri({scheme: res.type, resourceId: res.id, documentId})\n}\n\n/**\n * The GDR URI a document refers to itself by — its own `_id` minted into\n * its own `workflowResource`. This is the `$self` value filters see and\n * the form `Source.self` resolves to in ops and spawn.\n */\nexport function selfGdr(doc: {workflowResource: WorkflowResource; _id: string}): GdrUri {\n return gdrFromResource(doc.workflowResource, doc._id)\n}\n\n/**\n * Type-narrowing predicate — `true` when `value` looks like a GDR URI\n * (has a known scheme prefix). Use at boundaries that receive\n * stringified ids and need to refuse bare doc ids.\n */\nexport function isGdrUri(value: unknown): value is GdrUri {\n if (typeof value !== 'string') return false\n try {\n parseGdr(value)\n return true\n } catch {\n return false\n }\n}\n\n/** Build a GDR (id + type) pointing at a document within a workflow resource. */\nexport function gdrRef(\n res: WorkflowResource,\n documentId: string,\n type: string,\n): GlobalDocumentReference {\n return {id: gdrFromResource(res, documentId), type}\n}\n\n/** Type filter for GDR shape. */\nexport function isGdr(value: unknown): value is GlobalDocumentReference {\n return (\n typeof value === 'object' &&\n value !== null &&\n typeof (value as {id?: unknown}).id === 'string' &&\n typeof (value as {type?: unknown}).type === 'string'\n )\n}\n","import {getPath} from './core/path.ts'\nimport {isGdrUri, parseGdr, selfGdr} from './core/refs.ts'\nimport type {ParsedGdr} from './core/refs.ts'\nimport type {WorkflowInstance} from './types/instance.ts'\n\nexport interface Resource {\n type: string\n id: string\n}\n\nfunction resourceOf(p: ParsedGdr): Resource {\n if (p.scheme === 'dataset') return {type: 'dataset', id: `${p.projectId}.${p.dataset}`}\n return {type: p.scheme, id: p.resourceId ?? ''}\n}\n\ninterface GdrTarget {\n parsed: ParsedGdr\n type?: string\n}\n\nexport interface BindingContext {\n instance: WorkflowInstance\n stageName: string\n /** Shell-supplied clock reading (ISO) backing `$now` reads. */\n now: string\n}\n\n// State entry names are schema-constrained to GROQ-safe identifiers, so the\n// name segment is exactly \\w+ — anything past it is the value path.\nconst STATE_READ = /^\\$state\\.(\\w+)(?:\\.(.+))?$/\n\n/**\n * Whether a string is a syntactically valid guard read — the mini-language\n * accepted on `match.idRefs` and `metadata` values: `\"$self\"`, `\"$now\"`, or\n * `\"$state.<name>[.path]\"`. Checked at deploy ({@link validateDefinition})\n * so a typo fails before the first instance enters the stage, and enforced\n * again at resolve time by {@link resolveGuardRead}.\n */\nexport function isGuardReadExpr(expr: string): boolean {\n return expr === '$self' || expr === '$now' || STATE_READ.test(expr)\n}\n\n/**\n * Resolve a guard's deploy-time read — the `$state`-read value spelling on\n * `match.idRefs` and `metadata`. The lake contract stores resolved VALUES,\n * so these evaluate here, at deploy (and again on the post-state-op\n * refresh). Deliberately a tiny reader, not full GROQ: a guard value is\n * `\"$self\"`, `\"$now\"`, or `\"$state.<name>[.path]\"` — anything else is an\n * authoring error and fails loud rather than silently projecting nothing.\n */\nfunction resolveGuardRead(expr: string, ctx: BindingContext): unknown {\n if (expr === '$self') return selfGdr(ctx.instance)\n if (expr === '$now') return ctx.now\n const stateRead = STATE_READ.exec(expr)\n if (stateRead !== null) {\n const entry = (ctx.instance.state ?? []).find((s) => s.name === stateRead[1])\n const value = entry?.value\n return stateRead[2] !== undefined ? getPath(value, stateRead[2]) : value\n }\n throw new Error(\n `Guard read \"${expr}\" is not a supported deploy-time value — use \"$self\", \"$now\", ` +\n `or \"$state.<name>[.path]\" (guards store resolved values; the lake cannot see $state)`,\n )\n}\n\n/**\n * Resolve a single `idRefs` read to a GDR URI + an optional author type.\n * Returns null for unresolvable / non-GDR targets (e.g. an unfilled entry).\n */\nfunction resolveIdRefTarget(expr: string, ctx: BindingContext): GdrTarget | null {\n const value = resolveGuardRead(expr, ctx)\n if (typeof value === 'string' && isGdrUri(value)) {\n return {parsed: parseGdr(value)}\n }\n if (value && typeof value === 'object') {\n const v = value as {id?: unknown; type?: unknown}\n if (typeof v.id === 'string' && isGdrUri(v.id)) {\n return typeof v.type === 'string'\n ? {parsed: parseGdr(v.id), type: v.type}\n : {parsed: parseGdr(v.id)}\n }\n }\n return null\n}\n\n/**\n * Resolve every `idRefs` read. Returns null if any target is unresolvable\n * (the whole guard is then deferred) or if no targets are declared.\n */\nexport function resolveIdRefTargets(\n idRefs: readonly string[] | undefined,\n ctx: BindingContext,\n): GdrTarget[] | null {\n const targets: GdrTarget[] = []\n for (const expr of idRefs ?? []) {\n const target = resolveIdRefTarget(expr, ctx)\n if (target === null) return null\n targets.push(target)\n }\n return targets.length === 0 ? null : targets\n}\n\n/**\n * Enforce the single-resource invariant: every target must live in the same\n * datasource. Returns that shared resource, or throws on a span.\n */\nexport function assertSingleResource(targets: readonly GdrTarget[]): Resource {\n const resource = resourceOf(targets[0]!.parsed)\n for (const g of targets) {\n const r = resourceOf(g.parsed)\n if (r.type !== resource.type || r.id !== resource.id) {\n throw new Error(\n `Guard targets span multiple resources (${resource.type}:${resource.id} vs ${r.type}:${r.id}); a guard is single-resource.`,\n )\n }\n }\n return resource\n}\n\n/** Bare ids in both published + draft forms for each target. */\nexport function bareIdRefs(targets: readonly GdrTarget[]): string[] {\n return targets.flatMap((g) => [g.parsed.documentId, `drafts.${g.parsed.documentId}`])\n}\n\n/**\n * Effective `match.types`: author-specified wins; otherwise the distinct\n * inferred types across targets, or undefined when none were inferred.\n */\nexport function resolveMatchTypes(\n targets: readonly GdrTarget[],\n authorTypes: string[] | undefined,\n): string[] | undefined {\n if (authorTypes !== undefined) return authorTypes\n const inferred = [...new Set(targets.map((g) => g.type).filter((t): t is string => !!t))]\n return inferred.length > 0 ? inferred : undefined\n}\n\n/** Project each metadata read to its resolved value — the only bridge from\n * the lake eval context (which cannot see `$state`) to workflow state. */\nexport function resolveMetadata(\n metadata: Record<string, string> | undefined,\n ctx: BindingContext,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [k, expr] of Object.entries(metadata ?? {})) {\n out[k] = resolveGuardRead(expr, ctx)\n }\n return out\n}\n","import {parse as parseGroq} from 'groq-js'\n\nimport type {Guard, Stage, StateEntry, Task, WorkflowDefinition} from '../define/schema.ts'\nimport {isGuardReadExpr} from '../guard-bindings.ts'\n\n/**\n * Parse-validate every GROQ string in a (stored, desugared) definition\n * before deploy. Surfaces malformed predicates, conditions, bindings, and\n * `task.completeWhen`/`failWhen` expressions early — long before any\n * instance runs.\n *\n * Throws an `Error` with all problems aggregated. Doesn't try to\n * type-check semantics (just syntax). Reserved params don't need to be\n * declared here — groq-js's parser doesn't know about runtime params,\n * just syntax.\n */\nexport function validateDefinition(definition: WorkflowDefinition): void {\n const v = createDefinitionValidator()\n\n for (const entry of definition.state ?? []) {\n v.checkEntry(entry, `workflow.state \"${entry.name}\"`)\n }\n\n for (const [name, groq] of Object.entries(definition.predicates ?? {})) {\n v.checkCondition(groq, `predicate \"${name}\"`)\n }\n\n for (const stage of definition.stages) {\n validateStage(v, stage)\n }\n\n if (v.errors.length > 0) {\n throw new Error(\n `defineWorkflow(\"${definition.name}\", v${definition.version}): ` +\n `${v.errors.length} validation error${v.errors.length === 1 ? '' : 's'}:\\n` +\n v.errors.join('\\n'),\n )\n }\n}\n\ninterface DefinitionValidator {\n errors: string[]\n /** Parse-check raw GROQ; records a syntax error under `where`. */\n tryParse: (groq: string, where: string) => void\n /** Parse-check a condition AND reject `_type` discovery scans in it. */\n checkCondition: (groq: string, where: string) => void\n /** Parse-check a `query`-sourced state entry's GROQ. */\n checkEntry: (entry: StateEntry, label: string) => void\n /** Syntax-check a guard's `idRefs` / `metadata` read (NOT GROQ — the guard mini-language). */\n checkGuardRead: (expr: string, where: string) => void\n}\n\nfunction createDefinitionValidator(): DefinitionValidator {\n const errors: string[] = []\n const tryParse = (groq: string, where: string) => {\n try {\n parseGroq(groq)\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n errors.push(` · ${where}: ${message}`)\n }\n }\n // Reject conditions that scan by `_type` — those are discovery queries,\n // not predicates. Conditions evaluate against the in-memory snapshot\n // (instance + subject + ancestors + state-declared docs), which never\n // contains \"all docs of type X\", so a type scan returns empty and the\n // workflow appears stuck. Regex-based: `*[` followed by `_type`. False\n // negatives slip through harmlessly (runtime still returns empty).\n const rejectTypeScan = (groq: string, where: string) => {\n if (/\\*\\s*\\[\\s*_type\\b/.test(groq)) {\n errors.push(\n ` · ${where}: condition scans by \\`_type\\` — that's a discovery query, not a predicate. ` +\n `Conditions evaluate against the in-memory snapshot (instance + ancestors + ` +\n `state-declared docs). To bring extra docs in scope, declare a \\`doc.ref\\` ` +\n `(or \\`doc.refs\\`) state entry on the workflow or this stage. For lake scans like ` +\n `\"all articles in this release\", use \\`subworkflows.forEach\\` instead.`,\n )\n }\n }\n const checkCondition = (groq: string, where: string) => {\n tryParse(groq, where)\n rejectTypeScan(groq, where)\n }\n const checkEntry = (entry: StateEntry, label: string) => {\n if (entry.source.type === 'query') tryParse(entry.source.query, `${label}.query`)\n }\n const checkGuardRead = (expr: string, where: string) => {\n if (isGuardReadExpr(expr)) return\n errors.push(\n ` · ${where}: guard read \"${expr}\" is not a supported deploy-time value — use \"$self\", ` +\n `\"$now\", or \"$state.<name>[.path]\" (guards store resolved values; the lake cannot see $state)`,\n )\n }\n return {errors, tryParse, checkCondition, checkEntry, checkGuardRead}\n}\n\nfunction validateStage(v: DefinitionValidator, stage: Stage): void {\n for (const entry of stage.state ?? []) {\n v.checkEntry(entry, `stage \"${stage.name}\".state \"${entry.name}\"`)\n }\n for (const guard of stage.guards ?? []) {\n validateGuardReads(v, stage.name, guard)\n }\n for (const t of stage.transitions ?? []) {\n v.checkCondition(t.filter, `transition \"${t.name}\" (${stage.name} → ${t.to}) filter`)\n for (const [key, groq] of effectBindings(t.effects)) {\n v.tryParse(groq, `transition \"${t.name}\" effect binding \"${key}\"`)\n }\n }\n for (const task of stage.tasks ?? []) {\n validateTask(v, stage.name, task)\n }\n}\n\n/**\n * Guard reads resolve lazily — first at stage entry, not deploy — so a typo\n * would otherwise surface as a runtime throw when the first instance enters\n * the stage. Check the mini-language syntax here instead.\n */\nfunction validateGuardReads(v: DefinitionValidator, stageName: string, guard: Guard): void {\n const where = `stage \"${stageName}\" guard \"${guard.name}\"`\n for (const expr of guard.match.idRefs ?? []) {\n v.checkGuardRead(expr, `${where} match.idRefs`)\n }\n for (const [key, expr] of Object.entries(guard.metadata ?? {})) {\n v.checkGuardRead(expr, `${where} metadata \"${key}\"`)\n }\n}\n\nfunction validateTask(v: DefinitionValidator, stageName: string, task: Task): void {\n const where = `stage \"${stageName}\" task \"${task.name}\"`\n for (const entry of task.state ?? []) {\n v.checkEntry(entry, `${where}.state \"${entry.name}\"`)\n }\n if (task.filter !== undefined) v.checkCondition(task.filter, `${where}.filter`)\n if (task.completeWhen !== undefined) v.checkCondition(task.completeWhen, `${where}.completeWhen`)\n if (task.failWhen !== undefined) v.checkCondition(task.failWhen, `${where}.failWhen`)\n for (const [key, groq] of effectBindings(task.effects)) {\n v.tryParse(groq, `${where} effect binding \"${key}\"`)\n }\n validateTaskActions(v, task)\n if (task.subworkflows !== undefined) validateSubworkflows(v, where, task.subworkflows)\n}\n\nfunction validateTaskActions(v: DefinitionValidator, task: Task): void {\n for (const a of task.actions ?? []) {\n if (a.filter !== undefined) {\n v.checkCondition(a.filter, `task \"${task.name}\" action \"${a.name}\".filter`)\n }\n for (const [key, groq] of effectBindings(a.effects)) {\n v.tryParse(groq, `task \"${task.name}\" action \"${a.name}\" effect binding \"${key}\"`)\n }\n }\n}\n\n// subworkflows.forEach is intentionally NOT type-scan-checked — it's\n// discovery, not a condition. `with`/`context` are reads over $row +\n// the parent scope; parse-check them too.\nfunction validateSubworkflows(\n v: DefinitionValidator,\n where: string,\n sub: NonNullable<Task['subworkflows']>,\n): void {\n v.tryParse(sub.forEach, `${where}.subworkflows.forEach`)\n for (const [key, groq] of Object.entries(sub.with ?? {})) {\n v.tryParse(groq, `${where}.subworkflows.with \"${key}\"`)\n }\n for (const [key, groq] of Object.entries(sub.context ?? {})) {\n v.tryParse(groq, `${where}.subworkflows.context \"${key}\"`)\n }\n}\n\nfunction effectBindings(\n effects: readonly {name: string; bindings?: Record<string, string> | undefined}[] | undefined,\n): [string, string][] {\n return (effects ?? []).flatMap((e) =>\n Object.entries(e.bindings ?? {}).map(([k, groq]): [string, string] => [`${e.name}.${k}`, groq]),\n )\n}\n","/**\n * The engine's single source of \"now\".\n *\n * A {@link Clock} returns the current time as an ISO-8601 string. Each\n * verb-driven operation takes ONE reading and threads it everywhere —\n * `$now` in filters, the `now` op-source, every history `at` stamp,\n * `completedAt`, `enteredAt`, `lastChangedAt` — so an eval pass agrees on\n * the time and a frozen clock produces a deterministic instance.\n *\n * A clock is injected ONCE, never per call: production omits it entirely\n * (defaults to {@link wallClock}); deterministic harnesses pass\n * `createEngine({ clock })`, and tests use `@sanity/workflow-engine-test`'s\n * `setNow` / `advance` (the bench wraps the same seam). It is deliberately\n * NOT a field on the public per-verb `*Args` — the raw `workflow.*` verbs\n * accept it only through the internal {@link Clocked} seam, so prod code\n * can't trivially override engine time by accident.\n *\n * Out of scope: `drainEffects` (the external runtime worker claiming and\n * executing effects) still stamps `claimedAt` from wall-clock — it is not\n * a verb and the bench never drives it. Thread a clock there too if the\n * simulator ever needs deterministic drain timing.\n */\nexport type Clock = () => string\n\n/** The default clock: real wall-clock time as an ISO-8601 string. */\nexport const wallClock: Clock = () => new Date().toISOString()\n\n/**\n * Internal clock-injection seam for the raw `workflow.*` verbs. NOT part\n * of the public per-verb args (it is deliberately not re-exported from the\n * package root) — production injects a clock ONCE via\n * `createEngine({ clock })`, and the test bench via its `setNow` /\n * `advance`. This intersection just lets those two callers thread the\n * clock into a raw verb without `clock` cluttering every documented\n * `*Args` interface as if it were an everyday option.\n */\nexport type Clocked<T> = T & {clock?: Clock}\n","/**\n * Authorization model — grants and mutation guards.\n *\n * Grants are most-permissive-wins value permissions. Mutation guards are\n * the compiled/persisted form of an authoring `Guard`: owner-registered,\n * scoped by `match`, gated by a GROQ `predicate`, enforced OPTIMISTICALLY\n * engine-side only.\n */\n\nimport type {DocumentValuePermission, MutationGuardAction} from './enums.ts'\n\n// Grants. Filters are GROQ strings evaluated through groq-js with the\n// document as the dataset and the actor id as `identity()`. Compose:\n// most-permissive wins.\n\nexport interface Grant {\n filter: string\n permissions: DocumentValuePermission[]\n}\n\n// Mutation guards — the compiled/persisted form of an authoring `Guard`. A\n// guard is owner-registered, scoped by `match`, gated by a GROQ `predicate`\n// (empty = unconditional deny), with an opaque `metadata` bag the predicate\n// can read. Enforcement is OPTIMISTIC engine-side only.\n//\n// `resourceType`/`resourceId` scope a guard to a single datasource: the engine\n// spans datasources and must record which one a guard belongs to (the content\n// lake is per-datasource and infers the resource from storage).\n\n/**\n * The lake document type for a mutation guard. Single source of truth — both\n * the runtime value (id construction, `compileGuard`, queries) and the\n * {@link MutationGuardDoc} `_type` literal derive from here, so the `temp.`\n * POC prefix drops in exactly one place at cutover.\n */\nexport const GUARD_DOC_TYPE = 'temp.system.guard'\n\nexport interface MutationGuardMatch {\n types?: string[]\n /** Bare document ids (resource-local; both published and `drafts.` forms). */\n idRefs?: string[]\n idPatterns?: string[]\n actions: MutationGuardAction[]\n}\n\n/**\n * The persisted body of a mutation guard — every field except the lake system\n * fields. Shared by {@link MutationGuardDoc} (the stored doc) and the engine's\n * compile inputs, so the field set lives in one place.\n */\nexport interface MutationGuardBody {\n /** Engine-layer: the single datasource this guard belongs to. */\n resourceType: string\n resourceId: string\n /** Registering identity — the engine robot. Only owner/admin may modify. */\n owner: string\n /**\n * Provenance — the workflow that registered this guard. The lake's own guard\n * model carries none of these; they exist so the engine can find its guards\n * for coherency refresh and housekeeping without parsing them out of `_id`.\n */\n sourceInstanceId: string\n sourceDefinition: string\n sourceStage: string\n name?: string\n description?: string\n /** Bare document ids (resource-local; both published and `drafts.` forms). */\n match: MutationGuardMatch\n /** GROQ; empty string = unconditional deny. Bare ids/fields only — no GDRs. */\n predicate: string\n /** Caller-owned projected state the predicate reads as `guard.metadata.*`. */\n metadata: Record<string, unknown>\n}\n\nexport interface MutationGuardDoc extends MutationGuardBody {\n _id: string\n _type: typeof GUARD_DOC_TYPE\n // System fields are assigned by the lake on write — never sent on create\n // (an empty-string `_createdAt`/`_updatedAt` fails datetime validation).\n _rev?: string\n _createdAt?: string\n _updatedAt?: string\n}\n\n/**\n * Inputs to predicate evaluation: `document.before`/`after`, the `mutation`,\n * the `guard`, and `identity()`. `before` is null on create, `after` null on\n * delete.\n */\nexport interface MutationContext {\n before: ({_id: string; _type: string} & Record<string, unknown>) | null\n after: ({_id: string; _type: string} & Record<string, unknown>) | null\n action: MutationGuardAction\n /** Authenticated caller id, resolved as `identity()` in the predicate. */\n identity?: string\n}\n\n/**\n * Thrown when one or more guards deny a mutation. POC: raised by the engine /\n * bench enforcement layer; carries every denial. Fail-closed: a predicate that\n * errors or is non-true denies.\n */\nexport class MutationGuardDeniedError extends Error {\n readonly denied: Array<{guardId: string; name?: string}>\n readonly documentId: string\n readonly action: MutationGuardAction\n\n constructor(args: {\n documentId: string\n action: MutationGuardAction\n denied: Array<{guardId: string; name?: string}>\n }) {\n const ids = args.denied.map((d) => d.guardId).join(', ')\n super(`Mutation on \"${args.documentId}\" (${args.action}) denied by guard(s) [${ids}]`)\n this.name = 'MutationGuardDeniedError'\n this.denied = args.denied\n this.documentId = args.documentId\n this.action = args.action\n }\n\n /**\n * Build the error straight from the denying guard docs — the one mapping\n * from {@link MutationGuardDoc} to the structured `denied` payload, shared\n * by every enforcement site (engine pre-flight, bench write seam).\n */\n static fromGuards(args: {\n documentId: string\n action: MutationGuardAction\n guards: readonly MutationGuardDoc[]\n }): MutationGuardDeniedError {\n return new MutationGuardDeniedError({\n documentId: args.documentId,\n action: args.action,\n denied: args.guards.map((g) => ({\n guardId: g._id,\n ...(g.name !== undefined ? {name: g.name} : {}),\n })),\n })\n }\n}\n","/**\n * Pure compilation and evaluation of lake mutation guards.\n *\n * NO CLIENT. NO I/O. The shell resolves a stage `Guard`'s `match.idRefs`\n * Sources to bare ids + a resource and its `metadata` Sources to values, then\n * hands the resolved pieces here to assemble a `temp.system.guard` doc and to\n * evaluate predicates against a `before`/`after` mutation image via groq-js.\n *\n * Guard semantics:\n * - empty predicate ⇒ unconditional deny;\n * - fail-closed — a compile/eval error or non-`true` result denies;\n * - evaluation context = document before/after + mutation + guard + identity().\n *\n * Enforcement is OPTIMISTIC: the lake does not enforce `temp.system.guard`\n * yet, so a pass here is an engine *preview*, not proof. The predicate dialect\n * is groq-js delta-mode; the guard doc is referenced as the `$guard` param and\n * `identity()` resolves to the authenticated caller, the same way `permissions.ts`\n * feeds grant filters.\n */\n\nimport {evaluate, parse} from 'groq-js'\n\nimport {\n GUARD_DOC_TYPE,\n type MutationContext,\n type MutationGuardBody,\n type MutationGuardDoc,\n MutationGuardDeniedError,\n} from '../types/authorization.ts'\nimport type {MutationGuardAction} from '../types/enums.ts'\n\n/**\n * Deterministic id so deploy/retract are query-free and idempotent. Derived\n * from the guard's authored `name` — an author-controlled handle that stays\n * stable when guards are reordered or inserted (a positional index would\n * silently shift).\n */\nexport function lakeGuardId(args: {instanceDocId: string; guardName: string}): string {\n return `${GUARD_DOC_TYPE}.${args.instanceDocId}.${args.guardName}`\n}\n\nexport interface CompileGuardArgs extends MutationGuardBody {\n id: string\n}\n\n/** Assemble a persisted guard doc from resolved pieces. */\nexport function compileGuard(args: CompileGuardArgs): MutationGuardDoc {\n return {\n _id: args.id,\n _type: GUARD_DOC_TYPE,\n resourceType: args.resourceType,\n resourceId: args.resourceId,\n owner: args.owner,\n sourceInstanceId: args.sourceInstanceId,\n sourceDefinition: args.sourceDefinition,\n sourceStage: args.sourceStage,\n ...(args.name !== undefined ? {name: args.name} : {}),\n ...(args.description !== undefined ? {description: args.description} : {}),\n match: args.match,\n predicate: args.predicate,\n metadata: args.metadata,\n } satisfies MutationGuardDoc\n}\n\n/**\n * Translate a lake-wire predicate to groq-js for optimistic POC evaluation.\n * The wire dialect binds `guard` and `mutation` as predicate identifiers;\n * groq-js has no such globals, so we expose them as `$params` and rewrite the\n * references.\n * `identity()`, `delta::*`, and `before`/`after` are native to groq-js and pass\n * through. The STORED predicate stays in wire form (bare `guard`/`mutation`) so\n * it is correct when handed to the real lake; this rewrite is eval-time only.\n */\nfunction toGroqJsPredicate(predicate: string): string {\n return predicate\n .replace(/(?<!\\$)\\bguard\\./g, '$guard.')\n .replace(/(?<!\\$)\\bmutation\\./g, '$mutation.')\n}\n\n/** Glob match supporting a single `*` wildcard per pattern. */\nfunction globMatch(pattern: string, value: string): boolean {\n if (!pattern.includes('*')) return pattern === value\n const escaped = pattern.replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&').replace(/\\*/g, '.*')\n return new RegExp(`^${escaped}$`).test(value)\n}\n\n/**\n * Does this guard's `match` apply to a mutation on the given document?\n * `types` and id facets are ANDed; an unspecified facet does not constrain.\n */\nexport function guardMatches(\n guard: MutationGuardDoc,\n doc: {id: string; type?: string},\n action: MutationGuardAction,\n): boolean {\n const m = guard.match\n if (!m.actions.includes(action)) return false\n if (m.types && m.types.length > 0 && !(doc.type !== undefined && m.types.includes(doc.type))) {\n return false\n }\n const hasIdFacet = (m.idRefs && m.idRefs.length > 0) || (m.idPatterns && m.idPatterns.length > 0)\n if (hasIdFacet) {\n const byRef = m.idRefs?.includes(doc.id) ?? false\n const byPattern = m.idPatterns?.some((p) => globMatch(p, doc.id)) ?? false\n if (!byRef && !byPattern) return false\n }\n return true\n}\n\n/**\n * Evaluate a guard predicate against a mutation. Returns `true` only when the\n * predicate is strictly `true` (ALLOW). Empty predicate denies. Fail-closed:\n * any thrown error or non-`true` result denies.\n */\nexport async function evaluateMutationGuard(args: {\n guard: MutationGuardDoc\n context: MutationContext\n}): Promise<boolean> {\n const {guard, context} = args\n if (guard.predicate === '') return false // alwaysDeny\n const params = {guard, mutation: {action: context.action}}\n try {\n const tree = parse(toGroqJsPredicate(guard.predicate), {mode: 'delta', params})\n const value = await evaluate(tree, {\n before: context.before,\n after: context.after,\n params,\n ...(context.identity !== undefined ? {identity: context.identity} : {}),\n })\n return (await value.get()) === true\n } catch {\n return false\n }\n}\n\n/**\n * Run every guard whose `match` applies and collect those that DENY. Empty\n * result ⇒ allowed (optimistically).\n */\nexport async function denyingGuards(args: {\n guards: MutationGuardDoc[]\n doc: {id: string; type?: string}\n context: MutationContext\n}): Promise<MutationGuardDoc[]> {\n const {guards, doc, context} = args\n const denied: MutationGuardDoc[] = []\n for (const guard of guards) {\n if (!guardMatches(guard, doc, context.action)) continue\n if (!(await evaluateMutationGuard({guard, context}))) denied.push(guard)\n }\n return denied\n}\n\nexport interface InstanceWriteDenialsArgs {\n /** The held instance — both `before` and `after` of the pre-flighted write\n * (the projection can't know the exact post-commit shape, so delta\n * predicates see \"no change\"). */\n instance: {_id: string; _type: string; workflowResource: {type: string; id: string}}\n guards: readonly MutationGuardDoc[]\n /** Actor id, resolved as `identity()` in predicates. */\n identity?: string\n}\n\n/**\n * The guards that would deny the engine's own write to the instance doc — the\n * `update` every action / tick commit performs. Only guards registered in the\n * instance's own datasource count: a guard enforces solely within the\n * datasource it lives in, so a same-id match from a foreign datasource can\n * never gate this write and must not flip verdicts.\n */\nexport async function instanceWriteDenials(\n args: InstanceWriteDenialsArgs,\n): Promise<MutationGuardDoc[]> {\n const {instance, guards, identity} = args\n const enforceable = guards.filter(\n (g) =>\n g.resourceType === instance.workflowResource.type &&\n g.resourceId === instance.workflowResource.id,\n )\n if (enforceable.length === 0) return []\n // Interfaces aren't assignable to `Record<string, unknown>`; callers pass\n // full WorkflowInstance docs, so predicates can read any instance field.\n const doc = instance as {_id: string; _type: string} & Record<string, unknown>\n return denyingGuards({\n guards: enforceable,\n doc: {id: instance._id, type: instance._type},\n context: {\n action: 'update',\n before: doc,\n after: doc,\n ...(identity !== undefined ? {identity} : {}),\n },\n })\n}\n\n/**\n * Fail-fast pre-flight for a commit sequence: throws\n * {@link MutationGuardDeniedError} before any write when a guard denies the\n * instance update — so a multi-step move (commit → deploy guards → effects)\n * is never entered when its first write is already doomed. Best-effort: a\n * guard can land between this check and the commit; the lake remains the\n * final arbiter and the rollback machinery stays the backstop.\n */\nexport async function assertInstanceWriteAllowed(args: InstanceWriteDenialsArgs): Promise<void> {\n const denied = await instanceWriteDenials(args)\n if (denied.length === 0) return\n throw MutationGuardDeniedError.fromGuards({\n documentId: args.instance._id,\n action: 'update',\n guards: denied,\n })\n}\n","/**\n * Per-stage instance state.\n *\n * The instance carries `stages: StageEntry[]` — one entry per stage the\n * instance has been in, in entry order. The CURRENT stage is the last\n * entry whose `exitedAt` is undefined. Past stages persist with\n * `exitedAt` set so the audit trail is complete.\n *\n * Each StageEntry owns its tasks. TaskEntry is the task's runtime state\n * (status, who/when, spawned subworkflows). Its `name` matches the\n * authoring `Task.name`.\n */\n\nimport type {GlobalDocumentReference} from '../core/refs.ts'\nimport type {TaskStatus} from './enums.ts'\nimport type {StageName, TaskName} from './ids.ts'\nimport type {ResolvedStateEntry} from './state-values.ts'\n\nexport interface TaskEntry {\n _key: string\n /** Matches the authoring `Task.name`. */\n name: TaskName\n status: TaskStatus\n startedAt?: string\n completedAt?: string\n completedBy?: string\n filterEvaluation?: {\n at: string\n truthy: boolean\n detail?: string\n }\n /**\n * Subworkflows started by this task (via `task.subworkflows`). Each entry\n * is a GDR pointing at an instance document. Used by ancestor propagation\n * to walk back up the tree, and rendered as `$subworkflows` for the task's\n * `completeWhen` / `failWhen`.\n */\n spawnedInstances?: GlobalDocumentReference[]\n /** Task-scoped resolved state entries. Absent until the engine writes to it. */\n state?: ResolvedStateEntry[]\n}\n\nexport interface StageEntry {\n _key: string\n name: StageName\n enteredAt: string\n /** Set on transition out; absent for the current stage. */\n exitedAt?: string\n /** Stage-scoped resolved state entries. */\n state: ResolvedStateEntry[]\n tasks: TaskEntry[]\n}\n\n/**\n * The open (un-exited) {@link StageEntry} matching `currentStage`, or\n * `undefined`. On loop-backs (re-entering a stage) several entries share\n * a name — the prior ones have `exitedAt` set, the current one does not.\n * Reads the `stages` + `currentStage` shape shared by the persisted\n * `WorkflowInstance` and the engine's mutable copy.\n */\nexport function findOpenStageEntry(host: {\n stages: StageEntry[]\n currentStage: StageName\n}): StageEntry | undefined {\n return host.stages.find((s) => s.name === host.currentStage && s.exitedAt === undefined)\n}\n","/**\n * Pure param transforms — the RENDERED read scope.\n *\n * The stored definition is boring, generic primitives; richness lives in the\n * scope the engine renders for conditions and bindings:\n *\n * `buildParams({instance, now, snapshot?, extra?})` — assemble the reserved\n * param bag every condition sees: `$self`, `$state`, `$parent`,\n * `$ancestors`, `$stage`, `$now`, `$effects`, `$tasks`, `$allTasksDone`,\n * `$anyTaskFailed`. Context-bound vars (`$actor`, `$assigned`, `$can`,\n * `$row`, `$subworkflows`) and the author's pre-evaluated predicates ride\n * in via `extra` — the shell composes them per evaluation context.\n *\n * `assignedFor(instance, taskName, actor)` — the `$assigned`\n * computation: does the caller match the task's `assignees`-kind state\n * entry (by user id or role)? No entry means false.\n *\n * `paramsForLake(params)` — strip GDR URIs back to bare ids for the shell\n * when it falls through to a lake fetch (discovery scans).\n *\n * No client. No I/O. The shell builds these and passes them to\n * `evaluateCondition` (also pure).\n */\n\nimport type {Actor} from '../types/actor.ts'\nimport {findOpenStageEntry} from '../types/instance-state.ts'\nimport type {WorkflowInstance} from '../types/instance.ts'\nimport type {Assignee, ResolvedStateEntry} from '../types/state-values.ts'\nimport {extractDocumentId, isGdrUri, selfGdr} from './refs.ts'\nimport type {HydratedSnapshot} from './snapshot.ts'\n\nexport interface BuildParamsArgs {\n instance: WorkflowInstance\n /** Shell-supplied clock reading — multiple evaluations in one pass agree on the time. */\n now: string\n /**\n * When supplied, `$state` doc-ref reads render the HYDRATED document\n * (`$state.subject.category`) instead of the bare reference envelope.\n * Hydration completeness is the shell's responsibility.\n */\n snapshot?: HydratedSnapshot\n extra?: Record<string, unknown>\n}\n\nexport function buildParams(args: BuildParamsArgs): Record<string, unknown> {\n const {instance, now, snapshot, extra} = args\n const currentTasks = findOpenStageEntry(instance)?.tasks ?? []\n return {\n self: selfGdr(instance),\n state: renderedState(instance.state ?? [], snapshot),\n parent: instance.ancestors.at(-1)?.id ?? null,\n ancestors: instance.ancestors.map((a) => a.id),\n stage: instance.currentStage,\n now,\n /** `$effects` — parent context handoff by entry name, completed-effect\n * outputs namespaced under the effect's name (`$effects['x.y'].out`). */\n effects: effectsContextMap(instance),\n /** `$tasks` — the current stage's task rows, statuses included. */\n tasks: currentTasks,\n allTasksDone: currentTasks.every((t) => t.status === 'done' || t.status === 'skipped'),\n anyTaskFailed: currentTasks.some((t) => t.status === 'failed'),\n ...extra,\n }\n}\n\n/**\n * `$state.<name>` resolves the entry's VALUE directly — no `.value`\n * envelope, no privileged entry name. Doc refs render the hydrated document\n * when the snapshot has it (release refs keep their envelope: `releaseName`\n * lives there). Task- and stage-scope entries ride in via the evaluation\n * context's `extra` ({@link scopedStateOverlay}) and shadow lexically.\n */\nfunction renderedState(\n entries: readonly ResolvedStateEntry[],\n snapshot: HydratedSnapshot | undefined,\n): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const entry of entries) out[entry.name] = renderedValue(entry, snapshot)\n return out\n}\n\nfunction renderedValue(entry: ResolvedStateEntry, snapshot: HydratedSnapshot | undefined): unknown {\n if (entry._type !== 'doc.ref' || entry.value === null || snapshot === undefined) {\n return entry.value\n }\n return snapshot.docs.find((d) => (d as {_id?: string})._id === entry.value!.id) ?? entry.value\n}\n\n/**\n * Overlay for stage-/task-scope state in the current evaluation context —\n * merged over the workflow-scope `$state` map so inner declarations shadow\n * outer ones, exactly like the deploy-time lexical resolution of writes.\n */\nexport function scopedStateOverlay(\n instance: WorkflowInstance,\n snapshot: HydratedSnapshot | undefined,\n taskName?: string,\n): Record<string, unknown> {\n const stageEntry = findOpenStageEntry(instance)\n if (stageEntry === undefined) return {}\n const stageState = renderedState(stageEntry.state ?? [], snapshot)\n const task = taskName ? stageEntry.tasks.find((t) => t.name === taskName) : undefined\n return {...stageState, ...renderedState(task?.state ?? [], snapshot)}\n}\n\n/**\n * The `$assigned` computation: true iff the caller matches the task's\n * `assignees`-kind state entry — a user item by id, a role item by\n * membership in `actor.roles`. No entry (or no actor) means false.\n */\nexport function assignedFor(\n instance: WorkflowInstance,\n taskName: string,\n actor: Actor | undefined,\n): boolean {\n if (actor === undefined) return false\n const task = findOpenStageEntry(instance)?.tasks.find((t) => t.name === taskName)\n const entry = task?.state?.find((s) => s._type === 'assignees')\n if (entry === undefined) return false\n return (entry.value as Assignee[]).some((a) =>\n a.type === 'user' ? a.id === actor.id : (actor.roles ?? []).includes(a.role),\n )\n}\n\n/**\n * Render `effectsContext` as the `$effects` map. `json` entries decode to\n * their object form so a completed effect's outputs read namespaced:\n * `$effects['<effect name>'].<output>`.\n */\nexport function effectsContextMap(instance: WorkflowInstance): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const entry of instance.effectsContext) {\n out[entry.name] =\n entry._type === 'effectsContext.json' ? parseJsonContextEntry(entry) : entry.value\n }\n return out\n}\n\n/** A json entry that fails to parse is corrupt lake data — fail with the\n * entry name attached so the bad write is traceable. */\nfunction parseJsonContextEntry(entry: {name: string; value: string}): unknown {\n try {\n return JSON.parse(entry.value)\n } catch (err) {\n throw new Error(\n `effectsContext entry \"${entry.name}\" holds unparseable JSON: ${\n err instanceof Error ? err.message : String(err)\n }`,\n {cause: err},\n )\n }\n}\n\n/**\n * Strip GDR URIs back to bare `_id`s on the reserved id params before\n * a lake fetch (discovery scans). Sanity refs are stored bare on disk,\n * so `releaseRef._ref == $state.release.id` only matches when the id is\n * bare in the lake query.\n *\n * Pure transform. Doesn't fetch. The shell decides when to call it.\n *\n * The `$state` map is walked recursively because rendered values can\n * carry GDRs (doc refs, hydrated docs keyed by GDR `_id`) that need\n * stripping for lake match predicates.\n */\nexport function paramsForLake(params: Record<string, unknown>): Record<string, unknown> {\n return {\n ...params,\n self: typeof params.self === 'string' ? bareId(params.self) : params.self,\n parent: typeof params.parent === 'string' ? bareId(params.parent) : params.parent,\n ancestors: Array.isArray(params.ancestors)\n ? params.ancestors.map((a) => (typeof a === 'string' ? bareId(a) : a))\n : params.ancestors,\n state: stripStateForLake(params.state),\n }\n}\n\nfunction stripStateForLake(value: unknown): unknown {\n if (value === null || value === undefined) return value\n if (typeof value === 'string') return bareId(value)\n if (Array.isArray(value)) return value.map(stripStateForLake)\n if (typeof value === 'object') {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n out[k] = stripStateForLake(v)\n }\n return out\n }\n return value\n}\n\nfunction bareId(id: string): string {\n return isGdrUri(id) ? extractDocumentId(id) : id\n}\n","/**\n * Shell-side lake-guard lifecycle: deploy and retract `temp.system.guard`\n * documents as a workflow enters and exits stages. NOT pure — resolves each\n * stage `Guard`'s `match.idRefs` / `metadata` Sources against the instance,\n * splits the resolved GDR into the guard's resource (resourceType/resourceId)\n * + bare ids, and writes via `clientForGdr` into that resource.\n *\n * Single-resource is enforced here: all idRefs of one guard must resolve to\n * the same datasource (the guard lives in and references only that one).\n *\n * \"Retract\" lifts the predicate to `\"true\"` (unconditionally allow) rather\n * than deleting — the `WorkflowClient` contract has no delete, and a loop-back\n * re-enters the stage and re-deploys the real predicate. POC simplification;\n * orphan accumulation + cross-dataset non-atomicity are documented seams.\n *\n * Reconcile runs post-persist, outside the instance's `ifRevisionId` guard, so\n * both primitives gate on the instance's live committed stage (see\n * {@link committedStage}) to drop stale / superseded reconciles. The window\n * between that live-stage read and the guard write is itself non-atomic across\n * resources — the same documented-seam direction (over-lock) as above.\n *\n * Enforcement is OPTIMISTIC: deploying a guard does not make the lake enforce\n * it. The engine evaluates guards itself (core/guards.ts); the bench throws.\n */\n\nimport {compileGuard, lakeGuardId} from './core/guards.ts'\nimport type {ParsedGdr} from './core/refs.ts'\nimport type {Guard, WorkflowDefinition} from './define/schema.ts'\nimport {\n assertSingleResource,\n bareIdRefs,\n resolveIdRefTargets,\n resolveMatchTypes,\n resolveMetadata,\n} from './guard-bindings.ts'\nimport type {MutationGuardDoc} from './types/authorization.ts'\nimport type {WorkflowClient} from './types/client.ts'\nimport type {WorkflowInstance} from './types/instance.ts'\n\nexport const GUARD_OWNER = 'robot:workflow-engine'\n/** Retracted predicate — unconditionally allows, lifting the guard. */\nexport const GUARD_LIFTED_PREDICATE = 'true'\n\ninterface ResolvedGuard {\n doc: MutationGuardDoc\n routeGdr: ParsedGdr\n}\n\n/**\n * Resolve a stage `Guard` into a persisted doc + the GDR to route the write.\n * Returns null when no target resolves to a GDR (e.g. `self` — instance-side\n * guards are deferred), or when targets span resources (rejected).\n */\nfunction resolveGuard(\n guard: Guard,\n instance: WorkflowInstance,\n stageName: string,\n now: string,\n): ResolvedGuard | null {\n const ctx = {instance, stageName, now}\n\n const targets = resolveIdRefTargets(guard.match.idRefs, ctx)\n if (targets === null) return null\n\n const resource = assertSingleResource(targets)\n const types = resolveMatchTypes(targets, guard.match.types)\n\n const doc = compileGuard({\n id: lakeGuardId({instanceDocId: instance._id, guardName: guard.name}),\n resourceType: resource.type,\n resourceId: resource.id,\n owner: GUARD_OWNER,\n sourceInstanceId: instance._id,\n sourceDefinition: instance.definition,\n sourceStage: stageName,\n name: guard.name,\n ...(guard.description !== undefined ? {description: guard.description} : {}),\n match: {\n ...(types !== undefined ? {types} : {}),\n idRefs: bareIdRefs(targets),\n ...(guard.match.idPatterns !== undefined ? {idPatterns: guard.match.idPatterns} : {}),\n actions: guard.match.actions,\n },\n predicate: guard.predicate ?? '',\n metadata: resolveMetadata(guard.metadata, ctx),\n })\n\n return {doc, routeGdr: targets[0]!.parsed}\n}\n\nasync function upsertGuard(client: WorkflowClient, doc: MutationGuardDoc): Promise<void> {\n const existing = await client.getDocument(doc._id)\n if (!existing) {\n await client.create(doc)\n return\n }\n // Patch the whole body (provenance included) so create and update can never\n // disagree on which fields they persist. System fields are lake-assigned.\n const {_id, _type, _rev, _createdAt, _updatedAt, ...body} = doc\n await client.patch(doc._id).set(body).commit()\n}\n\nexport interface StageGuardArgs {\n client: WorkflowClient\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient\n instance: WorkflowInstance\n definition: WorkflowDefinition\n stageName: string\n /** Shell-supplied clock reading (ISO) backing guard `$now` reads. */\n now: string\n}\n\n/** Resolve a stage's guards to their routed client + guard doc, skipping any that don't resolve. */\nfunction resolvedStageGuards(\n args: StageGuardArgs,\n): Array<{client: WorkflowClient; doc: MutationGuardDoc}> {\n const stage = args.definition.stages.find((s) => s.name === args.stageName)\n const out: Array<{client: WorkflowClient; doc: MutationGuardDoc}> = []\n for (const guard of stage?.guards ?? []) {\n const resolved = resolveGuard(guard, args.instance, args.stageName, args.now)\n if (resolved === null) continue\n out.push({client: args.clientForGdr(resolved.routeGdr), doc: resolved.doc})\n }\n return out\n}\n\n/**\n * Re-read the instance's committed state from the lake. Reconcile runs as a\n * post-persist step *outside* the instance's `ifRevisionId` guard, so a stale\n * or retried reconcile can land after a newer transition already moved the\n * instance on. Both reconcile primitives gate on this live state so they never\n * act on a stage the instance has since left. `undefined` means the instance\n * doc is gone (deleted out of band) — both primitives then no-op, leaving the\n * deployed guards untouched (the orphan seam's over-lock direction) rather than\n * blindly deploying for, or lifting the lock of, a vanished instance.\n */\nasync function committedInstance(args: StageGuardArgs): Promise<WorkflowInstance | undefined> {\n return (await args.client.getDocument<WorkflowInstance>(args.instance._id)) ?? undefined\n}\n\n/**\n * Deploy every guard for a stage being entered (idempotent upsert), but only\n * while the instance is still committed to that stage. A deploy that lost the\n * race to a newer transition would otherwise re-enforce a stage the instance\n * already left — a stale lock the newer transition's retract can't see. A\n * vanished instance (`undefined`) likewise no-ops: `undefined !== stageName`.\n *\n * An aborted instance also no-ops: it parks on its stage forever, so a stale\n * deploy landing after abort's retract would re-lock the subjects with no\n * remaining path to lift them. The gate is `abortedAt`, not `completedAt` —\n * a normal move *into* a terminal stage stamps `completedAt` in the same\n * persist and must still deploy that stage's guards.\n */\nexport async function deployStageGuards(args: StageGuardArgs): Promise<void> {\n const live = await committedInstance(args)\n if (live === undefined || live.currentStage !== args.stageName) return\n if (live.abortedAt !== undefined) return\n for (const {client, doc} of resolvedStageGuards(args)) {\n await upsertGuard(client, doc)\n }\n}\n\n/**\n * Retract every guard for a stage being exited (lift predicate to allow), but\n * only once the instance has genuinely moved off that stage — or was aborted\n * on it: an aborted instance keeps its `currentStage` (no stage move), so the\n * `abortedAt` stamp is what licenses lifting the stage it still occupies. The\n * gate is `abortedAt`, not `completedAt` — normal completion parks the\n * instance on a structurally terminal stage whose guards must stay enforced.\n * Skip if it is still live on the stage (a concurrent loop-back re-entered\n * the stage and must keep its lock) or gone (leave the lock as the orphan\n * seam rather than silently unlocking a vanished instance — the same\n * over-lock direction as deploy).\n */\nexport async function retractStageGuards(args: StageGuardArgs): Promise<void> {\n const live = await committedInstance(args)\n if (live === undefined) return\n if (live.currentStage === args.stageName && live.abortedAt === undefined) return\n for (const {client, doc} of resolvedStageGuards(args)) {\n const existing = await client.getDocument<MutationGuardDoc>(doc._id)\n if (!existing) continue\n await client.patch(doc._id).set({predicate: GUARD_LIFTED_PREDICATE}).commit()\n }\n}\n","/** Hex-encoded random key, sliced to {@link length} chars. Used for every\n * Sanity array `_key` and document id suffix the engine mints. */\nexport function randomKey(length = 12): string {\n const bytes = new Uint8Array(length)\n globalThis.crypto.getRandomValues(bytes)\n return [...bytes]\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n .slice(0, length)\n}\n","/**\n * Pure condition evaluation.\n *\n * A condition is a raw GROQ string over the rendered scope — the reserved\n * `$`-vars ({@link buildParams}) plus the author's nullary predicates bound\n * as boolean params. Runs groq-js against the hydrated snapshot.\n *\n * NO CLIENT. NO I/O. NO LAKE FALLBACK.\n *\n * Conditions evaluate against whatever the shell handed us — never against\n * the network. Purity is what lets the evaluator compose reactively: an\n * observable's snapshot updates can pipe straight into this function. If a\n * condition references a doc the shell didn't hydrate, groq-js sees a hole\n * and evaluates accordingly (usually false / null). Hydration completeness\n * is the shell's responsibility, not the core's.\n *\n * Discovery queries (`*[_type == 'X' && ...]` — `subworkflows.forEach`,\n * cross-doc lake scans) are NOT conditions. They live in a separate shell\n * primitive (`discoverItems`) and never come through here.\n */\n\nimport {evaluate, parse} from 'groq-js'\n\nimport type {HydratedSnapshot} from './snapshot.ts'\n\nexport interface EvaluateConditionArgs {\n condition: string | undefined\n snapshot: HydratedSnapshot\n params: Record<string, unknown>\n}\n\n/**\n * Evaluate a condition against the supplied snapshot. Returns true when no\n * condition is set (vacuous truth — e.g. an ungated action).\n */\nexport async function evaluateCondition(args: EvaluateConditionArgs): Promise<boolean> {\n const {condition, snapshot, params} = args\n if (condition === undefined) return true\n return Boolean(await runGroq(condition, params, snapshot))\n}\n\n/**\n * Pre-evaluate the definition's nullary predicates into the boolean params\n * conditions read as `$<name>`. A predicate can't be a plain param (a param\n * is a value, not an expression) and is never macro-spliced — each body is\n * evaluated against the BUILT-IN scope only and its boolean result bound.\n * GROQ is pure, so for boolean predicates this equals inlining; predicates\n * referencing other predicates are rejected at deploy.\n */\nexport async function evaluatePredicates(args: {\n predicates: Record<string, string> | undefined\n snapshot: HydratedSnapshot\n params: Record<string, unknown>\n}): Promise<Record<string, boolean>> {\n const out: Record<string, boolean> = {}\n for (const [name, groq] of Object.entries(args.predicates ?? {})) {\n out[name] = Boolean(await runGroq(groq, args.params, args.snapshot))\n }\n return out\n}\n\n/**\n * Evaluate one GROQ expression over the rendered scope. Shared by condition\n * evaluation (boolean) and effect-binding resolution (raw value). The\n * snapshot dataset is ALWAYS bound — a pure-param expression ignores it,\n * while `->` derefs and `*[...]` joins need it (gating on a `*` heuristic\n * silently nulled derefs).\n */\nexport async function runGroq(\n groq: string,\n params: Record<string, unknown>,\n snapshot: HydratedSnapshot,\n): Promise<unknown> {\n const tree = parse(groq, {params})\n const value = await evaluate(tree, {dataset: snapshot.docs, params})\n return value.get()\n}\n","/**\n * Pure snapshot construction.\n *\n * A `HydratedSnapshot` is an in-memory groq-js dataset of docs the\n * engine evaluator can query without touching the network. Inside it,\n * **every identity is a GDR URI** — `_id` on each top-level doc AND\n * every nested `_ref` value. That uniformity is what lets the snapshot\n * behave like a real groq-js store: `*[_id == $subject][0].team->name`\n * deref works because `_ref` URIs and `_id` URIs are in the same form;\n * `*[_id in $ancestors]...` joins work because both ends speak URI.\n *\n * The CORE rule: ids are rewritten in the snapshot, NEVER in the\n * underlying storage. Persistence stays bare. Sanity rejects `:` in\n * `_id`s, and `_ref` values inside stored docs are the bare ids Sanity\n * validated on write. The URI form is a runtime concept; the bench /\n * shell loads docs in their storage form and hands them to the core,\n * which restamps them for snapshot keying.\n *\n * **A `_ref` inside a doc is always assumed to point at a doc in the\n * same resource as its containing doc** — that's how Sanity\n * references work (same dataset, validated on write). The rewriter\n * uses the parent doc's resource to construct the GDR URI for each\n * nested `_ref`. Cross-resource refs would need an explicit envelope\n * (out of scope for now).\n */\n\nimport type {SanityDocument} from '@sanity/types'\n\nimport {gdrFromResource, type WorkflowResource} from './refs.ts'\n\n/**\n * The in-memory groq-js dataset filters evaluate against. Built once\n * per cascade entry (in the shell), passed through to `evaluateFilter`\n * (in the core) for every filter check.\n */\nexport interface HydratedSnapshot {\n /** All hydrated docs, keyed by GDR URI as `_id`. */\n docs: SanityDocument[]\n /**\n * The set of GDR URIs present in `docs`. Helpful for tests and shells\n * that want to assert \"is this doc in scope?\" — the core eval pipeline\n * itself doesn't read it.\n */\n knownIds: Set<string>\n}\n\n/**\n * One loaded doc plus the resource it came from. The shell builds\n * this list by routing reads to the right client for each doc, then\n * hands it to `buildSnapshot`.\n */\nexport interface LoadedDoc {\n doc: SanityDocument\n resource: WorkflowResource\n}\n\n/**\n * Build a snapshot from a set of loaded docs. Pure transform.\n *\n * For each `LoadedDoc { doc, resource }`:\n * - The doc's `_id` is rewritten to `gdrFromResource(resource, _id)`.\n * - Every nested `_ref` value (recursively, through objects and arrays)\n * is rewritten the same way: bare ref → URI in the parent's resource.\n * Already-qualified `_ref` URIs (containing `:`) are left alone.\n *\n * Plain string fields, numbers, booleans — anything that isn't an\n * object with a `_ref` field — pass through untouched. The rewriter is\n * structural, not schema-aware: only the `_ref` field on an object is\n * treated as a Sanity reference. Everything else is user data.\n */\nexport function buildSnapshot(args: {docs: LoadedDoc[]}): HydratedSnapshot {\n const docs: SanityDocument[] = []\n const knownIds = new Set<string>()\n for (const {doc, resource} of args.docs) {\n const uri = gdrFromResource(resource, doc._id)\n const restamped = restampForSnapshot(doc, uri, resource)\n docs.push(restamped)\n knownIds.add(uri)\n }\n return {docs, knownIds}\n}\n\n/**\n * Restamp a single doc for the snapshot — rewrite `_id` to the given\n * GDR URI, recursively rewrite every nested `_ref` to a GDR URI in the\n * doc's own resource. Pure; doesn't mutate the input.\n */\nfunction restampForSnapshot<T extends SanityDocument>(\n doc: T,\n gdrUri: string,\n resource: WorkflowResource,\n): T {\n const rewritten = rewriteRefsRecursive(doc, resource) as T\n return {...rewritten, _id: gdrUri}\n}\n\n/**\n * Walk an arbitrary JSON-ish value and rewrite every `_ref` field on\n * an object to its GDR URI form (in `resource`). Other fields and\n * non-object values pass through unchanged.\n */\nfunction rewriteRefsRecursive(value: unknown, resource: WorkflowResource): unknown {\n if (Array.isArray(value)) {\n return value.map((v) => rewriteRefsRecursive(v, resource))\n }\n if (value === null || typeof value !== 'object') return value\n const obj = value as Record<string, unknown>\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(obj)) {\n if (k === '_ref' && typeof v === 'string') {\n // Already-qualified URIs (cross-resource refs) pass through.\n out[k] = v.includes(':') ? v : gdrFromResource(resource, v)\n } else {\n out[k] = rewriteRefsRecursive(v, resource)\n }\n }\n return out\n}\n","// Instance — the persisted instance document (see WORKFLOW_INSTANCE_TYPE).\n\nimport type {SanityDocument} from '@sanity/types'\n\nimport type {GlobalDocumentReference, WorkflowResource} from '../core/refs.ts'\nimport type {WorkflowDefinition} from '../define/schema.ts'\nimport type {WorkflowPerspective} from './client.ts'\nimport type {EffectHistoryEntry, EffectsContextEntry, PendingEffect} from './effects.ts'\nimport type {HistoryEntry} from './history.ts'\nimport type {StageName} from './ids.ts'\nimport type {StageEntry} from './instance-state.ts'\nimport type {ResolvedStateEntry} from './state-values.ts'\n\n/**\n * The lake document type for a workflow instance. Single source of truth — the\n * {@link WorkflowInstance} `_type`, every tag-scoped query, and the create\n * write all derive from here, mirroring {@link WORKFLOW_DEFINITION_TYPE}.\n * Engine-owned standalone documents carry the platform namespace.\n */\nexport const WORKFLOW_INSTANCE_TYPE = 'sanity.workflow.instance'\n\nexport interface WorkflowInstance extends SanityDocument {\n _type: typeof WORKFLOW_INSTANCE_TYPE\n /**\n * Engine-scope tags stamped on the instance at create time. Engines\n * with disjoint tag sets cannot read this instance; engines sharing\n * any tag with this array can.\n */\n tags: string[]\n /**\n * The Sanity resource this instance lives in. Stored on the doc so\n * any internal operation can mint GDRs for ancestors / spawned\n * children / etc. without re-supplying it. Mirrors\n * `@sanity/client`'s `ClientConfigResource`.\n */\n workflowResource: WorkflowResource\n /** Reference to the deployed definition, by its `name`. */\n definition: string\n pinnedVersion: number\n /** Frozen JSON snapshot of the definition at the moment the instance started. */\n definitionSnapshot: string\n /**\n * Workflow-level resolved state entries.\n * Populated from the workflow definition's `state[]` declarations plus\n * the caller-supplied `initialState` at `startInstance`. Persists for\n * the lifetime of the instance.\n *\n * To declare \"the subject document of this workflow\", add a\n * `{ type: \"doc.ref\", name: \"subject\", source: { type: \"init\" } }`\n * entry to the workflow definition. Conditions then read it as\n * `$state.subject`. There is no other subject mechanism.\n */\n state: ResolvedStateEntry[]\n /**\n * Stable named params the runtime hands to effect handlers via binding\n * resolution. Set at `startInstance`. **Not read by transition filters.**\n */\n effectsContext: EffectsContextEntry[]\n /**\n * Chain of ancestor workflow instances, root-first. Each entry is a\n * GDR pointing at a {@link WORKFLOW_INSTANCE_TYPE} document in the\n * engine's own workflow resource.\n */\n ancestors: GlobalDocumentReference[]\n /**\n * Optional perspective applied to state-entry query reads and spawn\n * `forEach.groq` discovery. When unset the engine treats reads as\n * `\"raw\"` (no filtering). Set at `startInstance` time to scope a\n * workflow's reads to a Content Release stack (e.g. `[releaseName]`\n * or `[releaseName, \"drafts\"]`).\n *\n * Engine-internal reads of instance / definition documents are\n * always raw, regardless of this field.\n */\n perspective?: WorkflowPerspective\n currentStage: StageName\n /**\n * Per-stage instance entries — one StageEntry per stage the instance\n * has been in, in entry order. Past stages persist with `exitedAt`\n * set; the current stage is the entry whose `exitedAt` is undefined.\n * Each entry owns its tasks.\n */\n stages: StageEntry[]\n pendingEffects: PendingEffect[]\n effectHistory: EffectHistoryEntry[]\n history: HistoryEntry[]\n startedAt: string\n lastChangedAt: string\n completedAt?: string\n /**\n * Set (to the same instant as `completedAt`) when the instance was\n * hard-stopped via `abortInstance` rather than reaching a terminal\n * stage. `completedAt` is always stamped alongside it so every\n * \"in-flight\" query (`!defined(completedAt)`) treats aborted and\n * completed instances uniformly; this field is what distinguishes them.\n */\n abortedAt?: string\n}\n\n/**\n * The ONE way to read an instance's frozen {@link WorkflowInstance.definitionSnapshot}\n * back into a {@link WorkflowDefinition} — wraps the parse so a corrupt\n * snapshot fails with the instance id attached instead of a bare\n * `SyntaxError`.\n */\nexport function parseDefinitionSnapshot(instance: WorkflowInstance): WorkflowDefinition {\n try {\n return JSON.parse(instance.definitionSnapshot) as WorkflowDefinition\n } catch (err) {\n throw new Error(\n `Failed to parse definitionSnapshot on instance \"${instance._id}\": ${\n err instanceof Error ? err.message : String(err)\n }`,\n {cause: err},\n )\n }\n}\n","/**\n * The reactive watch-set: which documents an instance's evaluation\n * depends on.\n *\n * A consumer that wants to drive the engine from live data subscribes\n * to exactly these docs, rebuilds the snapshot when any of them change,\n * and re-evaluates ({@link evaluateFromSnapshot}). The engine owns no\n * subscription itself — it only says *what* to watch.\n *\n * Pure: derivable from the persisted instance alone (resolved\n * `doc.ref`/`doc.refs`/`release.ref` state entry GDRs on the workflow scope +\n * current stage, `instance.ancestors`, and the instance itself). No I/O.\n * This is the \"which ids\" half that {@link hydrateSnapshot} loads — both\n * derive the set from {@link collectWatchRefs}, so there is one source of\n * truth.\n */\n\nimport {\n type GdrUri,\n type GlobalDocumentReference,\n gdrRef,\n isGdr,\n isGdrUri,\n type ParsedGdr,\n parseGdr,\n} from './core/refs.ts'\nimport type {WorkflowPerspective} from './types/client.ts'\nimport {findOpenStageEntry} from './types/instance-state.ts'\nimport {WORKFLOW_INSTANCE_TYPE, type WorkflowInstance} from './types/instance.ts'\n\n/**\n * A document the reactive layer should subscribe to, with its GDR\n * exploded so consumers never re-parse: the resource-addressing parts\n * (from {@link ParsedGdr}), the round-trip `globalDocumentId` URI, and\n * the target doc's schema `_type`. The resource parts let an adapter\n * detect refs pointing at a project/dataset/resource it isn't\n * configured for; `type` feeds per-doc handles (`useDocument` /\n * `editState`).\n */\nexport interface SubscriptionDocument extends ParsedGdr {\n /** Full GDR URI — resource-qualified identity, for round-trip / snapshot keying. */\n globalDocumentId: GdrUri\n /** Target doc's schema `_type`. */\n type: string\n}\n\n/**\n * Every {@link GlobalDocumentReference} an instance's evaluation reads:\n * the instance itself, its ancestors, the **content** docs named by\n * resolved `doc.ref`/`doc.refs` state entries, and the **release** docs named by\n * `release.ref` state entries — on the workflow scope and the current stage.\n * Order: self, ancestors, content state entries, release state entries. May contain\n * duplicates and non-GDR ids — the loader and\n * {@link subscriptionDocumentsForInstance} handle those respectively.\n */\nexport function collectWatchRefs(instance: WorkflowInstance): GlobalDocumentReference[] {\n const stage = findOpenStageEntry(instance)\n return [\n gdrRef(instance.workflowResource, instance._id, instance._type),\n ...instance.ancestors,\n ...entryDocRefs(instance.state),\n ...entryDocRefs(stage?.state),\n ...entryReleaseRefs(instance.state),\n ...entryReleaseRefs(stage?.state),\n ]\n}\n\n/**\n * Whether a watched ref reads RAW — never perspective-scoped. The\n * instance, its ancestors (both instance docs), and `release.ref`\n * system docs (`system.release`) are not versioned by a release\n * perspective; everything else is content and resolves to its\n * version/draft/published form. This is the single encoding of the rule\n * the {@link WatchSet} `perspective` contract describes to consumers, and\n * the rule {@link hydrateSnapshot} applies on the fetch side.\n */\nexport function readsRaw(ref: {type: string}): boolean {\n return ref.type === WORKFLOW_INSTANCE_TYPE || ref.type === 'system.release'\n}\n\n/**\n * The Content Release a watched doc resolves under, or `undefined` for a raw\n * read — how a reactive adapter turns the watch-set's perspective into the\n * per-doc release its store needs. Instance / ancestor / `system.release` docs\n * read raw ({@link readsRaw}); a content doc resolves under the **leading**\n * release in the stack. The engine never forms the `versions.<release>.<id>`\n * id — the adapter does (Studio's `editState` version arg, the SDK handle\n * `{releaseName}`). A non-array perspective (`raw`/`published`/`drafts`)\n * carries no release, so content falls back to draft/published.\n *\n * Note: this resolves a **single** release — the documented `instance.perspective`\n * shapes (`[release]` / `[release, \"drafts\"]`). The stores' per-doc reads take\n * one release, so a multi-release stack can't be observed reactively here; the\n * engine's own fetch path ({@link hydrateSnapshot}) honours the full stack via\n * `client.fetch({perspective})`.\n */\nexport function contentReleaseName(args: {\n ref: {type: string}\n perspective: WorkflowPerspective | undefined\n}): string | undefined {\n const {ref, perspective} = args\n if (readsRaw(ref)) return undefined\n if (!Array.isArray(perspective)) return undefined\n return perspective.find((entry) => entry !== 'drafts' && entry !== 'published' && entry !== 'raw')\n}\n\n/**\n * The reactive subscription target for an instance: the exploded,\n * deduped watch-set plus the instance's read {@link WorkflowPerspective}.\n */\nexport interface WatchSet {\n /**\n * Docs to subscribe to — instance + ancestors + the docs named by\n * `doc.ref`/`doc.refs`/`release.ref` state entries — deduped by\n * `globalDocumentId`. Refs that aren't resource-qualified GDR URIs are\n * skipped (without a resource there's nothing to subscribe against).\n */\n documents: SubscriptionDocument[]\n /**\n * The instance's effective read perspective (a release stack like\n * `[releaseName]` or `[releaseName, \"drafts\"]`), already resolved at\n * `startInstance`. `undefined` means raw/published.\n *\n * The engine does not form `versions.<release>.<id>` ids — it has no\n * such concept (it reads content through `client.fetch({perspective})`\n * for queries). A reactive consumer applies this perspective when it\n * subscribes: a **content** doc must be resolved to its version /\n * draft / published form (e.g. Studio `editState`'s version param, or\n * the SDK's `getVersionId`), while instance / ancestor / `system.release`\n * docs are always raw. The `type` on each {@link SubscriptionDocument}\n * tells the consumer which is which.\n */\n perspective?: WorkflowPerspective\n}\n\n/**\n * Build one {@link SubscriptionDocument} from a {@link GlobalDocumentReference}:\n * the parsed addressing parts plus the round-trip URI and schema `_type`.\n * Exported so adapter tests build fixtures exactly the way production does.\n */\nexport function subscriptionDocument(ref: GlobalDocumentReference): SubscriptionDocument {\n return {...parseGdr(ref.id), globalDocumentId: ref.id, type: ref.type}\n}\n\nexport function subscriptionDocumentsForInstance(instance: WorkflowInstance): WatchSet {\n const seen = new Set<string>()\n const documents: SubscriptionDocument[] = []\n for (const ref of collectWatchRefs(instance)) {\n if (!isGdrUri(ref.id) || seen.has(ref.id)) continue\n seen.add(ref.id)\n documents.push(subscriptionDocument(ref))\n }\n return {\n documents,\n ...(instance.perspective !== undefined ? {perspective: instance.perspective} : {}),\n }\n}\n\n/**\n * Pull the {@link GlobalDocumentReference} values out of `doc.ref` /\n * `doc.refs` (content) state entries. Content only — release state entries come\n * from {@link entryReleaseRefs}, so guard discovery (which reads this via\n * `collectEntryDocUris`) stays scoped to content docs.\n */\nexport function entryDocRefs(state: unknown): GlobalDocumentReference[] {\n return stateEntries(state).flatMap((entry) => {\n if (entry._type === 'doc.ref') {\n return isGdr(entry.value) ? [entry.value] : []\n }\n if (entry._type === 'doc.refs') {\n return Array.isArray(entry.value) ? entry.value.filter(isGdr) : []\n }\n return []\n })\n}\n\n/**\n * Pull the {@link GlobalDocumentReference} values out of `release.ref`\n * state entries — a `release.ref` value is a `ReleaseRef`, a GDR\n * (`type: \"system.release\"`) pointing at the `_.releases.<name>` system\n * doc, so a release changing re-evaluates the instance. Separate from\n * {@link entryDocRefs}: release docs are watched but read RAW (a release\n * perspective doesn't version a system doc), and guard discovery must not\n * follow them.\n */\nfunction entryReleaseRefs(state: unknown): GlobalDocumentReference[] {\n return stateEntries(state).flatMap((entry) =>\n entry._type === 'release.ref' && isGdr(entry.value) ? [entry.value] : [],\n )\n}\n\n/**\n * Narrow a polymorphic resolved-state entry array to the `{_type, value}` shape\n * the ref extractors read. Tolerates `unknown` (resolved state entry arrays are\n * polymorphic) and drops non-object entries.\n */\nfunction stateEntries(state: unknown): {_type?: string; value?: unknown}[] {\n if (!Array.isArray(state)) return []\n return state.filter(\n (entry): entry is {_type?: string; value?: unknown} => !!entry && typeof entry === 'object',\n )\n}\n","/**\n * Shell-side snapshot hydration.\n *\n * The core defines `HydratedSnapshot`, `LoadedDoc`, and the pure\n * `buildSnapshot` transform (recursive `_ref` + `_id` rewriting to\n * GDR URIs). This module does the I/O: route each read to the right\n * resource client, gather loaded docs with their resource attribution,\n * hand the list to `buildSnapshot`.\n *\n * **Scope rule (the contract):** a doc is in the snapshot iff it is\n * - the workflow instance itself,\n * - any ancestor doc (from `instance.ancestors[].id`),\n * - a doc declared by a `doc.ref` / `doc.refs` state entry on\n * the workflow OR the current stage,\n * - or the `system.release` doc named by a `release.ref` state entry.\n *\n * Authors who want their filters to read a referenced doc via `->`\n * deref MUST declare a doc.ref / doc.refs entry pointing at it. The\n * shell loads exactly what's declared; the core rewrites refs purely\n * over that set. No transitive crawling; no surprise hops.\n *\n * **Perspective:** content docs (`doc.ref`/`doc.refs`) are read under the\n * instance's `perspective` so a workflow in a Content Release sees its\n * subject's version content. The instance, ancestors (both instance\n * documents), and `release.ref` system docs are always read RAW\n * — per the engine contract, and because a release perspective doesn't\n * version those.\n */\n\nimport type {SanityDocument} from '@sanity/types'\n\nimport {parseGdr, selfGdr, type ParsedGdr, type WorkflowResource} from './core/refs.ts'\nimport {buildSnapshot, type HydratedSnapshot, type LoadedDoc} from './core/snapshot.ts'\nimport {collectWatchRefs, readsRaw, entryDocRefs} from './subscription-documents.ts'\nimport type {WorkflowClient, WorkflowPerspective} from './types/client.ts'\nimport type {WorkflowInstance} from './types/instance.ts'\n\n/**\n * Build the in-memory snapshot for filter evaluation on the instance's\n * current stage. Routed reads, then pure construction.\n *\n * The set of docs loaded is exactly {@link collectWatchRefs} — the same\n * watch-set {@link subscriptionDocumentsForInstance} emits, so the\n * reactive read path and the fetch path stay in lockstep. The instance\n * itself is already in hand, so it's pushed directly; everything else is\n * routed through `clientForGdr`.\n *\n * A doc that resolves to `null` (missing, or ACL-filtered to nothing)\n * simply isn't in the snapshot — predicates referencing it see\n * `null` / empty results. A read that *throws* (client/transport error)\n * propagates and fails the whole hydration; it is not swallowed.\n */\nexport async function hydrateSnapshot(args: {\n client: WorkflowClient\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient\n instance: WorkflowInstance\n /**\n * Content overlay — doc values the consumer already holds, keyed by GDR\n * URI. An id present here is used as-is (last-write-wins, scoped to the\n * watch-set); absent ids are loaded. The reactive session supplies this\n * so held content isn't refetched; absent → today's fetch behaviour.\n */\n overlay?: ReadonlyMap<string, LoadedDoc>\n}): Promise<HydratedSnapshot> {\n const {client, clientForGdr, instance, overlay} = args\n const loaded: LoadedDoc[] = []\n const visited = new Set<string>()\n\n const loadInto = async (\n uri: string,\n perspective: WorkflowPerspective | undefined,\n ): Promise<void> => {\n if (visited.has(uri)) return\n const held = overlay?.get(uri)\n if (held !== undefined) {\n loaded.push(held)\n visited.add(uri)\n return\n }\n const fetched = await loadByGdr(\n client,\n clientForGdr,\n instance.workflowResource,\n uri,\n perspective,\n )\n if (fetched) {\n loaded.push(fetched)\n visited.add(uri)\n }\n }\n\n // The instance itself is already loaded. Push it directly and key it\n // with the same GDR-URI form `buildSnapshot` uses, so a self-\n // referential ancestor/state entry dedups against it (collectWatchRefs lists\n // self first, but loadInto will skip it as already-visited).\n loaded.push({doc: instance, resource: instance.workflowResource})\n visited.add(selfGdr(instance))\n\n // Content docs honor the instance's perspective; instance / ancestor /\n // release docs read RAW (see {@link readsRaw} — the one home for that\n // rule, shared with the WatchSet contract the reactive consumer follows).\n for (const ref of collectWatchRefs(instance)) {\n await loadInto(ref.id, readsRaw(ref) ? undefined : instance.perspective)\n }\n\n return buildSnapshot({docs: loaded})\n}\n\nasync function loadByGdr(\n defaultClient: WorkflowClient,\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient,\n defaultResource: WorkflowResource,\n uri: string,\n perspective: WorkflowPerspective | undefined,\n): Promise<LoadedDoc | null> {\n let parsed: ParsedGdr\n try {\n parsed = parseGdr(uri)\n } catch {\n // Not a GDR URI — load the value directly against the default\n // client. Without a parsed GDR we can't know the resource, so we\n // attribute the doc to the default client's own resource.\n const doc = await readDoc(defaultClient, uri, perspective)\n if (!doc) return null\n return {doc, resource: defaultResource}\n }\n const routed = clientForGdr(parsed)\n const doc = await readDoc(routed, parsed.documentId, perspective)\n if (!doc) return null\n return {doc, resource: resourceFromParsed(parsed)}\n}\n\n/**\n * Read one doc by id, honoring the instance's read perspective. Without\n * a perspective it's a raw point read (`getDocument`). With one — a\n * release stack like `[releaseName]` — the read goes through\n * `fetch(..., {perspective})` so version/draft content is projected onto\n * the published id and a content doc that exists only inside a release is\n * still visible to filters. Mirrors how state-entry query resolution\n * already reads under perspective. The caller decides which reads are\n * perspective-scoped (content) vs raw — see {@link readsRaw}.\n */\nasync function readDoc(\n client: WorkflowClient,\n id: string,\n perspective: WorkflowPerspective | undefined,\n): Promise<SanityDocument | null> {\n if (perspective === undefined) {\n return (await client.getDocument<SanityDocument>(id)) ?? null\n }\n const doc = await client.fetch<SanityDocument | null>('*[_id == $id][0]', {id}, {perspective})\n return doc ?? null\n}\n\nexport function resourceFromParsed(parsed: ParsedGdr): WorkflowResource {\n if (parsed.scheme === 'dataset') {\n return {type: 'dataset', id: `${parsed.projectId}.${parsed.dataset}`}\n }\n return {type: parsed.scheme, id: parsed.resourceId ?? ''}\n}\n\n/**\n * Walk resolved state entries and collect every GDR URI mentioned by a\n * `doc.ref` or `doc.refs` state entry's value. The GDR-keyed id list lake\n * guard discovery needs; {@link entryDocRefs} is the typed source.\n */\nexport function collectEntryDocUris(resolvedStateEntries: unknown): string[] {\n return entryDocRefs(resolvedStateEntries).map((ref) => ref.id)\n}\n","/**\n * Per-state entry-type value validation.\n *\n * Every write into a typed state entry must match the state entry's declared shape.\n * The validator is called at three boundaries:\n *\n * 1. `workflow.op.state.set` — full-value replace on any state entry\n * 2. `workflow.op.state.append` — one-item push on array state entries\n * 3. `resolveDeclaredState` — init / literal / stateRead / query\n *\n * `validateStateValue` checks a complete state entry value against the state entry\n * type's shape (scalar or array-of-items, depending on the kind).\n *\n * `validateStateAppendItem` checks a single item against the state entry's\n * row shape (only array state entries support append).\n *\n * Both throw `StateValueShapeError` with the state entry id, state entry type and a\n * brief description of the observed shape — so the cause is obvious\n * in test output, drive-script stdout, and the workflow history.\n *\n * Notes stays permissive (any object with optional `_key`) pending a\n * dedicated row-shape design.\n */\n\nimport * as v from 'valibot'\n\nimport {isGdrUri} from './refs.ts'\n\nclass StateValueShapeError extends Error {\n readonly entryType: string\n readonly entryName: string\n readonly issues: string[]\n\n constructor(args: {\n entryType: string\n entryName: string\n issues: string[]\n mode: 'value' | 'item'\n }) {\n const issueText = args.issues.join('; ')\n super(\n `State entry ${args.mode} shape invalid for \"${args.entryName}\" (${args.entryType}): ${issueText}`,\n )\n this.name = 'StateValueShapeError'\n this.entryType = args.entryType\n this.entryName = args.entryName\n this.issues = args.issues\n }\n}\n\n// Per-shape schemas — used both for whole-value and per-item validation.\n\nconst GdrShape = v.looseObject({\n id: v.pipe(\n v.string(),\n v.check((s) => isGdrUri(s), 'must be a GDR URI'),\n ),\n type: v.pipe(v.string(), v.minLength(1)),\n})\n\n// Release ref: a GDR to the `_.releases.<name>` system doc, plus the\n// bare release name the engine reads to derive perspective.\nconst ReleaseRefShape = v.looseObject({\n id: v.pipe(\n v.string(),\n v.check((s) => isGdrUri(s), 'must be a GDR URI'),\n ),\n type: v.literal('system.release'),\n releaseName: v.pipe(v.string(), v.minLength(1)),\n})\n\nconst ActorShape = v.looseObject({\n kind: v.picklist(['user', 'ai', 'system']),\n id: v.pipe(v.string(), v.minLength(1)),\n roles: v.optional(v.array(v.string())),\n onBehalfOf: v.optional(v.string()),\n})\n\nconst AssigneeShape = v.union([\n v.looseObject({type: v.literal('user'), id: v.pipe(v.string(), v.minLength(1))}),\n v.looseObject({type: v.literal('role'), role: v.pipe(v.string(), v.minLength(1))}),\n])\n\nconst ChecklistItemShape = v.looseObject({\n label: v.pipe(v.string(), v.minLength(1)),\n done: v.boolean(),\n doneBy: v.optional(v.string()),\n doneAt: v.optional(v.string()),\n _key: v.optional(v.pipe(v.string(), v.minLength(1))),\n})\n\n// Notes are intentionally loose pending the row-shape design.\nconst NoteItemShape = v.pipe(\n v.looseObject({\n _key: v.optional(v.pipe(v.string(), v.minLength(1))),\n }),\n v.check(\n (val) => typeof val === 'object' && val !== null && !Array.isArray(val),\n 'must be an object',\n ),\n)\n\n// Scalars that allow null (write-sourced state entries default to null until written).\nconst NullableString = v.union([v.null(), v.string()])\nconst NullableNumber = v.union([v.null(), v.number()])\nconst NullableBoolean = v.union([v.null(), v.boolean()])\n\n// dateTime: stricter than plain string — must parse as ISO-8601.\nconst NullableDateTime = v.union([\n v.null(),\n v.pipe(\n v.string(),\n v.check((s) => !Number.isNaN(Date.parse(s)), 'must be an ISO-8601 datetime string'),\n ),\n])\n\n// URL: loose — accept any non-empty string. Tightening later is easy;\n// loosening would break already-stored values.\nconst NullableUrl = NullableString\n\n// Whole-value schemas, keyed by state entry type.\n\nconst valueSchemas = {\n 'doc.ref': v.union([v.null(), GdrShape]),\n 'doc.refs': v.array(GdrShape),\n 'release.ref': v.union([v.null(), ReleaseRefShape]),\n query: v.any(),\n 'value.string': NullableString,\n 'value.url': NullableUrl,\n 'value.number': NullableNumber,\n 'value.boolean': NullableBoolean,\n 'value.dateTime': NullableDateTime,\n 'value.actor': v.union([v.null(), ActorShape]),\n checklist: v.array(ChecklistItemShape),\n notes: v.array(NoteItemShape),\n assignees: v.array(AssigneeShape),\n} as const\n\n// Per-item schemas for `workflow.op.state.append`. Scalar state entry types\n// don't support append — callers asking for them get an error.\n\nconst itemSchemas = {\n 'doc.refs': GdrShape,\n checklist: ChecklistItemShape,\n notes: NoteItemShape,\n assignees: AssigneeShape,\n} as const\n\ntype AppendableStateKind = keyof typeof itemSchemas\n\nfunction isAppendable(entryType: string): entryType is AppendableStateKind {\n return entryType in itemSchemas\n}\n\n// Public API.\n\nexport function validateStateValue(args: {\n entryType: string\n entryName: string\n value: unknown\n}): void {\n const schema = (valueSchemas as Record<string, v.GenericSchema>)[args.entryType]\n if (schema === undefined) {\n throw new StateValueShapeError({\n entryType: args.entryType,\n entryName: args.entryName,\n issues: [`unknown state entry type ${args.entryType}`],\n mode: 'value',\n })\n }\n const result = v.safeParse(schema, args.value)\n if (!result.success) {\n throw new StateValueShapeError({\n entryType: args.entryType,\n entryName: args.entryName,\n issues: formatIssues(result.issues),\n mode: 'value',\n })\n }\n}\n\nexport function validateStateAppendItem(args: {\n entryType: string\n entryName: string\n item: unknown\n}): void {\n if (!isAppendable(args.entryType)) {\n throw new StateValueShapeError({\n entryType: args.entryType,\n entryName: args.entryName,\n issues: [`state entry type ${args.entryType} does not support append`],\n mode: 'item',\n })\n }\n const schema = itemSchemas[args.entryType]\n const result = v.safeParse(schema, args.item)\n if (!result.success) {\n throw new StateValueShapeError({\n entryType: args.entryType,\n entryName: args.entryName,\n issues: formatIssues(result.issues),\n mode: 'item',\n })\n }\n}\n\nfunction formatIssues(issues: readonly v.BaseIssue<unknown>[]): string[] {\n return issues.map((i) => {\n const keys = i.path?.map((p) => p.key) ?? []\n const path = keys.length > 0 ? `at ${keys.join('.')}: ` : ''\n return `${path}${i.message}`\n })\n}\n","/**\n * Resolve a definition's `state[]` declarations into `ResolvedStateEntry`s.\n *\n * Shared by:\n * - `workflow.startInstance` (workflow-scope state)\n * - engine stage entry (stage-scope state on StageEntry)\n * - engine task activation (task-scope state on TaskEntry)\n *\n * Source-kind semantics:\n * - `type: \"init\"` reads from caller-supplied `initialState`.\n * - `type: \"query\"` runs the entry's GROQ against the lake via the\n * supplied client; result lands as the entry value with `resolvedAt`\n * stamped on `query`-kind entries.\n * - `type: \"write\"` defaults to null (scalars) or `[]` (array kinds);\n * ops fill it later.\n */\n\nimport {paramsForLake} from './core/params.ts'\nimport {getPath} from './core/path.ts'\nimport {gdrFromResource, isGdrUri, type WorkflowResource} from './core/refs.ts'\nimport {validateStateValue} from './core/state-validation.ts'\nimport type {StateEntry} from './define/schema.ts'\nimport type {WorkflowClient, WorkflowPerspective} from './types/client.ts'\nimport type {InitialStateValue, ResolvedStateEntry} from './types/state-values.ts'\n\nexport interface ResolveStateContext {\n /** Lake client for `type: \"query\"` entry evaluation. Omitted → query\n * state entries fall back to their default value. */\n client?: WorkflowClient\n /**\n * Shell-supplied clock reading (ISO). Bound as `$now` for query-entry\n * GROQ and stamped as `resolvedAt` on `query`-kind entries, so\n * state resolution shares the engine's single {@link Clock}.\n */\n now: string\n selfId?: string\n tags?: string[]\n /** Bound to `$stage` inside stage/task-scope query entries. */\n stageName?: string\n /** Bound to `$task` inside task-scope query entries. */\n taskName?: string\n /**\n * Already-resolved state entries in the SAME scope being resolved\n * right now. Exposed to subsequent query-sourced state entries as\n * `$state.<entryName>`; also the lookup target for\n * `source: { type: \"stateRead\", scope: \"stage\" }` on a sibling\n * stage-scope entry. Sequential resolution means entry N's source can\n * read state entries 0..N-1 by id but not later ones.\n */\n resolvedState?: ResolvedStateEntry[]\n /**\n * Already-resolved workflow-scope state. Available when resolving\n * stage- or task-scope state entries so a `source: { type: \"stateRead\",\n * scope: \"workflow\" }` can read durable workflow-scope state entries that\n * were resolved at `startInstance` time.\n */\n workflowState?: ResolvedStateEntry[]\n /**\n * Resource of the workflow itself. Used to canonicalize raw Sanity\n * reference shapes (`{_ref, _type}`) returned by `type: \"query\"`\n * state entries into GDR `{id, type}` form. Without this, a query-sourced\n * doc.ref entry would leave its value in the lake shape and the\n * snapshot hydrator wouldn't know to pull the referenced doc into\n * scope.\n */\n workflowResource?: WorkflowResource\n /**\n * Perspective for `type: \"query\"` entry evaluation. Threaded through\n * to `client.fetch(..., { perspective })`. Lets a entry that runs\n * GROQ against the lake see a release-stacked view rather than the\n * published shadow. Unset → reads run under the client's default\n * perspective (which is `\"raw\"` on the test client and whatever the\n * caller configured on `@sanity/client`).\n */\n perspective?: WorkflowPerspective\n}\n\n/**\n * Derive a read perspective from resolved workflow-scope state: if any\n * `release.ref` entry has a value, return a single-release\n * stack `[releaseName]`. Returns `undefined` when no release entry is\n * populated, so callers can fall back to an explicit perspective or\n * the engine default.\n *\n * The first populated release entry wins (workflows targeting more than\n * one release aren't modelled — a single release-ref entry is the\n * canonical shape). Pure: operates on already-resolved state entries.\n */\nexport function derivePerspectiveFromState(\n entries: ResolvedStateEntry[] | undefined,\n): WorkflowPerspective | undefined {\n if (entries === undefined) return undefined\n for (const entry of entries) {\n if (entry._type === 'release.ref' && entry.value !== null) {\n const releaseName = entry.value.releaseName\n if (typeof releaseName === 'string' && releaseName.length > 0) {\n return [releaseName]\n }\n }\n }\n return undefined\n}\n\nexport async function resolveDeclaredState(args: {\n entryDefs: StateEntry[] | undefined\n initialState: InitialStateValue[]\n ctx: ResolveStateContext\n randomKey: () => string\n}): Promise<ResolvedStateEntry[]> {\n const {entryDefs, initialState, ctx, randomKey} = args\n if (entryDefs === undefined || entryDefs.length === 0) return []\n const out: ResolvedStateEntry[] = []\n for (const entry of entryDefs) {\n // Each entry sees the already-resolved ones via `$state.<entryName>`.\n const scopedCtx: ResolveStateContext = {...ctx, resolvedState: out}\n out.push(await resolveOneEntry(entry, initialState, scopedCtx, randomKey))\n }\n return out\n}\n\nconst ARRAY_SLOT_TYPES = new Set<StateEntry['type']>([\n 'doc.refs',\n 'checklist',\n 'notes',\n 'assignees',\n])\n\n/** Default for an unfilled entry: `[]` for array kinds, `null` otherwise. */\nfunction defaultEntryValue(entryType: StateEntry['type']): unknown {\n return ARRAY_SLOT_TYPES.has(entryType) ? [] : null\n}\n\n/**\n * Read a caller-supplied `init` value. Rejects bare doc ids at the\n * boundary: the engine stores GDR URIs throughout — callers MUST\n * construct full URIs (via `gdrFromResource` / `refDataset` / etc.)\n * before passing them into `initialState`. Silent canonicalisation\n * would mask the shape gap and let bare-id refs leak into snapshots,\n * where they mismatch every GDR-keyed lookup and break filters.\n */\nfunction resolveInitValue(\n entry: StateEntry,\n initialState: InitialStateValue[],\n defaultValue: unknown,\n): unknown {\n const initMatch = initialState.find((s) => s.name === entry.name && s.type === entry.type)\n if (initMatch === undefined) return defaultValue\n assertInitValueShape(entry, initMatch.value)\n return initMatch.value\n}\n\nfunction resolveStateReadValue(\n source: Extract<StateEntry['source'], {type: 'stateRead'}>,\n ctx: ResolveStateContext,\n defaultValue: unknown,\n): unknown {\n const entriesForScope =\n source.scope === 'workflow' ? (ctx.workflowState ?? []) : (ctx.resolvedState ?? [])\n const target = entriesForScope.find((s) => s.name === source.state)\n const targetValue = target === undefined ? undefined : (target as {value?: unknown}).value\n const resolved = source.path !== undefined ? getPath(targetValue, source.path) : targetValue\n return resolved === undefined || resolved === null ? defaultValue : resolved\n}\n\n/**\n * Run a `query` entry's GROQ against the lake. Params carry GDR URIs\n * (snapshot form) but are stripped to bare for the fetch — same pattern\n * as filter evaluation's lake fallback: the lake stores bare `_id`s, so\n * `$state.<entry>.value.id` etc. must be bare too.\n *\n * `$state` exposes state entries already resolved before this one (sequential\n * resolution). Cyclic references to later state entries produce `undefined` in\n * GROQ and the entry falls through to its default.\n */\nasync function resolveQueryValue(\n entry: StateEntry,\n source: Extract<StateEntry['source'], {type: 'query'}>,\n ctx: ResolveStateContext,\n client: WorkflowClient,\n defaultValue: unknown,\n): Promise<unknown> {\n const params = paramsForLake({\n self: ctx.selfId ?? null,\n state: stateMapFromResolved(ctx.resolvedState ?? []),\n stage: ctx.stageName ?? null,\n task: ctx.taskName ?? null,\n now: ctx.now,\n engineTags: ctx.tags ?? [],\n })\n try {\n const fetchOptions = ctx.perspective !== undefined ? {perspective: ctx.perspective} : undefined\n const result = await client.fetch<unknown>(source.query, params, fetchOptions)\n return normalizeQueryResult(entry.type, result, ctx.workflowResource) ?? defaultValue\n } catch (err) {\n throw new Error(\n `Failed to resolve query entry \"${entry.name}\" (${entry.type}): ${\n err instanceof Error ? err.message : String(err)\n }`,\n {cause: err},\n )\n }\n}\n\nasync function resolveEntryValue(\n entry: StateEntry,\n initialState: InitialStateValue[],\n ctx: ResolveStateContext,\n defaultValue: unknown,\n): Promise<unknown> {\n const source = entry.source\n if (source.type === 'init') return resolveInitValue(entry, initialState, defaultValue)\n if (source.type === 'literal') return source.value ?? defaultValue\n if (source.type === 'stateRead') return resolveStateReadValue(source, ctx, defaultValue)\n if (source.type === 'query' && ctx.client !== undefined) {\n return resolveQueryValue(entry, source, ctx, ctx.client, defaultValue)\n }\n // \"write\" (and \"query\" without a client) use defaults.\n return defaultValue\n}\n\n/** Build the persisted entry envelope; `query` state entries carry `resolvedAt`. */\nfunction buildResolvedEntry(\n entry: StateEntry,\n value: unknown,\n _key: string,\n now: string,\n): ResolvedStateEntry {\n const titleProp = entry.title !== undefined ? {title: entry.title} : {}\n const descriptionProp = entry.description !== undefined ? {description: entry.description} : {}\n if (entry.type === 'query') {\n return {\n _key,\n _type: 'query',\n name: entry.name,\n ...titleProp,\n ...descriptionProp,\n value,\n resolvedAt: now,\n }\n }\n return {\n _key,\n _type: entry.type,\n name: entry.name,\n ...titleProp,\n ...descriptionProp,\n value,\n } as ResolvedStateEntry\n}\n\nasync function resolveOneEntry(\n entry: StateEntry,\n initialState: InitialStateValue[],\n ctx: ResolveStateContext,\n randomKey: () => string,\n): Promise<ResolvedStateEntry> {\n const defaultValue = defaultEntryValue(entry.type)\n const value = await resolveEntryValue(entry, initialState, ctx, defaultValue)\n\n // Validate the resolved value against the entry's declared shape.\n // The `value.query` entry type is permissive (escape hatch). Default\n // values (null / []) are always shape-valid; init/literal/stateRead/\n // query may have produced something else — catch shape mismatches\n // here before they leak into the persisted snapshot.\n validateStateValue({entryType: entry.type, entryName: entry.name, value})\n\n return buildResolvedEntry(entry, value, randomKey(), ctx.now)\n}\n\n/** Project resolved state entries into the `$state` shape (entryName → entry envelope). */\nfunction stateMapFromResolved(entries: ResolvedStateEntry[]): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const s of entries) out[s.name] = s.value\n return out\n}\n\n/**\n * Validate caller-supplied `initialState` values for shape correctness\n * BEFORE they hit the persisted instance. Init-sourced doc.ref /\n * doc.refs state entries reject bare-string `id`s — the engine stores GDR\n * URIs everywhere and a bare id silently mismatches snapshots later.\n * Throws a clear error pointing at the entry id + bad value.\n *\n * Query-sourced values are NOT validated here; the lake returns\n * various shapes and {@link normalizeQueryResult} is the only path that\n * gets to canonicalise them.\n */\nfunction assertInitValueShape(entry: StateEntry, value: unknown): void {\n if (entry.type === 'doc.ref') {\n assertGdrShape(value, `state entry \"${entry.name}\" (doc.ref)`)\n return\n }\n if (entry.type === 'release.ref') {\n assertGdrShape(value, `state entry \"${entry.name}\" (release.ref)`)\n const v = value as {releaseName?: unknown}\n if (typeof v.releaseName !== 'string' || v.releaseName.length === 0) {\n throw new Error(\n `Invalid init value for state entry \"${entry.name}\" (release.ref): ` +\n `\\`releaseName\\` must be a non-empty string. Got ${JSON.stringify(v.releaseName)}.`,\n )\n }\n return\n }\n if (entry.type === 'doc.refs') {\n if (!Array.isArray(value)) {\n throw new Error(\n `Invalid init value for state entry \"${entry.name}\" (doc.refs): expected an array of GDRs, got ${typeof value}.`,\n )\n }\n for (const [i, item] of value.entries()) {\n assertGdrShape(item, `state entry \"${entry.name}\" (doc.refs) item [${i}]`)\n }\n }\n}\n\nfunction assertGdrShape(value: unknown, context: string): void {\n if (typeof value !== 'object' || value === null) {\n throw new Error(\n `Invalid GDR for ${context}: expected { id: \"<scheme>:...\", type: \"<schema>\" }, got ${typeof value}.`,\n )\n }\n const v = value as {id?: unknown; type?: unknown}\n if (typeof v.id !== 'string' || !isGdrUri(v.id)) {\n throw new Error(\n `Invalid GDR for ${context}: \\`id\\` must be a GDR URI (\"<scheme>:<...id-parts>\" with scheme dataset|canvas|media-library|dashboard). ` +\n `Got ${JSON.stringify(v.id)}. Construct via \\`gdrFromResource\\` / \\`refDataset\\` / \\`refCanvas\\` etc. — bare document ids are not accepted.`,\n )\n }\n if (typeof v.type !== 'string' || v.type.length === 0) {\n throw new Error(\n `Invalid GDR for ${context}: \\`type\\` (schema name) must be a non-empty string. Got ${JSON.stringify(v.type)}.`,\n )\n }\n}\n\n/**\n * Convert a raw GROQ result into the entry's expected value shape.\n *\n * For `doc.ref` / `doc.refs` entries, the engine's internal contract is\n * a GDR `{id, type}` object. But a natural query like\n * `*[_id == $state.subject.id][0].primaryTeam` returns the Sanity reference\n * shape `{_ref, _type: \"reference\"}` — bare `_ref`, generic `_type`.\n * Convert it: GDR id = `gdrFromResource(workflowResource, _ref)`,\n * GDR type = \"document\" (the target doc's real schema type isn't\n * carried by the ref envelope; consumers shouldn't depend on it for\n * the entry value's `type` field).\n *\n * Already-GDR-shaped values (with `id` + `type`) pass through. Bare\n * strings are treated as doc ids and wrapped. Arrays are walked for\n * the refs case. Other entry kinds pass through unchanged.\n */\nfunction normalizeQueryResult(\n entryType: StateEntry['type'],\n raw: unknown,\n workflowResource: WorkflowResource | undefined,\n): unknown {\n if (raw === null || raw === undefined) return raw\n if (entryType === 'doc.ref') {\n return coerceToGdr(raw, workflowResource)\n }\n if (entryType === 'doc.refs') {\n if (!Array.isArray(raw)) return []\n return raw.map((item) => coerceToGdr(item, workflowResource)).filter((v) => v !== null)\n }\n return raw\n}\n\ntype Gdr = {id: import('./core/refs.ts').GdrUri; type: string}\n\n/** Resolve a doc id (bare or already-URI) to a GDR URI via the resource. */\nfunction toGdrUri(\n docId: string,\n workflowResource: WorkflowResource,\n): import('./core/refs.ts').GdrUri {\n return isGdrUri(docId) ? docId : gdrFromResource(workflowResource, docId)\n}\n\n/**\n * Coerce an already-GDR-shaped `{id, type}` value. The id must be a\n * known-scheme URI to pass through; otherwise it's a bare id from a\n * non-canonical source and we re-derive it via the resource. Returns\n * null when the shape doesn't match so callers fall through.\n */\nfunction coerceGdrShape(raw: object, workflowResource: WorkflowResource | undefined): Gdr | null {\n if (!('id' in raw) || !('type' in raw)) return null\n const r = raw as {id: unknown; type: unknown}\n if (typeof r.id !== 'string' || typeof r.type !== 'string') return null\n if (isGdrUri(r.id)) return {id: r.id, type: r.type}\n if (workflowResource) return {id: gdrFromResource(workflowResource, r.id), type: r.type}\n return null\n}\n\n/**\n * Coerce a Sanity reference envelope `{_ref, _type: \"reference\"}` to a\n * GDR. Without `workflowResource` there's no way to construct the URI;\n * returns null and lets the snapshot hydrator skip the entry.\n */\nfunction coerceRefEnvelope(\n raw: object,\n workflowResource: WorkflowResource | undefined,\n): Gdr | null {\n if (!('_ref' in raw)) return null\n const r = raw as {_ref: unknown}\n if (typeof r._ref !== 'string' || !workflowResource) return null\n return {id: toGdrUri(r._ref, workflowResource), type: 'document'}\n}\n\nfunction coerceToGdr(raw: unknown, workflowResource: WorkflowResource | undefined): Gdr | null {\n if (raw === null || raw === undefined) return null\n if (typeof raw === 'object') {\n return coerceGdrShape(raw, workflowResource) ?? coerceRefEnvelope(raw, workflowResource)\n }\n // Bare string — assume doc id in the workflow resource.\n if (typeof raw === 'string' && workflowResource) {\n return {id: toGdrUri(raw, workflowResource), type: 'document'}\n }\n return null\n}\n","import {type Clock, wallClock} from '../clock.ts'\nimport {evaluateCondition, evaluatePredicates} from '../core/eval.ts'\nimport {assignedFor, buildParams, scopedStateOverlay} from '../core/params.ts'\nimport {extractDocumentId, type ParsedGdr} from '../core/refs.ts'\nimport type {HydratedSnapshot, LoadedDoc} from '../core/snapshot.ts'\nimport type {Stage, Task, WorkflowDefinition} from '../define/schema.ts'\nimport {randomKey} from '../keys.ts'\nimport {hydrateSnapshot} from '../snapshot.ts'\nimport {resolveDeclaredState} from '../state-resolution.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {StageName} from '../types/ids.ts'\nimport {parseDefinitionSnapshot, type WorkflowInstance} from '../types/instance.ts'\nimport type {InitialStateValue, ResolvedStateEntry} from '../types/state-values.ts'\n\n/**\n * Convert a GDR URI back to a bare document id. The engine's\n * cross-resource reference fields (`ancestors[].id`,\n * `spawnedInstances[].id`) carry full GDR URIs; the persistent `_id`\n * on disk is bare. Use this when fetching a referenced doc from Sanity.\n */\nexport function gdrToBareId(uri: string): string {\n return uri.includes(':') ? extractDocumentId(uri) : uri\n}\n\n// Internal — context load\n\nexport interface EngineContext {\n /** Engine's own client — bound to the workflow resource. */\n client: WorkflowClient\n /**\n * The single clock reading for this operation, taken once when the\n * context is built. EVERY \"now\" the engine stamps in this context —\n * `$now` in conditions, the `now` op-source, all history `at`,\n * `completedAt`, `enteredAt`, `lastChangedAt` — reads {@link EngineContext.now},\n * so the whole operation shares one instant rather than drifting across\n * repeated wall-clock reads.\n */\n now: string\n /**\n * The {@link Clock} this context was built from, carried so nested\n * operations the context spawns (child priming + cascade inside\n * `persist`) read the SAME clock. Stamps use {@link EngineContext.now},\n * not this — call it only to seed a fresh context. Defaults to\n * {@link wallClock}.\n */\n clock: Clock\n /**\n * Route a cross-resource read by parsed GDR. Returns the engine's\n * own client when the resolver doesn't have an entry. The cascade\n * uses this for subject + ancestor loads.\n */\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient\n instance: WorkflowInstance\n definition: WorkflowDefinition\n /**\n * GDR-keyed snapshot of docs hydrated at cascade entry — instance,\n * subject (if cross-resource and reachable), ancestors. Always\n * present: `loadContext` builds it via `hydrateSnapshot`. Conditions\n * evaluate against this snapshot (pure, no lake fallback). The shell\n * is responsible for completeness — anything not hydrated is invisible\n * to the condition.\n */\n snapshot: HydratedSnapshot\n}\n\nexport async function loadContext(\n client: WorkflowClient,\n instanceId: string,\n options?: {\n clientForGdr?: (parsed: ParsedGdr) => WorkflowClient\n clock?: Clock\n /** Content overlay — held doc values the cascade reads instead of\n * fetching (see {@link hydrateSnapshot}). Absent ids still load, so\n * a partial overlay degrades safely to a refetch. */\n overlay?: ReadonlyMap<string, LoadedDoc>\n },\n): Promise<EngineContext> {\n const instance = await client.getDocument<WorkflowInstance>(instanceId)\n if (!instance) {\n throw new Error(`Workflow instance ${instanceId} not found`)\n }\n const definition = parseDefinitionSnapshot(instance)\n const clientForGdr = options?.clientForGdr ?? (() => client)\n const clock = options?.clock ?? wallClock\n const snapshot = await hydrateSnapshot({\n client,\n clientForGdr,\n instance,\n ...(options?.overlay !== undefined ? {overlay: options.overlay} : {}),\n })\n return {client, clientForGdr, clock, now: clock(), instance, definition, snapshot}\n}\n\n/**\n * Per-evaluation context for the rendered scope's context-bound vars:\n * `$actor` / `$assigned` ride the caller, the task name selects the lexical\n * `$state` overlay and the `$subworkflows` rows, `vars` carries anything the\n * shell pre-computed (`$can`, `$row`, `$subworkflows`).\n */\nexport interface ConditionScopeOptions {\n taskName?: string\n actor?: Actor\n vars?: Record<string, unknown>\n}\n\n/**\n * Assemble the full rendered scope for one evaluation: the instance\n * built-ins, the lexical `$state` overlay for the task context, the caller\n * (`$actor`, `$assigned`), shell-supplied vars, and the author's nullary\n * predicates pre-evaluated as boolean `$name` params.\n */\nexport async function ctxConditionParams(\n ctx: EngineContext,\n opts?: ConditionScopeOptions,\n): Promise<Record<string, unknown>> {\n const base = buildParams({instance: ctx.instance, now: ctx.now, snapshot: ctx.snapshot})\n const state = {\n ...(base.state as Record<string, unknown>),\n ...scopedStateOverlay(ctx.instance, ctx.snapshot, opts?.taskName),\n }\n const params: Record<string, unknown> = {\n ...base,\n state,\n actor: opts?.actor,\n assigned:\n opts?.taskName !== undefined ? assignedFor(ctx.instance, opts.taskName, opts?.actor) : false,\n ...opts?.vars,\n }\n const predicates = await evaluatePredicates({\n predicates: ctx.definition.predicates,\n snapshot: ctx.snapshot,\n params,\n })\n return {...predicates, ...params}\n}\n\n/** Evaluate a condition against the context's hydrated snapshot with the\n * full rendered scope bound. An undefined condition is vacuously true. */\nexport async function ctxEvaluateCondition(\n ctx: EngineContext,\n condition: string | undefined,\n opts?: ConditionScopeOptions,\n): Promise<boolean> {\n if (condition === undefined) return true\n return evaluateCondition({\n condition,\n snapshot: ctx.snapshot,\n params: await ctxConditionParams(ctx, opts),\n })\n}\n\n/** Assemble an {@link EngineContext} for an already-loaded instance,\n * hydrating its snapshot. Used by the post-prime + propagation paths\n * that re-read the instance mid-cascade. */\nexport async function buildEngineContext(args: {\n client: WorkflowClient\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient\n instance: WorkflowInstance\n definition: WorkflowDefinition\n clock?: Clock\n}): Promise<EngineContext> {\n const {client, clientForGdr, instance, definition} = args\n const clock = args.clock ?? wallClock\n return {\n client,\n clientForGdr,\n clock,\n now: clock(),\n instance,\n definition,\n snapshot: await hydrateSnapshot({client, clientForGdr, instance}),\n }\n}\n\nexport function findStage(definition: WorkflowDefinition, stageName: StageName): Stage {\n const stage = definition.stages.find((s) => s.name === stageName)\n if (stage === undefined) {\n throw new Error(`Stage \"${stageName}\" not found in definition ${definition.name}`)\n }\n return stage\n}\n\n/**\n * Build the per-stage resolved state[] from the stage definition + an\n * optional `initialState` (e.g. supplied to `setStage`). Bound to the\n * instance's subject and to `$stage = stage.name`.\n */\nexport async function resolveStageStateEntries(args: {\n client: WorkflowClient\n instance: WorkflowInstance\n stage: Stage\n now: string\n initialState?: InitialStateValue[]\n}): Promise<ResolvedStateEntry[]> {\n const {client, instance, stage, now, initialState} = args\n return resolveDeclaredState({\n entryDefs: stage.state,\n initialState: initialState ?? [],\n ctx: {\n client,\n now,\n selfId: instance._id,\n tags: instance.tags ?? [],\n stageName: stage.name,\n workflowResource: instance.workflowResource,\n // Allow stage-scope entries' `source: { type: \"stateRead\", scope:\n // \"workflow\", ... }` to see the already-resolved workflow-scope state.\n workflowState: instance.state ?? [],\n ...(instance.perspective !== undefined ? {perspective: instance.perspective} : {}),\n },\n randomKey,\n })\n}\n\n/** Same shape as `resolveStageStateEntries` but scoped to a task. */\nexport async function resolveTaskStateEntries(args: {\n client: WorkflowClient\n instance: WorkflowInstance\n stage: Stage\n task: Task\n now: string\n}): Promise<ResolvedStateEntry[]> {\n const {client, instance, stage, task, now} = args\n return resolveDeclaredState({\n entryDefs: task.state,\n initialState: [],\n ctx: {\n client,\n now,\n selfId: instance._id,\n tags: instance.tags ?? [],\n stageName: stage.name,\n workflowResource: instance.workflowResource,\n taskName: task.name,\n workflowState: instance.state ?? [],\n ...(instance.perspective !== undefined ? {perspective: instance.perspective} : {}),\n },\n randomKey,\n })\n}\n","/**\n * Pure effect-binding resolution.\n *\n * An effect's `bindings` is a `Record<string, groq>` — GROQ reads over the\n * same rendered scope conditions use (`$state`, `$effects`, `$now`, …). Each\n * binding evaluates to a concrete value and merges with the effect's static\n * `input` to form the params object the handler is called with.\n */\n\nimport {runGroq} from './eval.ts'\nimport type {HydratedSnapshot} from './snapshot.ts'\n\nexport async function resolveBindings(args: {\n bindings: Record<string, string> | undefined\n staticInput: Record<string, unknown> | undefined\n snapshot: HydratedSnapshot\n /** The rendered scope — same param bag conditions evaluate over. */\n params: Record<string, unknown>\n}): Promise<Record<string, unknown>> {\n const resolved: Record<string, unknown> = {}\n for (const [key, groq] of Object.entries(args.bindings ?? {})) {\n resolved[key] = await runGroq(groq, args.params, args.snapshot)\n }\n return {...resolved, ...args.staticInput}\n}\n","import type {GlobalDocumentReference, WorkflowResource} from './core/refs.ts'\nimport type {WorkflowDefinition} from './define/schema.ts'\nimport {randomKey} from './keys.ts'\nimport type {Actor} from './types/actor.ts'\nimport type {WorkflowPerspective} from './types/client.ts'\nimport type {EffectsContextEntry} from './types/effects.ts'\nimport {WORKFLOW_INSTANCE_TYPE, type WorkflowInstance} from './types/instance.ts'\nimport type {ResolvedStateEntry} from './types/state-values.ts'\n\n/** Wrap a scalar or GDR value in its typed {@link EffectsContextEntry}\n * envelope, minting a fresh `_key`. */\nexport function effectsContextEntry(\n name: string,\n value: string | number | boolean | GlobalDocumentReference,\n): EffectsContextEntry {\n const _key = randomKey()\n if (typeof value === 'string') return {_key, _type: 'effectsContext.string', name, value}\n if (typeof value === 'number') return {_key, _type: 'effectsContext.number', name, value}\n if (typeof value === 'boolean') return {_key, _type: 'effectsContext.boolean', name, value}\n return {_key, _type: 'effectsContext.ref', name, value}\n}\n\n/**\n * Wrap a completed effect's outputs record as one `effectsContext.json`\n * entry keyed by the effect's name, so the rendered `$effects` map exposes\n * them namespaced: `$effects['<effect name>'].<output>`.\n */\nexport function effectsContextJsonEntry(\n name: string,\n value: Record<string, string | number | boolean | GlobalDocumentReference>,\n): EffectsContextEntry {\n return {_key: randomKey(), _type: 'effectsContext.json', name, value: JSON.stringify(value)}\n}\n\n/**\n * Build a fresh {@link WorkflowInstance} document for `create`. Shared by\n * `startInstance` (root instances) and the spawn path (child instances):\n * both pin the definition snapshot, seed state + effectsContext, enter\n * the initial stage with a single `stageEntered` history entry, and stamp\n * `_createdAt`/`startedAt`/`lastChangedAt` to the same `now`.\n */\nexport function buildInstanceBase(args: {\n id: string\n now: string\n tags: string[]\n workflowResource: WorkflowResource\n definitionName: string\n pinnedVersion: number\n definition: WorkflowDefinition\n state: ResolvedStateEntry[]\n effectsContext: EffectsContextEntry[]\n ancestors: GlobalDocumentReference[]\n perspective: WorkflowPerspective | undefined\n initialStage: string\n actor: Actor | undefined\n}): WorkflowInstance {\n const {id, now, actor, perspective} = args\n return {\n _id: id,\n _type: WORKFLOW_INSTANCE_TYPE,\n _rev: '',\n _createdAt: now,\n _updatedAt: now,\n tags: args.tags,\n workflowResource: args.workflowResource,\n definition: args.definitionName,\n pinnedVersion: args.pinnedVersion,\n definitionSnapshot: JSON.stringify(args.definition),\n state: args.state,\n effectsContext: args.effectsContext,\n ancestors: args.ancestors,\n ...(perspective !== undefined ? {perspective} : {}),\n currentStage: args.initialStage,\n stages: [],\n pendingEffects: [],\n effectHistory: [],\n history: [\n {\n _key: randomKey(),\n _type: 'stageEntered',\n at: now,\n stage: args.initialStage,\n ...(actor !== undefined ? {actor} : {}),\n },\n ],\n startedAt: now,\n lastChangedAt: now,\n }\n}\n","import type {Clock} from '../clock.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {Grant} from '../types/authorization.ts'\nimport type {StateScope, TaskStatus} from '../types/enums.ts'\nimport type {StageName, TaskName} from '../types/ids.ts'\n\n// Public API\n\nexport interface EngineCallOptions {\n actor?: Actor\n /**\n * Resolved grants for the caller — binds the advisory `$can` in the\n * commit-path condition check, mirroring the soft-gate's scope. Omit to\n * leave `$can` undefined (conditions referencing it fail closed).\n */\n grants?: Grant[]\n /** Injected {@link Clock} for deterministic time; defaults to wall-clock. */\n clock?: Clock\n}\n\nexport interface TransitionResult {\n fired: boolean\n fromStage?: StageName\n toStage?: StageName\n transition?: string\n}\n\nexport interface InvokeResult {\n invoked: boolean\n task: TaskName\n}\n\nexport interface OpAppliedSummary {\n opType: string\n target?: {scope: StateScope; state: string}\n resolved?: Record<string, unknown>\n}\n\nexport interface ActionResult {\n fired: boolean\n task: TaskName\n action: string\n newStatus?: TaskStatus\n /** Deterministic engine primitives that ran inline during the commit. */\n ranOps?: OpAppliedSummary[]\n}\n\n/**\n * Thrown when caller-supplied params don't satisfy the action's\n * declared `params[]` — missing required fields or wrong primitive\n * type. The action does not commit; the engine has not mutated state.\n */\nexport class ActionParamsInvalidError extends Error {\n readonly action: string\n readonly task: TaskName\n readonly issues: {param: string; reason: string}[]\n constructor(args: {action: string; task: TaskName; issues: {param: string; reason: string}[]}) {\n const lines = args.issues.map((i) => ` - ${i.param}: ${i.reason}`).join('\\n')\n super(`Action \"${args.action}\" on task \"${args.task}\" rejected: invalid params\\n${lines}`)\n this.name = 'ActionParamsInvalidError'\n this.action = args.action\n this.task = args.task\n this.issues = args.issues\n }\n}\n\n/**\n * Thrown when a guard deploy fails *after* its state move committed and the\n * engine could not restore the instance to its pre-move state — either the\n * rollback write itself failed, or the move created sibling docs (spawn) that a\n * parent-only rollback cannot undo. The workflow's persisted state and its\n * deployed guards are now divergent and need manual reconciliation; the engine\n * screams rather than leaving the inconsistency silent.\n */\nexport class WorkflowStateDivergedError extends Error {\n readonly instanceId: string\n /** The guard-deploy failure that triggered the (attempted) rollback. */\n readonly guardError: unknown\n /** The rollback failure, when rollback was attempted and itself failed. */\n readonly rollbackError?: unknown\n constructor(args: {\n instanceId: string\n guardError: unknown\n rollbackError?: unknown\n reason: string\n }) {\n super(\n `Workflow \"${args.instanceId}\" state committed but its guards could not be reconciled: ${args.reason}.`,\n {cause: args.guardError},\n )\n this.name = 'WorkflowStateDivergedError'\n this.instanceId = args.instanceId\n this.guardError = args.guardError\n if (args.rollbackError !== undefined) this.rollbackError = args.rollbackError\n }\n}\n\nexport interface CompleteEffectResult {\n effectKey: string\n status: 'done' | 'failed'\n}\n\n/** Total `fireAction` commit attempts before giving up — one initial try\n * plus reloads after each lost `ifRevisionId` race. */\nexport const CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS = 3\n\n/**\n * Thrown when a `fireAction` commit loses the optimistic-locking race on\n * all {@link CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS} attempts — every reload +\n * `ifRevisionId` retry was beaten by another writer committing first.\n * Surfacing it (rather than silently overwriting) lets the caller decide\n * whether to retry later or report a write storm; nothing was committed\n * on the final attempt.\n */\nexport class ConcurrentFireActionError extends Error {\n readonly instanceId: string\n readonly task: TaskName\n readonly action: string\n readonly attempts: number\n constructor(args: {instanceId: string; task: TaskName; action: string; attempts: number}) {\n super(\n `Action \"${args.action}\" on task \"${args.task}\" (instance ${args.instanceId}) lost the ` +\n `optimistic-locking race ${args.attempts} attempts running — a concurrent writer kept ` +\n `committing first. Re-read and retry, or investigate a write storm on this instance.`,\n )\n this.name = 'ConcurrentFireActionError'\n this.instanceId = args.instanceId\n this.task = args.task\n this.action = args.action\n this.attempts = args.attempts\n }\n}\n\n/**\n * True when a rev-guarded write was rejected by optimistic-locking — a 409\n * from the real client or the bench's `ifRevisionId check failed`. Lets\n * callers retry on a lost race while still rethrowing real errors\n * (validation, network, missing task) rather than masking them as conflicts.\n */\nexport function isRevisionConflict(error: unknown): boolean {\n if (typeof error !== 'object' || error === null) return false\n const {statusCode, message} = error as {statusCode?: unknown; message?: unknown}\n if (statusCode === 409) return true\n return typeof message === 'string' && message.includes('ifRevisionId check failed')\n}\n\n/**\n * Thrown when auto-transitions on an instance fail to stabilise within\n * {@link CascadeLimitError.limit} passes — the signature of a runaway\n * cascade. The classic trigger is two stages whose transition guards\n * stay simultaneously satisfied (e.g. an `op.state.set` lands a value\n * that trips the very guard that fired, and nothing ever clears it), so\n * the engine flip-flops and would otherwise write revisions forever.\n *\n * The cascade aborts at the limit rather than the engine hanging; the\n * instance is left at whatever stage the last completed pass reached.\n */\nexport class CascadeLimitError extends Error {\n readonly instanceId: string\n readonly limit: number\n constructor(args: {instanceId: string; limit: number}) {\n super(\n `Cascade did not stabilise after ${args.limit} auto-transitions on ${args.instanceId} — ` +\n `likely a runaway loop (transition guards that stay mutually satisfied). ` +\n `Check that each transition's filter eventually goes false.`,\n )\n this.name = 'CascadeLimitError'\n this.instanceId = args.instanceId\n this.limit = args.limit\n }\n}\n","import type {WorkflowClient} from '../types/client.ts'\nimport {WorkflowStateDivergedError} from './results.ts'\n\nexport interface DeployOrRollbackArgs {\n client: WorkflowClient\n instanceId: string\n /** The post-commit revision the rollback patch must still match. */\n committedRev: string | undefined\n /** Pre-commit field values to write back if the deploy fails. */\n restore: Record<string, unknown>\n /** Fields the move added that a rollback must remove (e.g. a fresh `completedAt`). */\n unset?: string[]\n /**\n * False when the commit also created sibling docs (a spawn transaction) that\n * a parent-only rollback cannot undo — a deploy failure then screams instead\n * of leaving orphaned children behind a half-applied move.\n */\n reversible: boolean\n /** Deploy/reconcile the stage's guards. Runs after the state has committed. */\n deploy: () => Promise<void>\n}\n\n/**\n * Deploy guards for a just-committed state move, rolling the move back if the\n * deploy fails. Ordering is deliberate: guards deploy AFTER the state commits\n * (a guard can lock the caller out of further edits, so it must follow the\n * state it enforces). On a deploy failure the engine restores the pre-commit\n * instance and re-throws the original error — the caller sees the failure with\n * state intact. When a clean rollback is impossible (spawn) or the rollback\n * write itself fails, it throws {@link WorkflowStateDivergedError} so the\n * divergence is loud, never silent.\n */\nexport async function deployOrRollback(args: DeployOrRollbackArgs): Promise<void> {\n try {\n await args.deploy()\n } catch (guardError) {\n if (!args.reversible) {\n throw new WorkflowStateDivergedError({\n instanceId: args.instanceId,\n guardError,\n reason: 'the move created child instances a parent-only rollback cannot undo',\n })\n }\n try {\n let patch = args.client.patch(args.instanceId).set(args.restore)\n if (args.unset && args.unset.length > 0) patch = patch.unset(args.unset)\n if (args.committedRev !== undefined) patch = patch.ifRevisionId(args.committedRev)\n await patch.commit()\n } catch (rollbackError) {\n throw new WorkflowStateDivergedError({\n instanceId: args.instanceId,\n guardError,\n rollbackError,\n reason: 'rollback of the committed move failed',\n })\n }\n throw guardError\n }\n}\n","/**\n * History-entry builders shared across the lifecycle boundaries. Leaf\n * module (keys + types only) so the op runner, the stage mover, and the\n * task activator can all stamp entries without import cycles.\n */\n\nimport {randomKey} from '../keys.ts'\nimport type {Actor} from '../types/actor.ts'\nimport {isTerminalTaskStatus, type TaskStatus} from '../types/enums.ts'\nimport type {HistoryEntry} from '../types/history.ts'\nimport type {StageName} from '../types/ids.ts'\nimport type {TaskEntry} from '../types/instance-state.ts'\n\n/**\n * The ONE task-status flip. Sets the entry's status, stamps\n * `completedAt`/`completedBy` when the new status is terminal, and pushes\n * the `taskStatusChanged` audit row — every boundary that flips a task\n * (the `status.set` op, gate auto-resolution, machine steps, ancestor\n * propagation) lands here so completion stamps and the audit trail can't\n * diverge across paths.\n */\nexport function applyTaskStatusChange(args: {\n entry: TaskEntry\n history: HistoryEntry[]\n stage: StageName\n to: TaskStatus\n /** The operation's clock reading (the caller's `ctx.now`). */\n at: string\n actor?: Actor\n}): void {\n const {entry, history, stage, to, at, actor} = args\n const from = entry.status\n entry.status = to\n if (isTerminalTaskStatus(to)) {\n entry.completedAt = at\n if (actor !== undefined) entry.completedBy = actor.id\n }\n history.push({\n _key: randomKey(),\n _type: 'taskStatusChanged',\n at,\n stage,\n task: entry.name,\n from,\n to,\n ...(actor !== undefined ? {actor} : {}),\n })\n}\n\n/**\n * Build the three-entry history sequence for a stage move:\n * `stageExited` → `transitionFired` → `stageEntered`. All three share\n * `at`, the `transition` name, `actor`, and the `via`/`reason`\n * discriminators that distinguish condition-driven transitions from\n * admin overrides.\n */\nexport function stageTransitionHistory(args: {\n fromStage: StageName\n toStage: StageName\n at: string\n transition?: string\n actor?: Actor\n via?: 'transition' | 'setStage'\n reason?: string\n}): HistoryEntry[] {\n const {fromStage, toStage, at, transition, actor, via, reason} = args\n const shared = {\n at,\n ...(transition !== undefined ? {transition} : {}),\n ...(actor !== undefined ? {actor} : {}),\n ...(via !== undefined ? {via} : {}),\n ...(reason !== undefined ? {reason} : {}),\n }\n return [\n {\n _key: randomKey(),\n _type: 'stageExited',\n stage: fromStage,\n toStage,\n ...shared,\n },\n {\n _key: randomKey(),\n _type: 'transitionFired',\n fromStage,\n toStage,\n ...shared,\n },\n {\n _key: randomKey(),\n _type: 'stageEntered',\n stage: toStage,\n fromStage,\n ...shared,\n },\n ]\n}\n","/**\n * Engine-scope tags — the multi-tenant isolation primitive.\n *\n * Every engine takes a required `tags: string[]` set at construction.\n * Tags must be Sanity-ID-compatible since they're joined into IDs with\n * `.` — ASCII lowercase + digits + dashes, no leading dash, no dots.\n *\n * The first tag in the array is the *canonical* tag, used as the ID\n * prefix when the engine writes new definitions or instances. The full\n * tag set goes onto every written doc and is the basis for read\n * filtering (tag intersection between engine and doc).\n */\n\nconst TAG_RE = /^[a-z0-9][a-z0-9-]*$/\n\nexport function validateTags(tags: string[]): void {\n if (tags.length === 0) {\n throw new Error('tags: must be a non-empty array')\n }\n for (const tag of tags) {\n if (!TAG_RE.test(tag)) {\n throw new Error(\n `tags: invalid tag \"${tag}\" — must match ${TAG_RE.source} (ASCII lowercase + digits + dashes, no leading dash, no dots)`,\n )\n }\n }\n}\n\nexport function canonicalTag(tags: string[]): string {\n return tags[0]!\n}\n\n/**\n * The engine's read-partition invariant as a GROQ predicate: a document is\n * visible when its `tags[]` intersect the caller's tag set.\n *\n * @param param - GROQ parameter holding the caller's tags. Defaults to\n * `engineTags`, matching the `workflow.query` guard so any query built with\n * it stays tag-scoped.\n */\nexport function tagScopeFilter(param = 'engineTags'): string {\n return `count(tags[@ in $${param}]) > 0`\n}\n","/**\n * Pure GROQ builder for resolving a deployed workflow definition. Composes the\n * doc-type constant and the tag-scope predicate so the engine's internal\n * lookups and the CLI share one definition of \"tag-scoped, latest-or-pinned\n * `workflow.definition`\" instead of hand-writing the query at each call site.\n */\n\nimport {WORKFLOW_DEFINITION_TYPE} from './define/schema.ts'\nimport {tagScopeFilter} from './tags.ts'\n\n/**\n * GROQ resolving a single deployed {@link WORKFLOW_DEFINITION_TYPE} visible to\n * the caller's tags. With {@link explicit} the query pins `$version`; otherwise\n * it returns the highest deployed version.\n *\n * Params: `$definition`, `$engineTags`, plus `$version` when {@link explicit}.\n *\n * @param explicit - whether the caller wants a specific version (`$version`)\n * rather than the latest.\n */\nexport function definitionLookupGroq(explicit: boolean): string {\n const scoped = `_type == \"${WORKFLOW_DEFINITION_TYPE}\" && name == $definition && ${tagScopeFilter()}`\n return explicit\n ? `*[${scoped} && version == $version][0]`\n : `*[${scoped}] | order(version desc)[0]`\n}\n","/**\n * Shell-side discovery query.\n *\n * Spawn `forEach.groq` scans the lake for rows to spawn child\n * workflows over. These are NOT filters — they look at content that\n * isn't in the snapshot (typically every doc of a given type that\n * references a doc the workflow already knows about). Different\n * semantics, different primitive, different code path from\n * `evaluateFilter`.\n *\n * Keeping discovery out of the filter pipeline is what lets the core\n * stay pure. Filters eval against pre-hydrated data; discovery hits the\n * lake by design.\n */\n\nimport {paramsForLake} from './core/params.ts'\nimport {parseGdr} from './core/refs.ts'\nimport type {WorkflowClient, WorkflowPerspective} from './types/client.ts'\n\n/**\n * Run a discovery GROQ against the appropriate client.\n *\n * The query receives params with GDR IDs stripped back to bare form\n * (via `paramsForLake`) because lake refs are bare. Caller decides\n * which client to use — typically the resource client of the first\n * `doc.ref` state entry, since discovery scans look for items related\n * to docs the workflow already references.\n */\nexport async function discoverItems(args: {\n client: WorkflowClient\n groq: string\n params: Record<string, unknown>\n /**\n * Read-side perspective. When set, the engine threads the instance's\n * `perspective` field through so spawn `forEach.groq` sees a\n * release-stacked view of the lake. Unset → client default.\n */\n perspective?: WorkflowPerspective\n}): Promise<unknown> {\n const {client, groq, params, perspective} = args\n const fetchOptions = perspective !== undefined ? {perspective} : undefined\n return client.fetch(groq, paramsForLake(params), fetchOptions)\n}\n\n/**\n * Convenience: pick the right client for a discovery scan given the\n * subject's GDR URI. Bare ids (no `:`) → default client. Anything\n * parseable → routed client.\n */\nexport function clientForDiscovery(\n defaultClient: WorkflowClient,\n clientForGdr: (parsed: import('./core/refs.ts').ParsedGdr) => WorkflowClient,\n subjectGdrUri: string | undefined,\n): WorkflowClient {\n if (!subjectGdrUri || !subjectGdrUri.includes(':')) return defaultClient\n try {\n return clientForGdr(parseGdr(subjectGdrUri))\n } catch {\n return defaultClient\n }\n}\n","import type {SanityDocument} from '@sanity/types'\nimport {evaluate, parse} from 'groq-js'\n\nimport {runGroq} from '../core/eval.ts'\nimport {buildParams} from '../core/params.ts'\nimport {\n gdrFromResource,\n isGdrUri,\n selfGdr,\n type GlobalDocumentReference,\n type WorkflowResource,\n} from '../core/refs.ts'\nimport type {Subworkflows, Task, WorkflowDefinition} from '../define/schema.ts'\nimport {definitionLookupGroq} from '../definition-query.ts'\nimport {clientForDiscovery, discoverItems} from '../discover.ts'\nimport {buildInstanceBase, effectsContextEntry} from '../instance.ts'\nimport {randomKey} from '../keys.ts'\nimport {derivePerspectiveFromState, resolveDeclaredState} from '../state-resolution.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {EffectsContextEntry} from '../types/effects.ts'\nimport {WORKFLOW_INSTANCE_TYPE, type WorkflowInstance} from '../types/instance.ts'\nimport type {InitialStateValue, ResolvedStateEntry, StateKind} from '../types/state-values.ts'\nimport {\n ctxConditionParams,\n ctxEvaluateCondition,\n type EngineContext,\n gdrToBareId,\n} from './context.ts'\nimport type {MutableInstance} from './mutation.ts'\n\n/**\n * Maximum depth of the subworkflow ancestor chain. A child's depth is\n * `ancestors.length`. With this limit a chain can reach\n * `root → 1 → 2 → 3 → 4 → 5 → 6` (six levels of nesting below root);\n * a spawn that would create a seventh level is rejected.\n *\n * Backstop against runtime recursion that the deploy-time cycle\n * detector cannot see — definitions whose spawn fires conditionally on\n * subject state can produce dynamic recursion without a static cycle\n * in the definition graph.\n */\nconst MAX_SPAWN_DEPTH = 6\n\n/**\n * The implicit completion gate for a `subworkflows` task that declares no\n * `completeWhen`: ALL subworkflows done — the dominant case costs zero\n * syntax, and `every` over an empty fan-out is vacuously true so a\n * zero-row spawn resolves immediately instead of hanging.\n */\nconst SUBWORKFLOWS_ALL_DONE = \"count($subworkflows[status != 'done']) == 0\"\n\n// System actor ids stamped when a resolution gate flips a task — the audit\n// trail's answer to \"who resolved this?\" when no human did.\nconst FAIL_WHEN_SYSTEM_ID = 'engine.failWhen'\nconst COMPLETE_WHEN_SYSTEM_ID = 'engine.completeWhen'\n\n/** The system actor that owns a gate-driven task flip. */\nexport function gateActor(outcome: GateOutcome): Actor {\n return {\n kind: 'system',\n id: outcome === 'failed' ? FAIL_WHEN_SYSTEM_ID : COMPLETE_WHEN_SYSTEM_ID,\n }\n}\n\n/** The status a satisfied resolution gate resolves a task into. */\nexport type GateOutcome = 'done' | 'failed'\n\n/**\n * The task's effective completion gate — explicit `completeWhen`, or the\n * implicit {@link SUBWORKFLOWS_ALL_DONE} default on a spawning task (the\n * dominant case costs zero syntax, and a zero-row fan-out resolves\n * vacuously instead of hanging).\n */\nexport function effectiveCompleteWhen(task: Task): string | undefined {\n return task.completeWhen ?? (task.subworkflows !== undefined ? SUBWORKFLOWS_ALL_DONE : undefined)\n}\n\n/**\n * Evaluate a task's resolution gate over the task-context scope: `failWhen`\n * first, then the effective `completeWhen` — failure dominates when both\n * fire. Returns the outcome of the first satisfied gate, or undefined when\n * neither holds.\n */\nexport async function evaluateResolutionGate(\n ctx: EngineContext,\n task: Task,\n vars: Record<string, unknown>,\n): Promise<GateOutcome | undefined> {\n const scope = {taskName: task.name, vars}\n if (task.failWhen !== undefined && (await ctxEvaluateCondition(ctx, task.failWhen, scope))) {\n return 'failed'\n }\n const completeWhen = effectiveCompleteWhen(task)\n if (completeWhen !== undefined && (await ctxEvaluateCondition(ctx, completeWhen, scope))) {\n return 'done'\n }\n return undefined\n}\n\n/**\n * Resolve a `subworkflows` declaration's `forEach` against the parent\n * instance, create one subworkflow instance per result row, and return the\n * refs. `with` values are GROQ over the parent's rendered scope plus the\n * iteration `$row`; `context` values evaluate once in the parent's scope and\n * land in each child's `effectsContext` bag (read there as `$effects.<name>`).\n */\nexport async function spawnSubworkflows(\n ctx: EngineContext,\n mutation: MutableInstance,\n task: Task,\n sub: Subworkflows,\n actor: Actor | undefined,\n): Promise<GlobalDocumentReference[]> {\n // Depth backstop. Parent's `ancestors.length` is its own depth; a\n // child would be at `parent.ancestors.length + 1`. Reject before any\n // lake work — the mutation has not been persisted yet, so throwing\n // here is safe.\n if (ctx.instance.ancestors.length + 1 > MAX_SPAWN_DEPTH) {\n const chain = [...ctx.instance.ancestors.map((a) => a.id), selfGdr(ctx.instance)].join(' → ')\n throw new Error(\n `Subworkflow depth limit (${MAX_SPAWN_DEPTH}) exceeded on task \"${task.name}\" of ${ctx.instance._id}. ` +\n `Ancestor chain: ${chain}`,\n )\n }\n\n const now = ctx.now\n const definition = await resolveDefinitionRef(ctx.client, sub.definition, ctx.instance.tags ?? [])\n if (definition === null) {\n const versionLabel =\n sub.definition.version === undefined || sub.definition.version === 'latest'\n ? 'latest'\n : `v${sub.definition.version}`\n throw new Error(\n `Subworkflow definition \"${sub.definition.name}\" ${versionLabel} not deployed (parent ${ctx.instance._id}, task ${task.name})`,\n )\n }\n\n const parentScope = await ctxConditionParams(ctx, {\n taskName: task.name,\n ...(actor ? {actor} : {}),\n })\n const rows = await resolveSpawnRows(ctx, sub)\n const effectsContext = await resolveContextHandoff(ctx, sub, parentScope)\n\n const refs: GlobalDocumentReference[] = []\n for (const row of rows) {\n const initialState = await projectRowState(ctx, sub, definition, parentScope, row)\n const {ref, body} = await prepareChildInstance({\n client: ctx.client,\n parent: ctx.instance,\n definition,\n initialState,\n effectsContext,\n actor,\n now,\n })\n refs.push(ref)\n // Defer the write — `persist` drains `pendingCreates` into one\n // transaction with the parent's patch.\n mutation.pendingCreates.push(body)\n }\n\n return refs\n}\n\n/**\n * Run `subworkflows.forEach` against the lake and return the rows. The\n * groq runs through the discovery client (resourceClients-aware).\n */\nasync function resolveSpawnRows(ctx: EngineContext, sub: Subworkflows): Promise<unknown[]> {\n const params = buildParams({instance: ctx.instance, now: ctx.now, snapshot: ctx.snapshot})\n const groq = sub.forEach\n\n let value: unknown\n if (groq.includes('*')) {\n // Lake discovery — route through resourceClients in case the GROQ\n // targets a different Sanity resource than the parent. We pick the\n // resource by the first workflow-scope `doc.ref` entry's GDR —\n // typically the natural \"subject\" of the workflow. Authors declaring\n // a different routing target should put that doc.ref entry first.\n const routingUri = firstDocRefGdrUri(ctx.instance.state)\n const client = clientForDiscovery(ctx.client, ctx.clientForGdr, routingUri)\n value = await discoverItems({\n client,\n groq,\n params,\n ...(ctx.instance.perspective !== undefined ? {perspective: ctx.instance.perspective} : {}),\n })\n } else {\n // Pure-param GROQ — evaluate in-process against an empty dataset.\n const tree = parse(groq, {params})\n const result = await evaluate(tree, {dataset: [ctx.instance], params, root: ctx.instance})\n value = await result.get()\n }\n\n if (Array.isArray(value)) return value\n if (value === null || value === undefined) return []\n return [value]\n}\n\n/** First workflow-scope `doc.ref` entry GDR URI, if any. Used to pick\n * the discovery client for `subworkflows.forEach`. */\nfunction firstDocRefGdrUri(entries: ResolvedStateEntry[] | undefined): string | undefined {\n if (!entries) return undefined\n for (const s of entries) {\n if (s._type === 'doc.ref' && s.value !== null) return s.value.id\n }\n return undefined\n}\n\n/**\n * Evaluate the `with` map for one row — each value is GROQ over the parent\n * scope with `$row` bound — and shape the results as the child's\n * `initialState`. The CHILD's state declarations dictate each entry's kind:\n * `with` supplies values for the child's `init`-sourced entries by name;\n * naming an entry the child doesn't declare fails loud.\n */\nasync function projectRowState(\n ctx: EngineContext,\n sub: Subworkflows,\n childDefinition: WorkflowDefinition,\n parentScope: Record<string, unknown>,\n row: unknown,\n): Promise<InitialStateValue[]> {\n const out: InitialStateValue[] = []\n for (const [name, groq] of Object.entries(sub.with ?? {})) {\n const declared = (childDefinition.state ?? []).find((e) => e.name === name)\n if (declared === undefined) {\n throw new Error(\n `subworkflows.with[\"${name}\"]: subworkflow \"${childDefinition.name}\" declares no state entry \"${name}\"`,\n )\n }\n const raw = await runGroq(groq, {...parentScope, row}, ctx.snapshot)\n const value = canonicaliseSpawnValue(declared.type, raw, ctx.instance.workflowResource)\n if (value === null || value === undefined) continue\n out.push({\n type: declared.type as InitialStateValue['type'],\n name,\n value: value as InitialStateValue['value'],\n } as InitialStateValue)\n }\n return out\n}\n\n/** Evaluate the `context` map once in the parent's scope — the parent→child\n * handoff that lands in each child's `effectsContext`. */\nasync function resolveContextHandoff(\n ctx: EngineContext,\n sub: Subworkflows,\n parentScope: Record<string, unknown>,\n): Promise<Record<string, string | number | boolean | GlobalDocumentReference>> {\n const out: Record<string, string | number | boolean | GlobalDocumentReference> = {}\n for (const [name, groq] of Object.entries(sub.context ?? {})) {\n const v = await runGroq(groq, parentScope, ctx.snapshot)\n if (v === undefined || v === null) continue\n if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') {\n out[name] = v\n } else if (typeof v === 'object' && 'id' in v && 'type' in v) {\n out[name] = v as GlobalDocumentReference\n }\n }\n return out\n}\n\n/**\n * Canonicalise a projected entry value for `doc.ref` / `doc.refs` kinds.\n * Row projections naturally produce raw row data: bare doc ids,\n * `{ _ref, _type }` envelopes, or `{ id, type }` pairs where `id` may be\n * bare. The engine knows the spawning parent's resource, so it\n * canonicalises bare ids into GDR URIs rooted at that resource.\n *\n * Cross-resource spawns must spell the URI out in GROQ — the engine\n * doesn't infer foreign resources. Other kinds pass through unchanged.\n */\nfunction canonicaliseSpawnValue(\n kind: StateKind,\n value: unknown,\n workflowResource: WorkflowResource,\n): unknown {\n if (kind === 'doc.ref') {\n return coerceSpawnGdr(value, workflowResource)\n }\n if (kind === 'doc.refs') {\n if (!Array.isArray(value)) return value\n return value.map((v) => coerceSpawnGdr(v, workflowResource)).filter((v) => v !== null)\n }\n return value\n}\n\nfunction coerceSpawnGdr(\n raw: unknown,\n workflowResource: WorkflowResource,\n): GlobalDocumentReference | null {\n // Canonicalise a bare doc id into a GDR URI rooted at this resource;\n // leave already-canonical URIs untouched.\n const toUri = (id: string) => (isGdrUri(id) ? id : gdrFromResource(workflowResource, id))\n\n if (raw === null || raw === undefined) return null\n if (typeof raw === 'object' && 'id' in raw && 'type' in raw) {\n const r = raw as {id: unknown; type: unknown}\n if (typeof r.id === 'string' && typeof r.type === 'string') {\n return {id: toUri(r.id), type: r.type}\n }\n }\n if (typeof raw === 'object' && '_ref' in raw) {\n const r = raw as {_ref: unknown}\n if (typeof r._ref === 'string') return {id: toUri(r._ref), type: 'document'}\n }\n if (typeof raw === 'string' && raw.length > 0) return {id: toUri(raw), type: 'document'}\n return null\n}\n\n/**\n * Resolve a logical `{name, version?}` ref to a deployed definition doc.\n * Scopes the lookup to definitions sharing at least one tag with the\n * caller. Picks the highest `version` when omitted or `\"latest\"`.\n *\n * Returns null when no matching definition exists.\n */\nasync function resolveDefinitionRef(\n client: WorkflowClient,\n ref: {name: string; version?: number | 'latest' | undefined},\n tags: string[],\n): Promise<(WorkflowDefinition & SanityDocument) | null> {\n const wantsExplicit = typeof ref.version === 'number'\n const params: Record<string, unknown> = {definition: ref.name, engineTags: tags}\n if (wantsExplicit) params.version = ref.version\n const result = await client.fetch<(WorkflowDefinition & SanityDocument) | null>(\n definitionLookupGroq(wantsExplicit),\n params,\n )\n return result ?? null\n}\n\nasync function prepareChildInstance(args: {\n client: WorkflowClient\n parent: WorkflowInstance\n definition: WorkflowDefinition & SanityDocument\n initialState: InitialStateValue[]\n effectsContext: Record<string, string | number | boolean | GlobalDocumentReference>\n actor: Actor | undefined\n now: string\n}): Promise<{ref: GlobalDocumentReference; body: WorkflowInstance}> {\n const {client, parent, definition, initialState, effectsContext, actor, now} = args\n\n // Child inherits the parent's tags + workflow resource so it stays\n // visible to whichever engine spawned the parent.\n const childTags = parent.tags ?? []\n const childPrefix = childTags[0] ?? 'wf'\n const workflowResource = parent.workflowResource\n // Bare `_id` — Sanity rejects `:` in document IDs. The GDR URI form\n // (`childUri`) is what the parent's `taskEntry.spawnedInstances[]`\n // and the child's own `ancestors[]` reference.\n const childDocId = `${childPrefix}.wf-instance.${randomKey()}`\n const childUri = gdrFromResource(workflowResource, childDocId)\n const childRef: GlobalDocumentReference = {id: childUri, type: WORKFLOW_INSTANCE_TYPE}\n const ancestors = [\n ...parent.ancestors,\n {\n id: selfGdr(parent),\n type: WORKFLOW_INSTANCE_TYPE,\n } as GlobalDocumentReference,\n ]\n\n // Resolve the child's workflow-scope state declarations against the\n // projected `initialState`. The child's own state[] declarations dictate\n // which entry names/kinds exist; the projection just fills the\n // `init`-sourced ones. Query/write entries resolve per their own source.\n // Children inherit the parent's perspective by default — if the parent\n // reads under a release stack, child conditions / discovery should see\n // the same stacked view of the lake.\n const inheritedPerspective = parent.perspective\n const childState = await resolveDeclaredState({\n entryDefs: definition.state,\n initialState,\n ctx: {\n client,\n now,\n selfId: childDocId,\n tags: childTags,\n workflowResource,\n ...(inheritedPerspective !== undefined ? {perspective: inheritedPerspective} : {}),\n },\n randomKey,\n })\n // A child may carry its own `release.ref` entry (projected from the\n // spawn `with`) — that takes precedence over inheritance.\n const childPerspective = derivePerspectiveFromState(childState) ?? inheritedPerspective\n\n const effectsContextEntries: EffectsContextEntry[] = Object.entries(effectsContext).map(\n ([key, value]) => {\n if (typeof value === 'object' && value !== null && 'id' in value && 'type' in value) {\n if (!isGdrUri(value.id)) {\n throw new Error(\n `subworkflows.context[\"${key}\"]: GDR id must be a \"<scheme>:...\" URI, got ${JSON.stringify(value.id)}.`,\n )\n }\n return effectsContextEntry(key, {id: value.id, type: value.type})\n }\n return effectsContextEntry(key, value)\n },\n )\n\n const base = buildInstanceBase({\n id: childDocId,\n now,\n tags: childTags,\n workflowResource,\n definitionName: definition.name,\n pinnedVersion: definition.version,\n definition,\n state: childState,\n effectsContext: effectsContextEntries,\n ancestors,\n perspective: childPerspective,\n initialStage: definition.initialStage,\n actor,\n })\n // Body is returned to the caller; the actual `client.create` happens\n // inside the parent's persist transaction so the parent's\n // `spawnedInstances` patch and this child create commit atomically.\n // Priming + cascade run after the transaction (per-child, single-doc).\n return {ref: childRef, body: base}\n}\n\n/**\n * Hydrate the `$subworkflows` rows for a task's conditions. A subworkflow is\n * `done` when its instance terminated — normal completion (reached a stage\n * with no transitions) or an admin abort; both stamp `completedAt`, which an\n * aborted child parks on a non-terminal stage, so this is the one signal that\n * covers both. Otherwise `active`. Instance-level *failure* has no\n * representation yet, so `status == 'failed'` is vacuously false — an explicit\n * `failWhen` over subworkflow state is the workaround until effect/instance\n * failure lands.\n */\nexport async function subworkflowRows(\n ctx: EngineContext,\n refs: readonly GlobalDocumentReference[],\n): Promise<{_id: string; stage: string; status: 'done' | 'active'}[]> {\n if (refs.length === 0) return []\n // Single GROQ — fetches every child in one roundtrip instead of N serial\n // getDocument calls. `ref.id` is the child's GDR URI; the persistent\n // `_id` is bare.\n const ids = refs.map((r) => gdrToBareId(r.id))\n const children = await ctx.client.fetch<\n {_id: string; currentStage: string; completedAt?: string}[]\n >(`*[_id in $ids]{_id, currentStage, completedAt}`, {ids})\n return children.map((c) => ({\n _id: c._id,\n stage: c.currentStage,\n status: c.completedAt !== undefined && c.completedAt !== null ? 'done' : 'active',\n }))\n}\n","/**\n * Pure resolution of the context-free `Source` kinds.\n *\n * A `Source` value declared on ops and state-entry seeds is evaluated into a\n * concrete value. No GROQ, no client, no I/O — just structural lookups\n * against the actor + caller params.\n *\n * Pure: `type: \"now\"` reads the shell-supplied `now` (the engine's\n * {@link Clock}), never wall-clock — so an op's `now` agrees with `$now`\n * in the same eval pass and a frozen clock keeps it deterministic.\n */\n\nimport type {Source} from '../define/schema.ts'\nimport type {Actor} from '../types/actor.ts'\n\n/**\n * Resolve the context-free Source kinds (`literal` / `param` / `actor` /\n * `now`). Returns `{handled: false}` for the kinds that need\n * resolver-specific backing data (`self`, `stage`, `stateRead`, `object`),\n * which the in-mutation op resolver (see `engine/ops.ts`) handles against\n * the mutation it is building.\n */\nexport function resolveStaticSource(\n src: Source,\n ctx: {params?: Record<string, unknown>; actor?: Actor | undefined; now: string},\n): {handled: true; value: unknown} | {handled: false} {\n switch (src.type) {\n case 'literal':\n return {handled: true, value: src.value}\n case 'param':\n return {handled: true, value: ctx.params?.[src.param]}\n case 'actor':\n return {handled: true, value: ctx.actor}\n case 'now':\n return {handled: true, value: ctx.now}\n default:\n return {handled: false}\n }\n}\n","import {getPath} from '../core/path.ts'\nimport {resolveStaticSource} from '../core/source.ts'\nimport {validateStateAppendItem, validateStateValue} from '../core/state-validation.ts'\nimport type {\n Action,\n ActionParam,\n Op,\n OpPredicate,\n Source,\n StoredStateRef,\n} from '../define/schema.ts'\nimport {randomKey} from '../keys.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {StageName, TaskName} from '../types/ids.ts'\nimport {findOpenStageEntry} from '../types/instance-state.ts'\nimport type {ResolvedStateEntry} from '../types/state-values.ts'\nimport {applyTaskStatusChange} from './history-entries.ts'\nimport type {MutableInstance} from './mutation.ts'\nimport {ActionParamsInvalidError, type OpAppliedSummary} from './results.ts'\n\n// Op runner — shared by every lifecycle boundary that carries ops (action\n// fire, transition fire, task activation) — plus action param validation.\n\n/**\n * Op types that mutate workflow state (vs `status.set`, which only flips a\n * task status). `satisfies` ties the list to the {@link Op} union, so a\n * rename or typo breaks compilation here instead of silently turning a\n * downstream state-change gate into a no-op.\n */\nconst STATE_OP_TYPES = [\n 'state.set',\n 'state.unset',\n 'state.append',\n 'state.updateWhere',\n 'state.removeWhere',\n] as const satisfies readonly Op['type'][]\n\n/** Whether an applied op mutated state (and so may have invalidated a guard). */\nexport function isStateOp(summary: OpAppliedSummary): boolean {\n return (STATE_OP_TYPES as readonly string[]).includes(summary.opType)\n}\n\nexport function validateActionParams(\n action: Action,\n taskName: TaskName,\n callerParams: Record<string, unknown> | undefined,\n): Record<string, unknown> {\n const declared = action.params ?? []\n const params = callerParams ?? {}\n const issues: {param: string; reason: string}[] = []\n\n for (const decl of declared) {\n const value = params[decl.name]\n const present = decl.name in params && value !== undefined && value !== null\n if (decl.required === true && !present) {\n issues.push({param: decl.name, reason: 'required but missing'})\n continue\n }\n if (!present) continue\n if (!checkParamType(value, decl)) {\n issues.push({\n param: decl.name,\n reason: `expected type=${decl.type}, got ${typeof value}`,\n })\n }\n }\n if (issues.length > 0) {\n throw new ActionParamsInvalidError({action: action.name, task: taskName, issues})\n }\n return params\n}\n\n/** True when `value` is a non-null object carrying a string-typed `field`. */\nfunction hasStringField(value: unknown, field: string): boolean {\n return (\n typeof value === 'object' &&\n value !== null &&\n field in value &&\n typeof (value as Record<string, unknown>)[field] === 'string'\n )\n}\n\nfunction checkParamType(value: unknown, decl: ActionParam): boolean {\n switch (decl.type) {\n case 'string':\n case 'url':\n case 'dateTime':\n return typeof value === 'string'\n case 'number':\n return typeof value === 'number' && Number.isFinite(value)\n case 'boolean':\n return typeof value === 'boolean'\n case 'actor':\n return hasStringField(value, 'kind')\n case 'doc.ref':\n return hasStringField(value, 'id')\n case 'doc.refs':\n return (\n Array.isArray(value) && value.every((v) => checkParamType(v, {...decl, type: 'doc.ref'}))\n )\n case 'json':\n return true\n default:\n return false\n }\n}\n\n/** Which lifecycle boundary is running these ops — lands on history. */\ninterface OpOrigin {\n task?: TaskName\n action?: string\n transition?: string\n}\n\ninterface RunOpsArgs {\n ops: readonly Op[] | undefined\n mutation: MutableInstance\n stage: StageName\n origin: OpOrigin\n params: Record<string, unknown>\n actor: Actor | undefined\n /** GDR URI of the instance the ops run against, for `Source.self`. */\n self: string\n /** Shell-supplied clock reading (ISO) — `now` op-source + history `at`. */\n now: string\n}\n\nexport function runOps(args: RunOpsArgs): OpAppliedSummary[] {\n const {ops, mutation, stage, origin, params, actor, self, now} = args\n if (ops === undefined || ops.length === 0) return []\n const summaries: OpAppliedSummary[] = []\n for (const op of ops) {\n const summary = applyOp(op, {mutation, stage, taskName: origin.task, params, actor, self, now})\n summaries.push(summary)\n mutation.history.push({\n _key: randomKey(),\n _type: 'opApplied',\n at: now,\n stage,\n ...(origin.task !== undefined ? {task: origin.task} : {}),\n ...(origin.action !== undefined ? {action: origin.action} : {}),\n ...(origin.transition !== undefined ? {transition: origin.transition} : {}),\n opType: summary.opType,\n ...(summary.target !== undefined ? {target: summary.target} : {}),\n ...(summary.resolved !== undefined ? {resolved: summary.resolved} : {}),\n ...(actor !== undefined ? {actor} : {}),\n })\n }\n return summaries\n}\n\ninterface OpContext {\n mutation: MutableInstance\n stage: StageName\n /** The task whose boundary is running — `scope: \"task\"` targets land here. */\n taskName: TaskName | undefined\n params: Record<string, unknown>\n actor: Actor | undefined\n self: string\n now: string\n}\n\nfunction applyOp(op: Op, ctx: OpContext): OpAppliedSummary {\n switch (op.type) {\n case 'state.set':\n return applyStateSet(op, ctx)\n case 'state.unset':\n return applyStateUnset(op, ctx)\n case 'state.append':\n return applyStateAppend(op, ctx)\n case 'state.updateWhere':\n return applyStateUpdateWhere(op, ctx)\n case 'state.removeWhere':\n return applyStateRemoveWhere(op, ctx)\n case 'status.set':\n return applyStatusSet(op, ctx)\n }\n}\n\nfunction applyStateSet(op: Extract<Op, {type: 'state.set'}>, ctx: OpContext): OpAppliedSummary {\n const value = resolveOpSource(op.value, ctx)\n const entry = locateEntry(ctx, op.target)\n // Wrong-shape writes throw `StateValueShapeError` — the engine aborts the\n // commit before persisting.\n validateStateValue({entryType: entry._type, entryName: entry.name, value})\n setEntryValue(entry, value)\n return {opType: op.type, target: op.target, resolved: {value}}\n}\n\n/** Array-valued kinds clear to empty; everything else to null (`!defined`). */\nconst EMPTY_BY_KIND: Partial<Record<ResolvedStateEntry['_type'], unknown[]>> = {\n 'doc.refs': [],\n checklist: [],\n notes: [],\n assignees: [],\n}\n\nfunction applyStateUnset(op: Extract<Op, {type: 'state.unset'}>, ctx: OpContext): OpAppliedSummary {\n const entry = locateEntry(ctx, op.target)\n setEntryValue(entry, EMPTY_BY_KIND[entry._type] ?? null)\n return {opType: op.type, target: op.target}\n}\n\nfunction applyStateAppend(\n op: Extract<Op, {type: 'state.append'}>,\n ctx: OpContext,\n): OpAppliedSummary {\n const item = resolveOpSource(op.value, ctx)\n const entry = locateEntry(ctx, op.target)\n validateStateAppendItem({entryType: entry._type, entryName: entry.name, item})\n const current = Array.isArray(entry.value) ? entry.value : []\n setEntryValue(entry, [...current, withRowKey(item)])\n return {opType: op.type, target: op.target, resolved: {item}}\n}\n\n/** Stamp a `_key` onto a plain-object row that lacks one; scalars and\n * arrays pass through unchanged. */\nfunction withRowKey(item: unknown): unknown {\n if (typeof item === 'object' && item !== null && !Array.isArray(item) && !('_key' in item)) {\n return {_key: randomKey(), ...(item as Record<string, unknown>)}\n }\n return item\n}\n\nfunction applyStateUpdateWhere(\n op: Extract<Op, {type: 'state.updateWhere'}>,\n ctx: OpContext,\n): OpAppliedSummary {\n const entry = locateEntry(ctx, op.target)\n const rows = requireArrayValue(entry, op)\n const merge = resolveOpSource(op.value, ctx)\n if (merge === null || typeof merge !== 'object' || Array.isArray(merge)) {\n throw new Error(\n `state.updateWhere value must resolve to an object of fields to merge (target \"${op.target.state}\")`,\n )\n }\n setEntryValue(\n entry,\n rows.map((row) =>\n evalOpPredicate(op.where, row, ctx) ? {...row, ...(merge as Record<string, unknown>)} : row,\n ),\n )\n return {opType: op.type, target: op.target, resolved: {merge}}\n}\n\nfunction applyStateRemoveWhere(\n op: Extract<Op, {type: 'state.removeWhere'}>,\n ctx: OpContext,\n): OpAppliedSummary {\n const entry = locateEntry(ctx, op.target)\n const rows = requireArrayValue(entry, op)\n setEntryValue(\n entry,\n rows.filter((row) => !evalOpPredicate(op.where, row, ctx)),\n )\n return {opType: op.type, target: op.target}\n}\n\n/**\n * The where-ops walk rows, so their target entry must hold an array. A\n * non-array value is an authoring/deploy divergence — fail hard rather\n * than no-op and report success.\n */\nfunction requireArrayValue(\n entry: ResolvedStateEntry,\n op: Extract<Op, {type: 'state.updateWhere' | 'state.removeWhere'}>,\n): Record<string, unknown>[] {\n if (!Array.isArray(entry.value)) {\n throw new Error(\n `${op.type} target ${op.target.scope}:\"${op.target.state}\" holds a non-array ` +\n `${entry._type} value — where-ops operate on array entries`,\n )\n }\n return entry.value as Record<string, unknown>[]\n}\n\n/**\n * Routes the `status.set` op (the desugared `status:` field included)\n * through {@link applyTaskStatusChange} — the ONE task-status mechanism —\n * after resolving the op's task name against the open stage.\n */\nfunction applyStatusSet(op: Extract<Op, {type: 'status.set'}>, ctx: OpContext): OpAppliedSummary {\n const entry = findOpenStageEntry(ctx.mutation)?.tasks.find((t) => t.name === op.task)\n if (entry === undefined) {\n throw new Error(`status.set targets task \"${op.task}\" which has no entry in the open stage`)\n }\n applyTaskStatusChange({\n entry,\n history: ctx.mutation.history,\n stage: ctx.stage,\n to: op.status,\n at: ctx.now,\n ...(ctx.actor !== undefined ? {actor: ctx.actor} : {}),\n })\n return {opType: op.type, resolved: {task: op.task, status: op.status}}\n}\n\n/**\n * The single write seam for entry values. `ResolvedStateEntry` is a\n * discriminated union whose per-kind `value` types TypeScript cannot relate\n * to a runtime-checked `unknown`, so the write needs a cast — confined here.\n * Every caller writes a shape it validated ({@link validateStateValue} /\n * {@link validateStateAppendItem}) or built from already-valid data (the\n * per-kind empty on unset, the where-op transforms over existing rows).\n */\nfunction setEntryValue(entry: ResolvedStateEntry, value: unknown): void {\n entry.value = value as never\n}\n\n/**\n * Targets were resolved lexically at deploy, so a declared entry MUST exist\n * at runtime — a miss is engine/instance divergence, never an authoring\n * default to paper over. Fail hard.\n */\nfunction locateEntry(ctx: OpContext, target: StoredStateRef): ResolvedStateEntry {\n const host = stateHost(ctx, target.scope)\n const entry = host?.find((s) => s.name === target.state)\n if (entry === undefined) {\n throw new Error(\n `Op target ${target.scope}:\"${target.state}\" has no resolved state entry on this instance — ` +\n `the deployed definition and the instance state have diverged`,\n )\n }\n return entry\n}\n\nfunction stateHost(\n ctx: OpContext,\n scope: StoredStateRef['scope'],\n): ResolvedStateEntry[] | undefined {\n if (scope === 'workflow') return ctx.mutation.state\n const stageEntry = findOpenStageEntry(ctx.mutation)\n if (scope === 'stage') return stageEntry?.state\n const task = stageEntry?.tasks.find((t) => t.name === ctx.taskName)\n if (task !== undefined && task.state === undefined) task.state = []\n return task?.state\n}\n\nfunction resolveOpSource(src: Source, ctx: OpContext): unknown {\n const staticValue = resolveStaticSource(src, ctx)\n if (staticValue.handled) return staticValue.value\n switch (src.type) {\n case 'self':\n // The instance's own GDR URI — matches `$self` in conditions. A GDR\n // string an op can stamp into a value entry (or compose via the\n // object source).\n return ctx.self\n case 'stage':\n return ctx.stage\n case 'stateRead': {\n const value = readEntryFromMutation(ctx, src)\n return src.path !== undefined ? getPath(value, src.path) : value\n }\n case 'object': {\n const out: Record<string, unknown> = {}\n for (const [field, fieldSrc] of Object.entries(src.fields)) {\n out[field] = resolveOpSource(fieldSrc, ctx)\n }\n return out\n }\n default:\n throw new Error(`Source type \"${src.type}\" is a state-entry origin, not a value`)\n }\n}\n\nfunction entryValue(entries: ResolvedStateEntry[] | undefined, name: string): unknown {\n return entries?.find((s) => s.name === name)?.value\n}\n\nfunction readEntryFromMutation(ctx: OpContext, src: Extract<Source, {type: 'stateRead'}>): unknown {\n // Lexical when scope is omitted: nearest declaring scope wins.\n const scopes = src.scope !== undefined ? [src.scope] : (['stage', 'workflow'] as const)\n const stageEntry = findOpenStageEntry(ctx.mutation)\n for (const scope of scopes) {\n const host = scope === 'workflow' ? ctx.mutation.state : stageEntry?.state\n const value = entryValue(host, src.state)\n if (value !== undefined) return value\n }\n return undefined\n}\n\nfunction evalOpPredicate(p: OpPredicate, row: Record<string, unknown>, ctx: OpContext): boolean {\n switch (p.type) {\n case 'all':\n return p.of.every((sub) => evalOpPredicate(sub, row, ctx))\n case 'any':\n return p.of.some((sub) => evalOpPredicate(sub, row, ctx))\n case 'field':\n return row[p.field] === resolveOpSource(p.equals, ctx)\n }\n}\n","import {selfGdr} from '../core/refs.ts'\nimport type {Stage, Task} from '../define/schema.ts'\nimport {randomKey} from '../keys.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {TaskName} from '../types/ids.ts'\nimport type {TaskEntry} from '../types/instance-state.ts'\nimport {\n ctxEvaluateCondition,\n type EngineContext,\n findStage,\n loadContext,\n resolveTaskStateEntries,\n} from './context.ts'\nimport {queueEffects} from './effects.ts'\nimport {applyTaskStatusChange} from './history-entries.ts'\nimport {\n findCurrentTasks,\n findTaskInCurrentStage,\n type MutableInstance,\n persist,\n requireMutationTaskEntry,\n startMutation,\n} from './mutation.ts'\nimport {runOps} from './ops.ts'\nimport type {EngineCallOptions, InvokeResult} from './results.ts'\nimport {\n effectiveCompleteWhen,\n evaluateResolutionGate,\n gateActor,\n spawnSubworkflows,\n subworkflowRows,\n} from './spawn.ts'\n\n/**\n * Manually activate a `pending` task — the explicit path for\n * `activation: \"manual\"` tasks (the default: a task never activates\n * silently). No-op if the task is already active or done.\n */\nexport async function invokeTask(args: {\n client: WorkflowClient\n instanceId: string\n task: TaskName\n options?: EngineCallOptions\n}): Promise<InvokeResult> {\n const {client, instanceId, task: taskName, options} = args\n const ctx = await loadContext(client, instanceId, {\n ...(options?.clock ? {clock: options.clock} : {}),\n })\n return commitInvoke(ctx, taskName, options?.actor)\n}\n\nasync function commitInvoke(\n ctx: EngineContext,\n taskName: TaskName,\n actor: Actor | undefined,\n): Promise<InvokeResult> {\n const {task} = findTaskInCurrentStage(ctx, taskName)\n const entry = findCurrentTasks(ctx.instance).find((t) => t.name === taskName)\n if (entry === undefined) {\n throw new Error(`Task \"${taskName}\" has no status entry on instance ${ctx.instance._id}`)\n }\n if (entry.status !== 'pending') {\n return {invoked: false, task: taskName}\n }\n\n const mutation = startMutation(ctx.instance)\n const mutEntry = requireMutationTaskEntry(mutation, taskName)\n await activateTask(ctx, mutation, task, mutEntry, actor)\n await persist(ctx, mutation)\n return {invoked: true, task: taskName}\n}\n\n/**\n * Activation — the task's lifecycle moment. The full payload runs here:\n * task-scoped state resolves, the task's `ops` apply, its `effects` queue,\n * and a `subworkflows` declaration fans out. Then resolution checks:\n * `failWhen` / `completeWhen` (failure dominates) evaluate over the\n * task-context scope (including `$subworkflows`), and the MACHINE-STEP rule\n * closes the loop — a task with no actions and no `completeWhen` has nothing\n * left to wait for, so it resolves `done` immediately, leaving its audit row.\n */\nexport async function activateTask(\n ctx: EngineContext,\n mutation: MutableInstance,\n task: Task,\n entry: TaskEntry,\n actor: Actor | undefined,\n): Promise<void> {\n // One clock reading for the whole activation so startedAt, any\n // auto-resolve flip, taskActivated, and spawn stamps agree on the time.\n const now = ctx.now\n entry.status = 'active'\n entry.startedAt = now\n if (task.state !== undefined && task.state.length > 0) {\n const stage = findStage(ctx.definition, mutation.currentStage)\n entry.state = await resolveTaskStateEntries({\n client: ctx.client,\n instance: ctx.instance,\n stage,\n task,\n now,\n })\n }\n\n runOps({\n ops: task.ops,\n mutation,\n stage: mutation.currentStage,\n origin: {task: task.name},\n params: {},\n actor,\n self: selfGdr(ctx.instance),\n now,\n })\n\n mutation.history.push({\n _key: randomKey(),\n _type: 'taskActivated',\n at: now,\n stage: mutation.currentStage,\n task: task.name,\n ...(actor !== undefined ? {actor} : {}),\n })\n\n await queueEffects(ctx, mutation, task.effects, {kind: 'task', name: task.name}, actor, {\n taskName: task.name,\n })\n\n let pendingChildren: {_id: string; stage: string; status: 'active'}[] | undefined\n if (task.subworkflows !== undefined) {\n const createsBefore = mutation.pendingCreates.length\n const refs = await spawnSubworkflows(ctx, mutation, task, task.subworkflows, actor)\n entry.spawnedInstances = refs\n // The children only exist on `pendingCreates` until persist's\n // transaction commits — a lake fetch would see NOTHING and the\n // implicit all-done gate would pass vacuously. Synthesize their\n // rows as 'active' so the gate (and any $subworkflows condition)\n // sees the real fan-out; a zero-row spawn still resolves vacuously.\n pendingChildren = mutation.pendingCreates\n .slice(createsBefore)\n .map((c) => ({_id: c._id, stage: c.currentStage, status: 'active' as const}))\n for (const ref of refs) {\n mutation.history.push({\n _key: randomKey(),\n _type: 'spawned',\n at: now,\n task: task.name,\n instanceRef: ref,\n })\n }\n }\n\n if (await autoResolveOnActivate(ctx, mutation, task, entry, now, pendingChildren)) return\n resolveMachineStep(mutation, task, entry, now)\n}\n\n/**\n * Run the task's resolution gate ({@link evaluateResolutionGate}) at\n * activation, immediately resolving the task with the gate's system actor\n * when it fires. Returns true when the task resolved so the caller skips\n * the machine-step check.\n */\nasync function autoResolveOnActivate(\n ctx: EngineContext,\n mutation: MutableInstance,\n task: Task,\n entry: TaskEntry,\n now: string,\n pendingChildren?: {_id: string; stage: string; status: 'active'}[],\n): Promise<boolean> {\n if (task.failWhen === undefined && effectiveCompleteWhen(task) === undefined) return false\n const vars =\n pendingChildren !== undefined\n ? {subworkflows: pendingChildren}\n : await taskConditionVars(ctx, entry)\n const outcome = await evaluateResolutionGate(ctx, task, vars)\n if (outcome === undefined) return false\n applyTaskStatusChange({\n entry,\n history: mutation.history,\n stage: mutation.currentStage,\n to: outcome,\n at: now,\n actor: gateActor(outcome),\n })\n return true\n}\n\n/**\n * The `$subworkflows` rows for a task's conditions — hydrated from the\n * spawned instances so `count($subworkflows[status == 'done'])` works.\n */\nexport async function taskConditionVars(\n ctx: EngineContext,\n entry: TaskEntry,\n): Promise<Record<string, unknown>> {\n if (entry.spawnedInstances === undefined || entry.spawnedInstances.length === 0) {\n return {subworkflows: []}\n }\n return {subworkflows: await subworkflowRows(ctx, entry.spawnedInstances)}\n}\n\n/**\n * A task with no actions and no `completeWhen` is a MACHINE STEP: its whole\n * job was the activation payload, so it resolves `done` immediately — an\n * audit row in the task list where a container hook would have fired\n * invisibly. (A `subworkflows` task without `completeWhen` is NOT a machine\n * step: the default all-done gate applies via the cascade.)\n */\nfunction resolveMachineStep(\n mutation: MutableInstance,\n task: Task,\n entry: TaskEntry,\n now: string,\n): void {\n const waitsForActor = task.actions !== undefined && task.actions.length > 0\n const waitsForCondition = task.completeWhen !== undefined || task.subworkflows !== undefined\n if (waitsForActor || waitsForCondition) return\n applyTaskStatusChange({\n entry,\n history: mutation.history,\n stage: mutation.currentStage,\n to: 'done',\n at: now,\n actor: {kind: 'system', id: 'engine.machineStep'},\n })\n}\n\n/**\n * Build the stage's task entries at enter: a task whose `filter` is falsy\n * against the stage's entry state is `skipped` (conditional enter — different\n * tasks for different arrivals); the rest start `pending` until activation.\n */\nexport async function buildStageTasks(ctx: EngineContext, stage: Stage): Promise<TaskEntry[]> {\n const entries: TaskEntry[] = []\n for (const task of stage.tasks ?? []) {\n const inScope = await ctxEvaluateCondition(ctx, task.filter, {taskName: task.name})\n entries.push({\n _key: randomKey(),\n name: task.name,\n status: inScope ? 'pending' : 'skipped',\n ...(task.filter !== undefined\n ? {\n filterEvaluation: {\n at: ctx.now,\n truthy: inScope,\n },\n }\n : {}),\n })\n }\n return entries\n}\n","import {selfGdr} from '../core/refs.ts'\nimport type {Stage, Transition} from '../define/schema.ts'\nimport {deployStageGuards, retractStageGuards} from '../guards-lifecycle.ts'\nimport {randomKey} from '../keys.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {StageName} from '../types/ids.ts'\nimport {findOpenStageEntry, type StageEntry} from '../types/instance-state.ts'\nimport {\n ctxEvaluateCondition,\n type EngineContext,\n findStage,\n loadContext,\n resolveStageStateEntries,\n} from './context.ts'\nimport {queueEffects} from './effects.ts'\nimport {deployOrRollback} from './guard-commit.ts'\nimport {stageTransitionHistory} from './history-entries.ts'\nimport {\n instanceStateFields,\n materializeInstance,\n type MutableInstance,\n persist,\n startMutation,\n} from './mutation.ts'\nimport {runOps} from './ops.ts'\nimport type {EngineCallOptions, TransitionResult} from './results.ts'\nimport {activateTask, buildStageTasks} from './tasks.ts'\n\n/**\n * A stage with no transitions out IS terminal — structural, not declared.\n * Reaching one completes the instance.\n */\nexport function isTerminalStage(stage: Stage): boolean {\n return (stage.transitions ?? []).length === 0\n}\n\n/**\n * Admin override — force the instance into `targetStage` regardless of\n * conditions or declared transitions. Use cases: Kanban-style UI where\n * each column is a stage; migration scripts; manual recovery from a\n * stuck workflow. ACL gating is enforced at the API layer.\n *\n * Behaviour mirrors a successful transition: exit current stage, append\n * a fresh StageEntry for the target, auto-activate the target's\n * `activation: \"auto\"` tasks, cascade. The history entries carry\n * `via: \"setStage\"` so audits can distinguish condition-driven\n * transitions from admin overrides.\n */\nexport async function setStage(args: {\n client: WorkflowClient\n instanceId: string\n targetStage: StageName\n reason?: string\n options?: EngineCallOptions\n}): Promise<TransitionResult> {\n const {client, instanceId, targetStage, reason, options} = args\n const ctx = await loadContext(client, instanceId, {\n ...(options?.clock ? {clock: options.clock} : {}),\n })\n return commitSetStage(ctx, targetStage, reason, options?.actor)\n}\n\n/**\n * Append a fresh {@link StageEntry} for `nextStage` and run the on-entry\n * lifecycle. A stage is a pure container — it carries no payload of its own;\n * ENTER work belongs to the tasks (`activation: \"auto\"` ones light up here,\n * conditionally via their `filter`), and ARRIVAL work rode in on the firing\n * transition. A stage with no transitions IS terminal — nothing to declare —\n * so reaching one completes the instance. The caller owns history,\n * prior-stage exit, persistence, and guard reconciliation. `at` is the single\n * timestamp stamped on the entry.\n */\nasync function enterStage(\n ctx: EngineContext,\n mutation: MutableInstance,\n nextStage: Stage,\n actor: Actor | undefined,\n at: string,\n): Promise<void> {\n mutation.currentStage = nextStage.name\n const nextStageEntry: StageEntry = {\n _key: randomKey(),\n name: nextStage.name,\n enteredAt: at,\n state: await resolveStageStateEntries({\n client: ctx.client,\n instance: ctx.instance,\n stage: nextStage,\n now: at,\n }),\n tasks: await buildStageTasks(ctx, nextStage),\n }\n mutation.stages.push(nextStageEntry)\n\n for (const task of nextStage.tasks ?? []) {\n if (task.activation !== 'auto') continue\n const entry = nextStageEntry.tasks.find((t) => t.name === task.name)\n if (entry && entry.status === 'pending') {\n await activateTask(ctx, mutation, task, entry, actor)\n }\n }\n\n if (isTerminalStage(nextStage)) {\n mutation.completedAt = at\n }\n}\n\n/**\n * A terminal instance never moves again — by transition or admin override.\n * Terminal stages declare no transitions, so for normal completion this is\n * belt-and-braces; an aborted instance, though, parks `completedAt` on a\n * non-terminal stage whose transitions and setStage targets still exist.\n * Without this gate a tick/cascade or admin move would re-animate a dead\n * instance: a fresh open StageEntry, re-queued effects, and re-deployed\n * guards that no exit path could ever retract.\n */\nfunction isTerminal(ctx: EngineContext): boolean {\n return ctx.instance.completedAt !== undefined\n}\n\nasync function commitSetStage(\n ctx: EngineContext,\n targetStage: StageName,\n reason: string | undefined,\n actor: Actor | undefined,\n): Promise<TransitionResult> {\n if (isTerminal(ctx)) {\n return {fired: false}\n }\n const currentStage = findStage(ctx.definition, ctx.instance.currentStage)\n const nextStage = findStage(ctx.definition, targetStage)\n if (currentStage.name === nextStage.name) {\n return {fired: false}\n }\n\n const mutation = startMutation(ctx.instance)\n const at = ctx.now\n\n const transitionName = `setStage:${currentStage.name}->${nextStage.name}`\n mutation.history.push(\n ...stageTransitionHistory({\n fromStage: currentStage.name,\n toStage: nextStage.name,\n at,\n transition: transitionName,\n via: 'setStage',\n ...(actor !== undefined ? {actor} : {}),\n ...(reason !== undefined ? {reason} : {}),\n }),\n )\n\n const priorEntry = findOpenStageEntry(mutation)\n if (priorEntry !== undefined) priorEntry.exitedAt = at\n\n await enterStage(ctx, mutation, nextStage, actor, at)\n\n await persistStageMove(ctx, mutation, currentStage.name, nextStage.name)\n\n return {\n fired: true,\n fromStage: currentStage.name,\n toStage: nextStage.name,\n transition: transitionName,\n }\n}\n\n/**\n * Persist a stage move, then reconcile its lake guards — deploy the entered\n * stage's, then lift the exited stage's. The two are deliberately separate, not\n * a single `reconcile`, because of rollback ordering:\n *\n * - Deploying the entered stage's lock runs *inside* the rollback scope. If it\n * fails, the move rolls back and the **exited** stage's guards are untouched —\n * the stage we return to is still enforced. (Retract-then-deploy would have\n * left the exited stage unlocked on a deploy failure.)\n * - Lifting the exited stage's guards runs *after* the move commits, resolved\n * against the pre-move `ctx.instance` so its stage-scoped reads still\n * resolve (post-move that stage entry is `exitedAt`-stamped). A retract\n * failure leaves a stale lock on the prior stage — the documented orphan seam,\n * the safe (over-lock) direction — rather than an unlocked stage.\n */\nasync function persistStageMove(\n ctx: EngineContext,\n mutation: MutableInstance,\n exitedStage: StageName,\n enteredStage: StageName,\n): Promise<void> {\n await persistThenDeploy(ctx, mutation, () =>\n deployStageGuards({\n client: ctx.client,\n clientForGdr: ctx.clientForGdr,\n instance: materializeInstance(ctx.instance, mutation),\n definition: ctx.definition,\n stageName: enteredStage,\n now: ctx.now,\n }),\n )\n await retractStageGuards({\n client: ctx.client,\n clientForGdr: ctx.clientForGdr,\n instance: ctx.instance,\n definition: ctx.definition,\n stageName: exitedStage,\n now: ctx.now,\n })\n}\n\n/**\n * Commit a mutation, then deploy its stage's guards — rolling the commit back\n * (or screaming when it can't) if the deploy fails, so persisted state and\n * deployed guards never silently diverge. Guards deploy AFTER the commit: a\n * guard can lock the caller out of further edits, so it must follow the state\n * it enforces. When the commit was a spawn transaction it created child docs a\n * parent-only rollback can't undo, so that case screams instead of half-undoing.\n * This is the shared commit+deploy chokepoint for the transition and action paths.\n */\nexport async function persistThenDeploy(\n ctx: EngineContext,\n mutation: MutableInstance,\n deploy: () => Promise<void>,\n): Promise<void> {\n const spawned = mutation.pendingCreates.length > 0\n const committed = await persist(ctx, mutation)\n await deployOrRollback({\n client: ctx.client,\n instanceId: ctx.instance._id,\n committedRev: committed._rev,\n restore: instanceStateFields(ctx.instance),\n unset: ctx.instance.completedAt === undefined ? ['completedAt'] : [],\n reversible: !spawned,\n deploy,\n })\n}\n\n/**\n * Re-deploy the current stage's guards against post-mutation state. A guard\n * snapshots the workflow state its `match.idRefs`/`metadata` reads resolve to\n * at deploy time; when ops change that state without a stage move, the engine\n * must refresh the guard so it stays coherent (the \"use the engine, stay\n * consistent\" contract). Idempotent upsert — re-resolves each guard's reads\n * against the new state via {@link materializeInstance}.\n *\n * Caveat: refresh only upserts. If an op changes a guard's `match.idRefs`\n * *target* (not just metadata), the re-deploy writes the guard to the new\n * resource while the old one lingers — the orphan/cross-dataset seam documented\n * in `guards-lifecycle.ts`. The metadata-change case (stable idRef) is fully\n * coherent; idRef re-homing waits on the retract/GC work.\n *\n * The caller runs this through {@link persistThenDeploy}, so a failed\n * re-deploy rolls the state change back rather than leaving it stale. One\n * coherence relaxation: {@link deployStageGuards} no-ops if a concurrent\n * transition moved the instance off `stageName` between the persist and the\n * deploy. The refresh is then correctly skipped (refreshing a left stage would\n * itself be wrong) and the state op stands — `deployOrRollback` sees success,\n * so this is not a divergence, it's the newer transition taking ownership.\n */\nexport async function refreshStageGuards(\n ctx: EngineContext,\n mutation: MutableInstance,\n stageName: StageName,\n): Promise<void> {\n await deployStageGuards({\n client: ctx.client,\n clientForGdr: ctx.clientForGdr,\n instance: materializeInstance(ctx.instance, mutation),\n definition: ctx.definition,\n stageName,\n now: ctx.now,\n })\n}\n\nexport async function commitTransition(\n ctx: EngineContext,\n actor: Actor | undefined,\n): Promise<TransitionResult> {\n if (isTerminal(ctx)) {\n return {fired: false}\n }\n const currentStage = findStage(ctx.definition, ctx.instance.currentStage)\n const transition = await pickTransition(ctx, currentStage)\n if (transition === undefined) {\n return {fired: false}\n }\n\n const mutation = startMutation(ctx.instance)\n const at = ctx.now\n\n // State-write-on-move: the transition's ops run in the same audited\n // commit, before its effects queue so bindings read the updated state.\n runOps({\n ops: transition.ops,\n mutation,\n stage: currentStage.name,\n origin: {transition: transition.name},\n params: {},\n actor,\n self: selfGdr(ctx.instance),\n now: at,\n })\n\n await queueEffects(\n ctx,\n mutation,\n transition.effects,\n {\n kind: 'transition',\n name: transition.name,\n },\n actor,\n )\n\n mutation.history.push(\n ...stageTransitionHistory({\n fromStage: currentStage.name,\n toStage: transition.to,\n at,\n transition: transition.name,\n ...(actor !== undefined ? {actor} : {}),\n }),\n )\n\n // Mark the prior stage exited. There can be multiple entries with the\n // same name from loop-backs — the current one has no exitedAt.\n const priorEntry = findOpenStageEntry(mutation)\n if (priorEntry !== undefined) priorEntry.exitedAt = at\n\n const nextStage = findStage(ctx.definition, transition.to)\n await enterStage(ctx, mutation, nextStage, actor, at)\n\n await persistStageMove(ctx, mutation, currentStage.name, nextStage.name)\n\n return {\n fired: true,\n fromStage: currentStage.name,\n toStage: transition.to,\n transition: transition.name,\n }\n}\n\n/**\n * Transition selection — one rule: every transition is evaluated on every\n * commit and cascade; the first truthy `filter` in declaration order fires.\n * A transition is purely a condition over the rendered scope — routing\n * differences are written into state by actions and read here.\n */\nasync function pickTransition(ctx: EngineContext, stage: Stage): Promise<Transition | undefined> {\n for (const candidate of stage.transitions ?? []) {\n if (await ctxEvaluateCondition(ctx, candidate.filter)) return candidate\n }\n return undefined\n}\n","// Essential commit⇄cascade mutual recursion: `mutation.persist` is the single\n// transactional commit chokepoint, and committing a parent that spawned\n// subworkflows must drive those children's lifecycle (prime → cascade →\n// propagate) inline, which itself commits through `persist`. Children are\n// primed *within* the parent's commit so the parent's completion gate observes\n// them in the same pass — deferring the drive to a higher layer would break\n// that synchronous nested-workflow semantics. Resolved at call time; module\n// init is unaffected.\n// fallow-ignore-file circular-dependencies\nimport type {Clock} from '../clock.ts'\nimport type {ParsedGdr} from '../core/refs.ts'\nimport type {LoadedDoc} from '../core/snapshot.ts'\nimport type {Stage, Task, WorkflowDefinition} from '../define/schema.ts'\nimport {deployStageGuards} from '../guards-lifecycle.ts'\nimport {randomKey} from '../keys.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {StageEntry} from '../types/instance-state.ts'\nimport {\n parseDefinitionSnapshot,\n WORKFLOW_INSTANCE_TYPE,\n type WorkflowInstance,\n} from '../types/instance.ts'\nimport {\n buildEngineContext,\n type EngineContext,\n findStage,\n gdrToBareId,\n loadContext,\n resolveStageStateEntries,\n} from './context.ts'\nimport {deployOrRollback} from './guard-commit.ts'\nimport {applyTaskStatusChange} from './history-entries.ts'\nimport {currentTasks, findCurrentTasks, persist, startMutation} from './mutation.ts'\nimport {CascadeLimitError, type EngineCallOptions, type TransitionResult} from './results.ts'\nimport {\n effectiveCompleteWhen,\n evaluateResolutionGate,\n gateActor,\n type GateOutcome,\n} from './spawn.ts'\nimport {commitTransition} from './stages.ts'\nimport {activateTask, buildStageTasks, taskConditionVars} from './tasks.ts'\n\n/**\n * Re-evaluate transitions. Use after any change that might unblock one\n * (e.g. after a fireAction commits) — selection is one rule: first truthy\n * `filter` in declaration order fires.\n */\nasync function evaluateAutoTransitions(args: {\n client: WorkflowClient\n instanceId: string\n options?: EngineCallOptions\n clientForGdr?: (parsed: ParsedGdr) => WorkflowClient\n clock?: Clock\n overlay?: ReadonlyMap<string, LoadedDoc>\n}): Promise<TransitionResult> {\n const {client, instanceId, options, clientForGdr, clock, overlay} = args\n const ctx = await loadContext(client, instanceId, {\n ...(clientForGdr ? {clientForGdr} : {}),\n ...(clock ? {clock} : {}),\n ...(overlay ? {overlay} : {}),\n })\n return commitTransition(ctx, options?.actor)\n}\n\n// Initial-stage priming, cascade, propagation — used by both api.ts (for\n// fresh instances and after-call cascading) and the spawn path inside\n// activateTask. Exported so api.ts doesn't reimplement them.\n\n/**\n * Build the initial stage entry + auto-activate its `activation: \"auto\"`\n * tasks for a freshly-created instance. Called by both\n * `workflow.startInstance` and the spawn path. The stage itself carries no\n * payload — enter work belongs to the tasks.\n */\nexport async function primeInitialStage(\n client: WorkflowClient,\n instanceId: string,\n actor: Actor | undefined,\n clientForGdr?: (parsed: ParsedGdr) => WorkflowClient,\n clock?: Clock,\n): Promise<void> {\n const instance = await client.getDocument<WorkflowInstance>(instanceId)\n if (!instance) return\n // Idempotency: if the initial stage entry is already on the instance,\n // skip. New instances arrive here with `stages: []`.\n if (instance.stages.length > 0) return\n\n const definition = parseDefinitionSnapshot(instance)\n const stage = definition.stages.find((s) => s.name === instance.currentStage)\n if (stage === undefined) return\n\n const ctx = await buildEngineContext({\n client,\n clientForGdr: clientForGdr ?? (() => client),\n instance,\n definition,\n ...(clock ? {clock} : {}),\n })\n // One clock reading for the whole prime so condition `$now`, the stage\n // entry, and the commit all agree on the time.\n const now = ctx.now\n\n const initialStageEntry: StageEntry = {\n _key: randomKey(),\n name: stage.name,\n enteredAt: now,\n state: await resolveStageStateEntries({client, instance, stage, now}),\n tasks: await buildStageTasks(ctx, stage),\n }\n\n // Patch — fails fast if the instance was deleted between the\n // `create` above and this prime call. `ifRevisionId` rejects concurrent\n // priming attempts (e.g. a retried startInstance).\n const committed = await client\n .patch(instance._id)\n .set({\n stages: [initialStageEntry],\n lastChangedAt: now,\n })\n .ifRevisionId(instance._rev)\n .commit()\n\n // Deploy lake guards for the initial stage (no exit to retract). If the\n // deploy fails, roll the prime back to the freshly-created (unprimed) state\n // so an instance never sits primed-but-unlocked; surface the error.\n await deployOrRollback({\n client,\n instanceId: instance._id,\n committedRev: committed._rev,\n restore: {\n stages: instance.stages,\n history: instance.history,\n },\n reversible: true,\n deploy: () =>\n deployStageGuards({\n client,\n clientForGdr: clientForGdr ?? (() => client),\n instance,\n definition,\n stageName: stage.name,\n now,\n }),\n })\n\n await autoActivatePrimedTasks(client, instanceId, definition, stage, actor, clientForGdr, clock)\n}\n\n/**\n * After the initial stage entry is persisted, re-load and activate the\n * `activation: \"auto\"` tasks. Each activation reloads + persists\n * independently so subworkflow fan-outs + auto-resolution see committed\n * state.\n */\nasync function autoActivatePrimedTasks(\n client: WorkflowClient,\n instanceId: string,\n definition: WorkflowDefinition,\n stage: Stage,\n actor: Actor | undefined,\n clientForGdr?: (parsed: ParsedGdr) => WorkflowClient,\n clock?: Clock,\n): Promise<void> {\n const resolvedClientForGdr = clientForGdr ?? (() => client)\n for (const task of stage.tasks ?? []) {\n if (task.activation !== 'auto') continue\n const updated = await client.getDocument<WorkflowInstance>(instanceId)\n if (!updated) continue\n const updatedCtx = await buildEngineContext({\n client,\n clientForGdr: resolvedClientForGdr,\n instance: updated,\n definition,\n ...(clock ? {clock} : {}),\n })\n const mutation = startMutation(updated)\n const mutEntry = currentTasks(mutation).find((t) => t.name === task.name)\n if (mutEntry && mutEntry.status === 'pending') {\n await activateTask(updatedCtx, mutation, task, mutEntry, actor)\n await persist(updatedCtx, mutation)\n }\n }\n}\n\n// Backpressure for the auto-transition cascade. Ops mutate state once per\n// `fireAction` (a finite authored list — no re-entrancy, so they need no\n// per-action limit of their own), but the *transitions* an op unblocks can\n// flip-flop without end. This is the single bound that catches that runaway;\n// it throws {@link CascadeLimitError} rather than writing revisions forever.\nconst CASCADE_LIMIT = 100\n\n/**\n * Walk active task entries whose definition carries an auto-resolution\n * gate — an explicit `completeWhen` / `failWhen`, or the implicit\n * all-subworkflows-done gate — evaluate against the current snapshot, and\n * flip any matching task. Failure dominates when both fire.\n *\n * The engine never runs a clock itself — this only fires if something\n * else (a `tick`, a `fireAction`, a `completeEffect`, or `startInstance`)\n * has already kicked the cascade. A scheduler crossing a deadline calls\n * `tick` (with an injected {@link Clock} under test); state-based\n * conditions rely on the caller invoking `tick` when state changes.\n */\ntype AutoResolveCandidate = {task: Task; outcome: GateOutcome}\n\n/** For each active gated task, run {@link evaluateResolutionGate} over the\n * task-context scope and collect the outcome. */\nasync function gatherAutoResolveCandidates(\n ctx: EngineContext,\n tasks: Task[],\n): Promise<AutoResolveCandidate[]> {\n const currentTasksList = findCurrentTasks(ctx.instance)\n const candidates: AutoResolveCandidate[] = []\n for (const task of tasks) {\n const entry = currentTasksList.find((e) => e.name === task.name)\n if (entry?.status !== 'active') continue\n const outcome = await evaluateResolutionGate(ctx, task, await taskConditionVars(ctx, entry))\n if (outcome !== undefined) candidates.push({task, outcome})\n }\n return candidates\n}\n\nasync function resolveCompleteWhen(\n client: WorkflowClient,\n instanceId: string,\n clientForGdr?: (parsed: ParsedGdr) => WorkflowClient,\n clock?: Clock,\n overlay?: ReadonlyMap<string, LoadedDoc>,\n): Promise<number> {\n const ctx = await loadContext(client, instanceId, {\n ...(clientForGdr ? {clientForGdr} : {}),\n ...(clock ? {clock} : {}),\n ...(overlay ? {overlay} : {}),\n })\n const stage = findStage(ctx.definition, ctx.instance.currentStage)\n const gatedTasks = (stage.tasks ?? []).filter(\n (t) => effectiveCompleteWhen(t) !== undefined || t.failWhen !== undefined,\n )\n if (gatedTasks.length === 0) return 0\n\n const candidates = await gatherAutoResolveCandidates(ctx, gatedTasks)\n if (candidates.length === 0) return 0\n\n const mutation = startMutation(ctx.instance)\n let count = 0\n for (const {task, outcome} of candidates) {\n const mutEntry = currentTasks(mutation).find((t) => t.name === task.name)\n if (mutEntry === undefined || mutEntry.status !== 'active') continue\n applyTaskStatusChange({\n entry: mutEntry,\n history: mutation.history,\n stage: stage.name,\n to: outcome,\n at: ctx.now,\n actor: gateActor(outcome),\n })\n count++\n }\n if (count > 0) {\n await persist(ctx, mutation)\n }\n return count\n}\n\n/**\n * Cascade auto-transitions on the given instance until it lands stably.\n * Returns the count of transitions fired during the cascade. Resolves\n * any auto-gated tasks before each transition pass so a gate that became\n * satisfied can immediately unblock an `$allTasksDone`-style condition.\n */\nexport async function cascadeAutoTransitions(\n client: WorkflowClient,\n instanceId: string,\n actor: Actor | undefined,\n clientForGdr?: (parsed: ParsedGdr) => WorkflowClient,\n clock?: Clock,\n overlay?: ReadonlyMap<string, LoadedDoc>,\n): Promise<number> {\n let count = 0\n while (true) {\n await resolveCompleteWhen(client, instanceId, clientForGdr, clock, overlay)\n const result = await evaluateAutoTransitions({\n client,\n instanceId,\n ...(actor !== undefined ? {options: {actor}} : {}),\n ...(clientForGdr ? {clientForGdr} : {}),\n ...(clock ? {clock} : {}),\n ...(overlay ? {overlay} : {}),\n })\n if (!result.fired) return count\n count++\n if (count >= CASCADE_LIMIT) {\n throw new CascadeLimitError({instanceId, limit: CASCADE_LIMIT})\n }\n }\n}\n\n/**\n * Walk up an instance's ancestor chain, re-evaluating each ancestor's\n * spawning task in case its completion gate is now satisfied. If a parent\n * task flips as a result, cascade auto-transitions on the parent and\n * recurse upward.\n *\n * This is the load-bearing primitive for nested workflows: subworkflow\n * transitions ripple up the tree, parent gates close, grand-parent\n * gates close, all the way to the root.\n */\ninterface ResolvedParentSpawn {\n parent: WorkflowInstance\n definition: WorkflowDefinition\n stage: Stage\n task: Task\n outcome: GateOutcome\n}\n\n/** The parent whose spawning task this child belongs to, when that task's\n * gate (explicit `completeWhen`/`failWhen` or the implicit all-done) is now\n * satisfied — or undefined (no ancestors, parent gone/malformed, no matching\n * task, task already resolved, gate not yet met). */\nasync function findResolvedParentSpawn(\n client: WorkflowClient,\n child: WorkflowInstance,\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient,\n clock?: Clock,\n): Promise<ResolvedParentSpawn | undefined> {\n const parentRef = child.ancestors.at(-1)\n if (parentRef === undefined) return undefined\n // ancestors[].id is the GDR URI; the Sanity `_id` is bare.\n const parent = await client.getDocument<WorkflowInstance>(gdrToBareId(parentRef.id))\n // A misconfigured caller could put an arbitrary doc ref in ancestors[];\n // bail gracefully instead of crashing on `JSON.parse(undefined)`.\n if (!parent || parent._type !== WORKFLOW_INSTANCE_TYPE) return undefined\n if (typeof parent.definitionSnapshot !== 'string') return undefined\n\n const definition = parseDefinitionSnapshot(parent)\n const stage = definition.stages.find((s) => s.name === parent.currentStage)\n if (stage === undefined) return undefined\n\n // Find the task on the parent's current stage that spawned this child.\n // `spawnedInstances[].id` is the child's GDR URI; the `_id` is bare.\n const parentCurrentTasks = findCurrentTasks(parent)\n const task = (stage.tasks ?? []).find((t) => {\n if (t.subworkflows === undefined) return false\n const entry = parentCurrentTasks.find((e) => e.name === t.name)\n return entry?.spawnedInstances?.some((r) => gdrToBareId(r.id) === child._id) ?? false\n })\n if (task?.subworkflows === undefined) return undefined\n\n const entry = parentCurrentTasks.find((e) => e.name === task.name)\n if (entry === undefined || entry.status !== 'active') return undefined\n\n const ctx = await buildEngineContext({\n client,\n clientForGdr,\n instance: parent,\n definition,\n ...(clock ? {clock} : {}),\n })\n const outcome = await evaluateResolutionGate(ctx, task, await taskConditionVars(ctx, entry))\n if (outcome === undefined) return undefined\n return {parent, definition, stage, task, outcome}\n}\n\nexport async function propagateToAncestors(\n client: WorkflowClient,\n instanceId: string,\n actor: Actor | undefined,\n clientForGdr?: (parsed: ParsedGdr) => WorkflowClient,\n clock?: Clock,\n): Promise<void> {\n const instance = await client.getDocument<WorkflowInstance>(instanceId)\n if (!instance) return\n\n const resolvedClientForGdr = clientForGdr ?? (() => client)\n const found = await findResolvedParentSpawn(client, instance, resolvedClientForGdr, clock)\n if (found === undefined) return\n const {parent, definition, stage, task, outcome} = found\n\n // Flip the parent's task and persist. The flip is the spawning task's\n // resolution gate firing, so it carries the gate's system actor — not\n // the caller that happened to drive the propagation.\n const ctx = await buildEngineContext({\n client,\n clientForGdr: resolvedClientForGdr,\n instance: parent,\n definition,\n ...(clock ? {clock} : {}),\n })\n const mutation = startMutation(parent)\n const mutEntry = currentTasks(mutation).find((e) => e.name === task.name)\n if (mutEntry === undefined) return\n applyTaskStatusChange({\n entry: mutEntry,\n history: mutation.history,\n stage: stage.name,\n to: outcome,\n at: ctx.now,\n actor: gateActor(outcome),\n })\n await persist(ctx, mutation)\n\n // Cascade auto-transitions on the parent. This may transition it to\n // a new stage, which itself may unblock the grandparent's task.\n await cascadeAutoTransitions(client, parent._id, actor, clientForGdr, clock)\n\n // Recurse: propagate from the parent upward.\n await propagateToAncestors(client, parent._id, actor, clientForGdr, clock)\n}\n","import type {SanityDocument} from '@sanity/types'\n\nimport type {Stage, Task} from '../define/schema.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {EffectHistoryEntry, EffectsContextEntry, PendingEffect} from '../types/effects.ts'\nimport type {HistoryEntry} from '../types/history.ts'\nimport type {StageName, TaskName} from '../types/ids.ts'\nimport {findOpenStageEntry, type StageEntry, type TaskEntry} from '../types/instance-state.ts'\nimport type {WorkflowInstance} from '../types/instance.ts'\nimport type {ResolvedStateEntry} from '../types/state-values.ts'\nimport {cascadeAutoTransitions, primeInitialStage, propagateToAncestors} from './cascade.ts'\nimport {type EngineContext, findStage} from './context.ts'\n\n// Internal — commits\n\nexport interface MutableInstance {\n currentStage: StageName\n state: ResolvedStateEntry[]\n stages: StageEntry[]\n pendingEffects: PendingEffect[]\n effectHistory: EffectHistoryEntry[]\n effectsContext: EffectsContextEntry[]\n history: HistoryEntry[]\n lastChangedAt: string\n completedAt?: string\n abortedAt?: string\n /**\n * Net-new child workflow instances queued by `spawnChildren` during\n * this mutation. Drained at `persist` time into a single same-resource\n * transaction so the parent's `spawnedInstances` patch and the child\n * `create`s commit atomically.\n */\n pendingCreates: WorkflowInstance[]\n}\n\nexport function startMutation(instance: WorkflowInstance): MutableInstance {\n return {\n currentStage: instance.currentStage,\n // Deep-ish copy. Per-scope state entry arrays need their own copies\n // so ops can mutate without leaking into the source.\n state: (instance.state ?? []).map((s) => ({...s})),\n stages: instance.stages.map((s) => ({\n ...s,\n state: (s.state ?? []).map((entry) => ({...entry})),\n tasks: s.tasks.map((t) => ({\n ...t,\n ...(t.state !== undefined ? {state: t.state.map((entry) => ({...entry}))} : {}),\n })),\n })),\n pendingEffects: [...instance.pendingEffects],\n effectHistory: [...instance.effectHistory],\n effectsContext: [...instance.effectsContext],\n history: [...instance.history],\n lastChangedAt: instance.lastChangedAt,\n ...(instance.completedAt !== undefined ? {completedAt: instance.completedAt} : {}),\n ...(instance.abortedAt !== undefined ? {abortedAt: instance.abortedAt} : {}),\n pendingCreates: [],\n }\n}\n\n/**\n * The persisted state fields of an instance, sans `lastChangedAt`. Single\n * source for both `persist` (what a commit writes) and guard-failure rollback\n * (what restoring the pre-commit instance must write back), so the two can't\n * drift. `completedAt` is included only when set — callers rolling back a move\n * that newly completed an instance must `unset` it separately.\n */\nexport function instanceStateFields(\n src: Pick<\n MutableInstance,\n | 'currentStage'\n | 'state'\n | 'stages'\n | 'pendingEffects'\n | 'effectHistory'\n | 'effectsContext'\n | 'history'\n | 'completedAt'\n | 'abortedAt'\n >,\n): Record<string, unknown> {\n const fields: Record<string, unknown> = {\n currentStage: src.currentStage,\n state: src.state,\n stages: src.stages,\n pendingEffects: src.pendingEffects,\n effectHistory: src.effectHistory,\n effectsContext: src.effectsContext,\n history: src.history,\n }\n if (src.completedAt !== undefined) fields.completedAt = src.completedAt\n if (src.abortedAt !== undefined) fields.abortedAt = src.abortedAt\n return fields\n}\n\n/**\n * A read-only `WorkflowInstance` view of an in-flight mutation: the persisted\n * identity/provenance fields from `base`, with the mutated `currentStage` /\n * `state` / `stages` layered on. Guard (re)deployment resolves Sources against\n * this so it sees post-move state, not the stale loaded instance.\n */\nexport function materializeInstance(\n base: WorkflowInstance,\n mutation: MutableInstance,\n): WorkflowInstance {\n return {\n ...base,\n currentStage: mutation.currentStage,\n state: mutation.state,\n stages: mutation.stages,\n }\n}\n\nexport async function persist(\n ctx: EngineContext,\n mutation: MutableInstance,\n): Promise<SanityDocument> {\n // Patch (not createOrReplace): patches require the doc to exist, so\n // a deleted instance mid-cascade fails fast instead of getting\n // silently resurrected. `ifRevisionId` adds optimistic concurrency —\n // if another writer raced us, the patch errors instead of clobbering.\n const set: Record<string, unknown> = {\n ...instanceStateFields(mutation),\n lastChangedAt: ctx.now,\n }\n\n const pendingCreates = mutation.pendingCreates\n if (pendingCreates.length === 0) {\n return ctx.client.patch(ctx.instance._id).set(set).ifRevisionId(ctx.instance._rev).commit()\n }\n\n // Multi-doc same-resource write: bundle the N child creates with the\n // parent's patch in one Sanity transaction. Children inherit the\n // parent's `workflowResource` so they are always provably same-resource.\n const tx = ctx.client.transaction()\n for (const body of pendingCreates) tx.create(body)\n tx.patch(ctx.client.patch(ctx.instance._id).set(set).ifRevisionId(ctx.instance._rev))\n await tx.commit()\n mutation.pendingCreates = []\n\n // Children are now durably in the lake with the parent's\n // `spawnedInstances` recorded atomically. Prime each child's initial\n // stage, cascade to whatever stage it lands on (possibly terminal),\n // then propagate up — a child that reached terminal needs to\n // re-evaluate its parent's spawn-completion gate. Pre-refactor,\n // `spawnChildren` ran per-child create+prime+cascade synchronously\n // and `activateTask`'s in-memory `checkSpawnCompletion` flipped the\n // parent's task done in the same mutation; deferring creates into\n // the transaction means we restore that effect via explicit\n // propagation here.\n const actorForPriming: Actor | undefined = undefined\n for (const body of pendingCreates) {\n await primeInitialStage(ctx.client, body._id, actorForPriming, ctx.clientForGdr, ctx.clock)\n await cascadeAutoTransitions(ctx.client, body._id, actorForPriming, ctx.clientForGdr, ctx.clock)\n await propagateToAncestors(ctx.client, body._id, actorForPriming, ctx.clientForGdr, ctx.clock)\n }\n\n // Reload the parent so callers see the post-commit `_rev`. Persist's\n // historical return shape is the patched parent doc; preserve that.\n const reloaded = await ctx.client.getDocument<SanityDocument>(ctx.instance._id)\n if (!reloaded) {\n throw new Error(`Instance ${ctx.instance._id} disappeared after transaction commit`)\n }\n return reloaded\n}\n\n// Helpers for working with the per-stage task entries. The open\n// StageEntry lookup is {@link findOpenStageEntry} (in types/instance-state).\n\nfunction currentStageEntry(mutation: MutableInstance): StageEntry {\n const entry = findOpenStageEntry(mutation)\n if (entry === undefined) {\n throw new Error(\n `Mutation invariant broken: no current (un-exited) StageEntry for currentStage \"${mutation.currentStage}\"`,\n )\n }\n return entry\n}\n\nexport function currentTasks(mutation: MutableInstance): TaskEntry[] {\n return currentStageEntry(mutation).tasks\n}\n\n/** Find a task definition on the instance's current stage, throwing a\n * consistent error when it isn't declared there. */\nexport function findTaskInCurrentStage(\n ctx: EngineContext,\n taskName: TaskName,\n): {stage: Stage; task: Task} {\n const stage = findStage(ctx.definition, ctx.instance.currentStage)\n const task = (stage.tasks ?? []).find((t) => t.name === taskName)\n if (task === undefined) {\n throw new Error(\n `Task \"${taskName}\" not found in current stage \"${stage.name}\" of ${ctx.definition.name}`,\n )\n }\n return {stage, task}\n}\n\n/** The mutation copy's entry for `task`. Throws if it vanished — the\n * live instance and its mutation copy must agree on task identity. */\nexport function requireMutationTaskEntry(mutation: MutableInstance, task: TaskName): TaskEntry {\n const mutEntry = currentTasks(mutation).find((t) => t.name === task)\n if (mutEntry === undefined) {\n throw new Error(`Task \"${task}\" disappeared from mutation copy — invariant broken`)\n }\n return mutEntry\n}\n\nfunction findCurrentStageEntry(instance: WorkflowInstance): StageEntry | undefined {\n return findOpenStageEntry(instance)\n}\n\nexport function findCurrentTasks(instance: WorkflowInstance): TaskEntry[] {\n return findCurrentStageEntry(instance)?.tasks ?? []\n}\n","import {resolveBindings} from '../core/bindings.ts'\nimport type {GlobalDocumentReference} from '../core/refs.ts'\nimport type {Effect} from '../define/schema.ts'\nimport {effectsContextJsonEntry} from '../instance.ts'\nimport {randomKey} from '../keys.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {EffectHistoryEntry, EffectOrigin, PendingEffect} from '../types/effects.ts'\nimport type {HistoryEntry} from '../types/history.ts'\nimport {ctxConditionParams, type EngineContext, loadContext} from './context.ts'\nimport {materializeInstance, type MutableInstance, persist, startMutation} from './mutation.ts'\nimport type {CompleteEffectResult, EngineCallOptions} from './results.ts'\n\n/**\n * Mark a queued effect as completed. Drains it from `pendingEffects`,\n * appends an `EffectHistoryEntry`, and (if `outputs` are supplied)\n * upserts them into `effectsContext` under the effect's name — making them\n * available to downstream effect bindings and conditions as\n * `$effects['<effect name>'].<output>`.\n *\n * This is the only path that mutates `effectsContext` after start.\n */\nexport async function completeEffect(args: {\n client: WorkflowClient\n instanceId: string\n effectKey: string\n status: 'done' | 'failed'\n outputs?: Record<string, string | number | boolean | GlobalDocumentReference>\n detail?: string\n error?: {message: string; stack?: string}\n durationMs?: number\n options?: EngineCallOptions\n}): Promise<CompleteEffectResult> {\n const {client, instanceId, effectKey, status, outputs, detail, error, durationMs, options} = args\n const ctx = await loadContext(client, instanceId, {\n ...(options?.clock ? {clock: options.clock} : {}),\n })\n return commitCompleteEffect(\n ctx,\n effectKey,\n status,\n outputs,\n detail,\n error,\n durationMs,\n options?.actor,\n )\n}\n\n/** Build the {@link EffectHistoryEntry} recorded when a queued effect\n * completes, carrying the pending entry's identity forward and stamping\n * the run outcome. A supplied `actor` overrides the pending entry's. */\nexport function buildEffectHistoryEntry(\n pending: PendingEffect,\n outcome: {\n status: 'done' | 'failed'\n ranAt: string\n actor: Actor | undefined\n detail: string | undefined\n error: {message: string; stack?: string} | undefined\n durationMs: number | undefined\n outputs: Record<string, string | number | boolean | GlobalDocumentReference> | undefined\n },\n): EffectHistoryEntry {\n const {status, ranAt, actor, detail, error, durationMs, outputs} = outcome\n const resolvedActor = actor ?? pending.actor\n return {\n _key: pending._key,\n name: pending.name,\n ...(pending.title !== undefined ? {title: pending.title} : {}),\n ...(pending.description !== undefined ? {description: pending.description} : {}),\n params: pending.params,\n origin: pending.origin,\n ...(resolvedActor !== undefined ? {actor: resolvedActor} : {}),\n ranAt,\n ...(durationMs !== undefined ? {durationMs} : {}),\n status,\n ...(detail !== undefined ? {detail} : {}),\n ...(error !== undefined ? {error} : {}),\n ...(outputs !== undefined ? {outputs} : {}),\n }\n}\n\n/** Upsert a completed effect's outputs record into the mutation's\n * `effectsContext` as one entry keyed by the effect's name, replacing any\n * existing entry with that name. */\nfunction upsertEffectsContext(\n mutation: MutableInstance,\n effectName: string,\n outputs: Record<string, string | number | boolean | GlobalDocumentReference>,\n): void {\n const existingIndex = mutation.effectsContext.findIndex((e) => e.name === effectName)\n const entry = effectsContextJsonEntry(effectName, outputs)\n if (existingIndex >= 0) mutation.effectsContext[existingIndex] = entry\n else mutation.effectsContext.push(entry)\n}\n\nasync function commitCompleteEffect(\n ctx: EngineContext,\n effectKey: string,\n status: 'done' | 'failed',\n outputs: Record<string, string | number | boolean | GlobalDocumentReference> | undefined,\n detail: string | undefined,\n error: {message: string; stack?: string} | undefined,\n durationMs: number | undefined,\n actor: Actor | undefined,\n): Promise<CompleteEffectResult> {\n const pending = ctx.instance.pendingEffects.find((e) => e._key === effectKey)\n if (pending === undefined) {\n throw new Error(`Pending effect \"${effectKey}\" not found on instance ${ctx.instance._id}`)\n }\n\n const mutation = startMutation(ctx.instance)\n mutation.pendingEffects = mutation.pendingEffects.filter((e) => e._key !== effectKey)\n\n const ranAt = ctx.now\n mutation.effectHistory.push(\n buildEffectHistoryEntry(pending, {status, ranAt, actor, detail, error, durationMs, outputs}),\n )\n\n if (status === 'done' && outputs !== undefined) {\n upsertEffectsContext(mutation, pending.name, outputs)\n }\n\n mutation.history.push({\n _key: randomKey(),\n _type: 'effectCompleted',\n at: ranAt,\n effectKey,\n effect: pending.name,\n status,\n ...(outputs !== undefined ? {outputs} : {}),\n ...(detail !== undefined ? {detail} : {}),\n ...(actor !== undefined ? {actor} : {}),\n })\n\n await persist(ctx, mutation)\n return {effectKey, status}\n}\n\n/** Materialise one queued effect: its {@link PendingEffect} envelope and\n * the matching `effectQueued` history entry, sharing a freshly-minted\n * `_key`. Caller pushes each into the right array. */\nfunction buildQueuedEffect(\n effect: Effect,\n origin: EffectOrigin,\n params: Record<string, unknown>,\n actor: Actor | undefined,\n now: string,\n): {pending: PendingEffect; history: HistoryEntry} {\n const key = randomKey()\n const pending: PendingEffect = {\n _key: key,\n _type: 'pendingEffect',\n name: effect.name,\n ...(effect.title !== undefined ? {title: effect.title} : {}),\n ...(effect.description !== undefined ? {description: effect.description} : {}),\n ...(effect.bindings !== undefined ? {bindings: effect.bindings} : {}),\n params,\n origin,\n ...(actor !== undefined ? {actor} : {}),\n queuedAt: now,\n }\n const history: HistoryEntry = {\n _key: randomKey(),\n _type: 'effectQueued',\n at: now,\n effectKey: key,\n effect: effect.name,\n origin,\n }\n return {pending, history}\n}\n\n/**\n * Queue a boundary's effects. Bindings are GROQ over the rendered scope and\n * see the FRESHEST state — evaluated against the in-progress mutation so an\n * op that ran earlier in the same commit is visible to a bound effect.\n */\nexport async function queueEffects(\n ctx: EngineContext,\n mutation: MutableInstance,\n effects: Effect[] | undefined,\n origin: EffectOrigin,\n actor: Actor | undefined,\n opts?: {callerParams?: Record<string, unknown>; taskName?: string},\n): Promise<void> {\n if (!effects || effects.length === 0) return\n const now = ctx.now\n const liveCtx: EngineContext = {...ctx, instance: materializeInstance(ctx.instance, mutation)}\n const params = await ctxConditionParams(liveCtx, {\n ...(opts?.taskName !== undefined ? {taskName: opts.taskName} : {}),\n ...(actor !== undefined ? {actor} : {}),\n // Caller-supplied action params, readable in bindings as `$params.<name>`.\n vars: {params: opts?.callerParams ?? {}},\n })\n for (const effect of effects) {\n const resolved = await resolveBindings({\n bindings: effect.bindings,\n staticInput: effect.input,\n snapshot: ctx.snapshot,\n params,\n })\n const {pending, history} = buildQueuedEffect(effect, origin, resolved, actor, now)\n mutation.pendingEffects.push(pending)\n mutation.history.push(history)\n }\n}\n","import {retractStageGuards} from '../guards-lifecycle.ts'\nimport {randomKey} from '../keys.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {StageName} from '../types/ids.ts'\nimport {findOpenStageEntry} from '../types/instance-state.ts'\nimport {type EngineContext, findStage, loadContext} from './context.ts'\nimport {buildEffectHistoryEntry} from './effects.ts'\nimport {persist, startMutation} from './mutation.ts'\nimport type {EngineCallOptions} from './results.ts'\n\nexport type AbortResult = {fired: false} | {fired: true; stage: StageName}\n\n/**\n * Admin override — hard-stop an in-flight instance where it stands.\n * Unlike reaching a terminal stage this is not a graceful exit: no\n * transition fires (so no transition ops or effects), task statuses freeze\n * as-is for audit, and every still-pending effect is cancelled so no\n * drainer can dispatch it post-abort. Stamps `abortedAt` alongside\n * `completedAt` (same instant) — in-flight queries keep their single\n * `!defined(completedAt)` shape; `abortedAt` carries the distinction.\n * ACL gating is enforced at the API layer.\n *\n * Aborting an already-terminal instance (completed or aborted) is a\n * `{fired: false}` no-op, mirroring `setStage`'s same-stage behaviour.\n */\nexport async function abortInstance(args: {\n client: WorkflowClient\n instanceId: string\n reason?: string\n options?: EngineCallOptions\n}): Promise<AbortResult> {\n const {client, instanceId, reason, options} = args\n const ctx = await loadContext(client, instanceId, {\n ...(options?.clock ? {clock: options.clock} : {}),\n })\n return commitAbort(ctx, reason, options?.actor)\n}\n\nasync function commitAbort(\n ctx: EngineContext,\n reason: string | undefined,\n actor: Actor | undefined,\n): Promise<AbortResult> {\n if (ctx.instance.completedAt !== undefined) {\n return {fired: false}\n }\n\n const stage = findStage(ctx.definition, ctx.instance.currentStage)\n const mutation = startMutation(ctx.instance)\n const at = ctx.now\n\n const openEntry = findOpenStageEntry(mutation)\n if (openEntry !== undefined) openEntry.exitedAt = at\n\n // Cancel the queue: every pending effect moves to effectHistory as\n // failed, so a concurrent drainer that re-reads finds nothing to claim.\n mutation.effectHistory.push(\n ...mutation.pendingEffects.map((pending) =>\n buildEffectHistoryEntry(pending, {\n status: 'failed',\n ranAt: at,\n actor,\n detail: 'instance aborted before dispatch',\n error: undefined,\n durationMs: undefined,\n outputs: undefined,\n }),\n ),\n )\n mutation.pendingEffects = []\n\n mutation.history.push({\n _key: randomKey(),\n _type: 'aborted',\n at,\n stage: stage.name,\n ...(reason !== undefined ? {reason} : {}),\n ...(actor !== undefined ? {actor} : {}),\n })\n\n mutation.completedAt = at\n mutation.abortedAt = at\n\n await persist(ctx, mutation)\n\n // Lift the aborted stage's lake guards after the commit, resolved\n // against the pre-abort instance — same ordering and orphan seam as\n // the exited-stage retraction in a stage move (a retract failure\n // leaves a stale lock, the safe over-lock direction).\n await retractStageGuards({\n client: ctx.client,\n clientForGdr: ctx.clientForGdr,\n instance: ctx.instance,\n definition: ctx.definition,\n stageName: stage.name,\n now: ctx.now,\n })\n\n return {fired: true, stage: stage.name}\n}\n","/**\n * Permissions — GROQ-filter-based grant evaluation.\n *\n * Sanity ACLs come back as `Grant[]`. Each grant has a GROQ `filter`\n * and a list of `permissions` it confers. Whether a permission is\n * allowed on a given document is \"does any grant whose filter matches\n * the document carry that permission?\". Most-permissive wins; multiple\n * grants compose.\n *\n * Filters are evaluated with groq-js (already a dependency for transition\n * filter evaluation) so the engine doesn't ship a second predicate engine.\n */\n\nimport {evaluate, parse} from 'groq-js'\n\nimport type {Grant} from './types/authorization.ts'\nimport type {DocumentValuePermission} from './types/enums.ts'\n\n// Parsed-filter cache, keyed by the filter string. AST is cheap to\n// reuse; the evaluation against a document is what we want to keep\n// uncached because the document changes much more often than the filter.\nconst parsedFilters = new Map<string, ReturnType<typeof parse>>()\n\n/**\n * Evaluate a grant's GROQ filter against a single document with the\n * supplied identity. Returns true iff the document survives the filter.\n *\n * The implementation parses `*[<filter>]` once per filter string,\n * evaluates against a singleton dataset, and asks the result for its\n * length — `length === 1` means the doc passed.\n */\nexport async function matchesFilter(args: {\n document: {_id?: string; _type?: string; [key: string]: unknown}\n filter: string\n userId?: string\n}): Promise<boolean> {\n const {document, filter, userId} = args\n if (!parsedFilters.has(filter)) {\n parsedFilters.set(filter, parse(`*[${filter}]`))\n }\n const ast = parsedFilters.get(filter)!\n const result = await evaluate(ast, {\n dataset: [document],\n ...(userId !== undefined ? {identity: userId} : {}),\n })\n const data = await result.get()\n return Array.isArray(data) && data.length === 1\n}\n\n/**\n * Does the supplied `grants` set grant `permission` on `document` for\n * the given user? Walks each grant; a grant counts iff its filter\n * matches AND it lists the permission. Most-permissive wins.\n */\nexport async function grantsPermissionOn(args: {\n document?: {_id?: string; _type?: string; [key: string]: unknown}\n grants: Grant[]\n permission: DocumentValuePermission\n userId?: string\n}): Promise<boolean> {\n const {document, grants, permission, userId} = args\n if (!document || grants.length === 0) return false\n\n for (const grant of grants) {\n if (!grant.permissions.includes(permission)) continue\n if (\n await matchesFilter({\n document,\n filter: grant.filter,\n ...(userId !== undefined ? {userId} : {}),\n })\n ) {\n return true\n }\n }\n return false\n}\n\n/**\n * Convenience: fetch the grants for a given resource via the supplied\n * client:\n *\n * GET <resourcePath> → Grant[]\n *\n * `resourcePath` is caller-supplied so the same helper works for\n * project ACLs (`/projects/<id>/datasets/<dataset>/acl`) and for a\n * dedicated workflow-collaboration resource. The client must support\n * the `request<T>({url})` method `@sanity/client` exposes.\n */\nexport async function fetchGrants(args: {\n client: {request: <T>(opts: {url: string; signal?: AbortSignal}) => Promise<T>}\n resourcePath: string\n signal?: AbortSignal\n}): Promise<Grant[]> {\n const {client, resourcePath, signal} = args\n return client.request<Grant[]>({url: resourcePath, ...(signal ? {signal} : {})})\n}\n","/**\n * Access state — the cohesive (actor + grants) pair the engine\n * relies on for every authorization decision: one provider, one\n * cached resolution.\n *\n * Resolution strategy:\n *\n * 1. **Override.** If the caller supplies an `access` object on the\n * verb (or the bench's `createBench({ access })`), it wins — no\n * network calls. This is the only path that fires for the test\n * bench, whose `TestClient` has no token-bearing `request` method.\n * 2. **Token.** Otherwise the engine resolves both halves from the\n * supplied `@sanity/client`:\n * - `actor` ← `client.request({ url: \"/users/me\" })`\n * - `grants` ← `client.request({ url: grantsFromPath })`\n * Run in parallel; cached per-client (and per-path for grants) via\n * WeakMap so concurrent verb calls share one fetch.\n * 3. **Refusal.** If the client can't make HTTP requests (`request`\n * undefined) and no override was supplied, the engine throws a\n * clear error pointing at the bench / explicit override.\n *\n * Grants-fetch failure degrades open (gate is skipped, real Sanity\n * write boundary still enforces). Actor-fetch failure is fatal — the\n * engine refuses to stamp history without an identity.\n */\n\nimport {fetchGrants} from './permissions.ts'\nimport type {Actor} from './types/actor.ts'\nimport type {Grant} from './types/authorization.ts'\nimport type {WorkflowClient} from './types/client.ts'\n\n/** The options bag accepted by {@link WorkflowClient.request}. */\ntype RequestOptions = Parameters<NonNullable<WorkflowClient['request']>>[0]\n\n/**\n * Sanity's `/users/me` response shape — subset of `@sanity/types`'s\n * `CurrentUser`. Declared locally so the engine doesn't take a\n * runtime dep on `@sanity/types` for a single type.\n */\ninterface SanityCurrentUser {\n id: string\n name?: string\n email?: string\n /** @deprecated singular `role` on legacy responses */\n role?: string\n roles?: {name: string; title?: string; description?: string}[]\n}\n\n/**\n * The engine's view of \"who am I, what can I do?\". `actor` is who\n * the engine stamps onto history / `completedBy` / `Source.actor`.\n * `grants` (when present) gates `permission-denied`; when absent the\n * gate is skipped and the real Sanity write boundary takes over.\n *\n * This is the RESOLVED shape — `actor` is guaranteed. For the\n * partial-override shape callers pass on verb args, see\n * `WorkflowAccessOverride`.\n */\nexport interface WorkflowAccess {\n actor: Actor\n grants?: Grant[]\n}\n\n/**\n * Partial override accepted by every public verb's `access?:`\n * argument. Any field present wins; missing halves token-resolve.\n *\n * `{ actor, grants }` — bench's all-access default; both halves\n * injected, no token round-trip.\n * `{ actor }` — \"act as another user\"; grants come from\n * `grantsFromPath` (or the gate is skipped).\n * `{ grants }` — \"preview with restricted permissions\"; actor\n * comes from `/users/me`.\n * omitted entirely — both halves token-resolved.\n */\nexport type WorkflowAccessOverride = Partial<WorkflowAccess>\n\nexport interface ResolveAccessArgs {\n /**\n * Partial override. Any field set here wins outright; any field\n * left unset falls through to token resolution.\n *\n * - `override.actor` set + `override.grants` set → returned as-is.\n * - `override.actor` set + `override.grants` unset → actor from\n * override; grants fetched from `grantsFromPath` (or undefined).\n * - `override.actor` unset + `override.grants` set → actor from\n * `/users/me`; grants from override.\n * - `override` undefined entirely → both halves fetched.\n *\n * The test bench passes a fully-populated `{ actor, grants }` so\n * the underlying TestClient (no `request` method) never hits the\n * token path. Admin/preview tooling passes one or the other.\n */\n override?: {actor?: Actor; grants?: Grant[]}\n /**\n * Where the engine should fetch grants from the supplied client\n * when `override.grants` isn't given, e.g. a Canvas resource at\n * `/canvases/<resourceId>/acl` or a dataset at\n * `/projects/<id>/datasets/<ds>/acl`.\n */\n grantsFromPath?: string\n}\n\n// Actor cache is per-client. /users/me doesn't vary by path; one\n// fetch per client lifetime suffices.\nconst actorCache = new WeakMap<object, Promise<Actor | undefined>>()\n\n// Grants cache is per-(client, path). Multiple consumers in one\n// process can share the same client across different resources.\nconst grantsCache = new WeakMap<object, Map<string, Promise<Grant[] | undefined>>>()\n\n/**\n * Resolve the engine's `WorkflowAccess` for a client. Override wins\n * outright; otherwise both halves are fetched in parallel and\n * cached. Throws if neither path yields an actor — the engine\n * refuses to operate without an identity.\n */\nexport async function resolveAccess(\n client: WorkflowClient,\n args: ResolveAccessArgs = {},\n): Promise<WorkflowAccess> {\n const overrideActor = args.override?.actor\n const overrideGrants = args.override?.grants\n\n // Fast path: bench supplies both halves; no token needed.\n if (overrideActor !== undefined && overrideGrants !== undefined) {\n return {actor: overrideActor, grants: overrideGrants}\n }\n\n // Reaching here, the fast path above ruled out \"both halves supplied\",\n // so at least one half needs the client. A client with no `request`\n // can't fetch either: throw if the missing half is the actor, otherwise\n // degrade open on grants (the production \"endpoint unreachable\" path).\n //\n // Wrap `request` once so every downstream call site (actor + grants)\n // invokes it AS a method on `client`. `@sanity/client` >= 7.22 reads a\n // private field through `this`, so a detached `const fn = client.request;\n // fn(...)` loses `this` and throws before issuing the request. The\n // wrapper stays lazy: a plain `.bind` here would dereference `request`\n // eagerly even when an override supplies the only half we need, tripping\n // clients (e.g. the in-memory bench) whose `request` is a throw-on-use\n // stub. `=== undefined` preserves the probe for clients with no `request`.\n const requestFn: NonNullable<WorkflowClient['request']> | undefined =\n client.request === undefined ? undefined : <T>(opts: RequestOptions) => client.request!<T>(opts)\n if (requestFn === undefined) {\n if (overrideActor === undefined) {\n throw new Error(\n \"workflow: no actor available. The engine resolves the actor from the client's token \" +\n \"via `client.request({ url: '/users/me' })`. Supply a real `@sanity/client` configured \" +\n 'with a token, or pass an explicit `access.actor` override (the test bench provides ' +\n 'one by default).',\n )\n }\n return {actor: overrideActor}\n }\n\n const actorPromise =\n overrideActor !== undefined ? Promise.resolve(overrideActor) : cachedActor(client, requestFn)\n\n const grantsPromise = resolveGrants(overrideGrants, args.grantsFromPath, client, requestFn)\n\n const [actor, grants] = await Promise.all([actorPromise, grantsPromise])\n if (actor === undefined) {\n throw new Error(\n 'workflow: failed to resolve actor from `/users/me`. The client is configured but the ' +\n 'endpoint returned no usable identity — check the token, or pass `access.actor` explicitly.',\n )\n }\n return {actor, ...(grants !== undefined ? {grants} : {})}\n}\n\nfunction cachedActor(\n client: WorkflowClient,\n requestFn: NonNullable<WorkflowClient['request']>,\n): Promise<Actor | undefined> {\n const cached = actorCache.get(client)\n if (cached !== undefined) return cached\n\n // Evict on failure so a transient `/users/me` error (401/503/network)\n // doesn't poison the per-client cache for its lifetime — the next call\n // retries instead of permanently throwing \"failed to resolve actor\".\n const pending = fetchActor(requestFn).catch((err) => {\n if (actorCache.get(client) === pending) actorCache.delete(client)\n throw err\n })\n actorCache.set(client, pending)\n return pending\n}\n\nfunction resolveGrants(\n overrideGrants: Grant[] | undefined,\n grantsFromPath: string | undefined,\n client: WorkflowClient,\n requestFn: NonNullable<WorkflowClient['request']>,\n): Promise<Grant[] | undefined> {\n if (overrideGrants !== undefined) return Promise.resolve(overrideGrants)\n if (grantsFromPath !== undefined) return cachedGrants(client, requestFn, grantsFromPath)\n return Promise.resolve(undefined)\n}\n\nfunction cachedGrants(\n client: WorkflowClient,\n requestFn: NonNullable<WorkflowClient['request']>,\n resourcePath: string,\n): Promise<Grant[] | undefined> {\n let byPath = grantsCache.get(client)\n if (byPath === undefined) {\n byPath = new Map()\n grantsCache.set(client, byPath)\n }\n let cached = byPath.get(resourcePath)\n if (cached === undefined) {\n cached = fetchGrantsCached(requestFn, resourcePath)\n byPath.set(resourcePath, cached)\n }\n return cached\n}\n\nasync function fetchActor(\n requestFn: <T>(opts: {\n url?: string\n uri?: string\n signal?: AbortSignal\n tag?: string\n }) => Promise<T>,\n): Promise<Actor | undefined> {\n // `@sanity/client.request` distinguishes `uri` (project-API path,\n // resolved against the apiHost — e.g. `https://api.sanity.io/v1/users/me`)\n // from `url` (raw URL). `/users/me` is a global endpoint accessed via\n // `uri`. Studio itself uses `uri: '/users/me'` in its authStore\n // (sanity-v3 `createAuthStore.ts`). Using `url` here makes the\n // request hit the project-scoped endpoint, which returns empty for\n // the global user — causing \"no usable identity\" errors in studio.\n let user: SanityCurrentUser\n try {\n user = await requestFn<SanityCurrentUser>({\n uri: '/users/me',\n tag: 'workflow.access.resolve-actor',\n })\n } catch (err) {\n // Surface the request failure with its cause intact so the eventual\n // throw is diagnosable — and let it propagate so the per-client cache\n // is evicted and the next call retries (transient 401/503/network).\n throw new Error(\n \"workflow: /users/me request failed. The engine resolves the actor from the client's token \" +\n 'via `client.request({ uri: \"/users/me\" })`. Check the token/connectivity, or pass an ' +\n 'explicit `access.actor` override.',\n {cause: err},\n )\n }\n // A well-formed response that carries no usable identity is NOT an\n // error worth retrying — return undefined so the caller throws its\n // \"no usable identity\" message.\n if (!user || typeof user.id !== 'string' || user.id.length === 0) return undefined\n const roleNames = user.roles?.map((r) => r.name).filter((n): n is string => Boolean(n)) ?? []\n return {\n kind: 'user',\n id: user.id,\n ...(roleNames.length > 0 ? {roles: roleNames} : {}),\n }\n}\n\nasync function fetchGrantsCached(\n requestFn: NonNullable<WorkflowClient['request']>,\n resourcePath: string,\n): Promise<Grant[] | undefined> {\n try {\n return await fetchGrants({client: {request: requestFn}, resourcePath})\n } catch (err) {\n console.warn(\n `workflow: failed to fetch grants from \"${resourcePath}\"; skipping permission gate. ` +\n `Original error: ${err instanceof Error ? err.message : String(err)}`,\n )\n return undefined\n }\n}\n","/**\n * Shell-side guard reads, two kinds. The verdict load\n * ({@link verdictGuardsForInstance}) feeds evaluate/fireAction/tick and is\n * physically scoped to the engine's own datasource. The housekeeping reads\n * ({@link guardsForResource}, {@link guardsForInstance},\n * {@link guardsForDefinition}) exist for coherency refresh and DX/cleanup and\n * union across every datasource in scope.\n *\n * Retract lifts a guard's predicate rather than deleting it, so prior-stage\n * resources still hold guard docs that housekeeping must find — hence the\n * housekeeping reads union across every resource in scope and dedup by `_id`.\n */\n\nimport {parseGdr, type ParsedGdr, type WorkflowResource} from './core/refs.ts'\nimport type {Stage, StateEntry, WorkflowDefinition} from './define/schema.ts'\nimport {collectEntryDocUris, resourceFromParsed} from './snapshot.ts'\nimport {GUARD_DOC_TYPE, type MutationGuardDoc} from './types/authorization.ts'\nimport type {WorkflowClient} from './types/client.ts'\nimport type {WorkflowInstance} from './types/instance.ts'\n\nconst resourceKey = (r: WorkflowResource): string => `${r.type}.${r.id}`\n\n/** Every guard in one resource, regardless of which workflow registered it. */\nexport function guardsForResource(client: WorkflowClient): Promise<MutationGuardDoc[]> {\n return client.fetch<MutationGuardDoc[]>(`*[_type == $t] | order(_id asc)`, {t: GUARD_DOC_TYPE})\n}\n\n/**\n * The per-instance guard filter — the single definition of \"this instance's\n * guards in one datasource\". The engine's verdict load\n * ({@link verdictGuardsForInstance}) fetches it once against the engine\n * datasource; the reactive adapters feed the same query/params to their\n * stores as a live subscription; {@link guardsForInstance} unions it across\n * datasources for housekeeping. Matches lifted guards too (predicate\n * `\"true\"`) — the consumer decides how to render a lifted guard.\n */\nexport function instanceGuardQuery(instanceId: string): {\n query: string\n params: Record<string, string>\n} {\n return {\n query: `*[_type == $guardType && sourceInstanceId == $instanceId]`,\n params: {guardType: GUARD_DOC_TYPE, instanceId},\n }\n}\n\n/**\n * The guards allowed to influence this instance's verdicts, read from the\n * engine's own datasource only. A guard enforces solely within the datasource\n * it physically lives in, and `resourceType`/`resourceId` are plain document\n * fields any writer in that datasource can set — so a verdict load must be\n * physically scoped: a guard doc in a watched content dataset that\n * self-declares the engine's resource id must never reach a verdict. This\n * keeps the advisory layer consistent (verdicts are UX, the lake enforces);\n * it is not itself a security boundary. Runs the same query the reactive\n * adapters subscribe with ({@link instanceGuardQuery}), so the stateless and\n * reactive paths agree.\n */\nexport function verdictGuardsForInstance(\n client: WorkflowClient,\n instanceId: string,\n): Promise<MutationGuardDoc[]> {\n const {query, params} = instanceGuardQuery(instanceId)\n return client.fetch<MutationGuardDoc[]>(query, params)\n}\n\nexport interface GuardsForInstanceArgs {\n client: WorkflowClient\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient\n instance: WorkflowInstance\n}\n\n/**\n * All guards this instance registered, unioned across every resource it\n * touches. Dedups resources by resource key and results by `_id`.\n * Housekeeping only — never a verdict input ({@link verdictGuardsForInstance}\n * owns that), since this union reads datasources outside the engine's trust\n * boundary.\n */\nexport async function guardsForInstance(args: GuardsForInstanceArgs): Promise<MutationGuardDoc[]> {\n const {client, clientForGdr, instance} = args\n\n const stateUris = [\n ...collectEntryDocUris(instance.state),\n ...instance.stages.flatMap((stage) => collectEntryDocUris(stage.state)),\n ]\n const clients = resourceClientMap(\n instance.workflowResource,\n client,\n clientForGdr,\n stateUris.map((uri) => tryParseGdr(uri)),\n )\n const {query, params} = instanceGuardQuery(instance._id)\n return queryGuardsAcross(clients.values(), query, params)\n}\n\nexport interface GuardsForDefinitionArgs {\n client: WorkflowClient\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient\n workflowResource: WorkflowResource\n definition: string\n /** Every deployed version of {@link GuardsForDefinitionArgs.definition}. */\n definitions: WorkflowDefinition[]\n}\n\n/**\n * All guards a workflow's definition deployed, unioned across the datasources\n * its guards statically name — no live instance required. Guard docs are\n * stamped with the version-less definition, so this spans the datasources\n * declared across ALL deployed versions\n * ({@link GuardsForDefinitionArgs.definitions}), not just the latest.\n *\n * A datasource is statically reachable when a guard idRef resolves to a\n * hardcoded GDR literal — directly, or via a `stateRead` of a state entry whose source\n * is a literal GDR — or to the workflow resource (`self`, or a `query`-sourced\n * state entry, which restamps into it). Guards whose resource is only known once an\n * instance exists — reading a `subject` / `init` / otherwise runtime-sourced\n * state entry — are NOT reachable here; that is the per-instance boundary, use\n * {@link guardsForInstance}. Dedups resources by key, results by `_id`.\n */\nexport async function guardsForDefinition(\n args: GuardsForDefinitionArgs,\n): Promise<MutationGuardDoc[]> {\n const {client, clientForGdr, workflowResource, definition, definitions} = args\n\n const gdrs = definitions.flatMap((def) =>\n guardIdRefs(def).map(({idRef, stage}) => staticIdRefGdr(idRef, stage, def)),\n )\n const clients = resourceClientMap(workflowResource, client, clientForGdr, gdrs)\n return queryGuardsAcross(clients.values(), `*[_type == $t && sourceDefinition == $definition]`, {\n t: GUARD_DOC_TYPE,\n definition,\n })\n}\n\n/** Every guard idRef in the definition, paired with the stage it belongs to. */\nfunction guardIdRefs(definition: WorkflowDefinition): Array<{idRef: string; stage: Stage}> {\n return definition.stages.flatMap((stage) =>\n (stage.guards ?? []).flatMap((guard) =>\n (guard.match.idRefs ?? []).map((idRef) => ({idRef, stage})),\n ),\n )\n}\n\n/**\n * The concrete external datasource a guard idRef resolves to using the\n * definition alone, or `undefined` when it targets the workflow resource\n * (already a candidate) or resolves only per-instance. An idRef is a\n * `$state` read string; the only static non-workflow case is an entry whose\n * declared source is a literal GDR. Everything else (`init`, `write`,\n * `query`) resolves at runtime — the documented per-instance boundary.\n */\nfunction staticIdRefGdr(\n idRef: string,\n stage: Stage,\n definition: WorkflowDefinition,\n): ParsedGdr | undefined {\n const read = /^\\$state\\.([\\w-]+)/.exec(idRef)\n if (read === null) return undefined\n const source = entriesInScope(stage, definition).find((e) => e.name === read[1])?.source\n return source?.type === 'literal' ? gdrFromValue(source.value) : undefined\n}\n\n/** The statically-declared entries reachable from a stage's guards. */\nfunction entriesInScope(stage: Stage, definition: WorkflowDefinition): readonly StateEntry[] {\n return [\n ...(definition.state ?? []),\n ...(stage.state ?? []),\n ...(stage.tasks ?? []).flatMap((task) => task.state ?? []),\n ]\n}\n\n/** Parse a GDR from a literal Source value — a bare URI string or a `{id}` ref. */\nfunction gdrFromValue(value: unknown): ParsedGdr | undefined {\n if (typeof value === 'string') return tryParseGdr(value)\n if (typeof value === 'object' && value !== null && 'id' in value) {\n const id = (value as {id: unknown}).id\n return typeof id === 'string' ? tryParseGdr(id) : undefined\n }\n return undefined\n}\n\nfunction tryParseGdr(uri: string): ParsedGdr | undefined {\n try {\n return parseGdr(uri)\n } catch {\n return undefined\n }\n}\n\n/**\n * Map every resource a query should span — the base resource plus each resolved\n * GDR — to the client that reads it, deduped by resource key. `undefined`\n * entries (unparseable / unresolvable refs) are skipped.\n */\nfunction resourceClientMap(\n base: WorkflowResource,\n baseClient: WorkflowClient,\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient,\n gdrs: Iterable<ParsedGdr | undefined>,\n): Map<string, WorkflowClient> {\n const map = new Map<string, WorkflowClient>([[resourceKey(base), baseClient]])\n for (const parsed of gdrs) {\n if (parsed === undefined) continue\n const key = resourceKey(resourceFromParsed(parsed))\n if (!map.has(key)) map.set(key, clientForGdr(parsed))\n }\n return map\n}\n\n/** Run one guard query against each resource client, then dedup by `_id`. */\nasync function queryGuardsAcross(\n clients: Iterable<WorkflowClient>,\n query: string,\n params: Record<string, unknown>,\n): Promise<MutationGuardDoc[]> {\n const perResource = await Promise.all(\n [...clients].map((c) => c.fetch<MutationGuardDoc[]>(query, params)),\n )\n return dedupById(perResource.flat())\n}\n\nfunction dedupById(guards: MutationGuardDoc[]): MutationGuardDoc[] {\n const byId = new Map(guards.map((g) => [g._id, g]))\n return [...byId.values()].sort((a, b) => a._id.localeCompare(b._id))\n}\n","/**\n * `workflow.evaluate` — the third concept.\n *\n * Reads an instance and projects \"what can this actor do right now,\n * and why not the rest?\" as a structured `WorkflowEvaluation`. Pure\n * read; never writes. Different actors see different evaluations of\n * the same instance.\n *\n * Gating is ONE mechanism: each action's `filter` condition over the\n * rendered scope (`$actor`, `$assigned`, `$can`, `$state`, …) — authoring\n * sugar like `roles` desugared into it at define time. Everything this\n * module evaluates is advisory UX; the hard gates are the lake ACL on the\n * documents and guards. `$can.*` is the honest spelling of that: an\n * advisory permission read computed from grants when the caller supplies\n * them, undefined otherwise (conditions referencing it fail closed).\n *\n * Used internally by `fireAction` to gate writes and externally by\n * UIs to render disabled-with-reason buttons.\n */\n\nimport {resolveAccess, type WorkflowAccessOverride} from './access.ts'\nimport {type Clocked, wallClock} from './clock.ts'\nimport {evaluateCondition, evaluatePredicates} from './core/eval.ts'\nimport {instanceWriteDenials} from './core/guards.ts'\nimport {assignedFor, buildParams, scopedStateOverlay} from './core/params.ts'\nimport type {ParsedGdr, WorkflowResource} from './core/refs.ts'\nimport type {HydratedSnapshot} from './core/snapshot.ts'\nimport type {Action, Task, WorkflowDefinition} from './define/schema.ts'\nimport {isTerminalStage} from './engine/stages.ts'\nimport {verdictGuardsForInstance} from './guards-query.ts'\nimport {grantsPermissionOn} from './permissions.ts'\nimport {hydrateSnapshot} from './snapshot.ts'\nimport {validateTags} from './tags.ts'\nimport type {Actor} from './types/actor.ts'\nimport type {Grant, MutationGuardDoc} from './types/authorization.ts'\nimport type {WorkflowClient} from './types/client.ts'\nimport {DOCUMENT_VALUE_PERMISSIONS, isTerminalTaskStatus, type TaskStatus} from './types/enums.ts'\nimport type {\n ActionEvaluation,\n DisabledReason,\n StageEvaluation,\n TaskEvaluation,\n TransitionEvaluation,\n WorkflowEvaluation,\n} from './types/evaluation.ts'\nimport {findOpenStageEntry, type TaskEntry} from './types/instance-state.ts'\nimport {parseDefinitionSnapshot, type WorkflowInstance} from './types/instance.ts'\n\nexport interface EvaluateArgs {\n client: WorkflowClient\n /** Engine-scope tags — required. */\n tags: string[]\n /** Engine workflow resource — required. */\n workflowResource: WorkflowResource\n instanceId: string\n /**\n * Optional access-state override. By default the engine resolves\n * `(actor, grants)` from the supplied client's token via\n * `/users/me` (+ `grantsFromPath`). The bench supplies its\n * `ALL_ACCESS` default here; admin tooling can use this for\n * \"view as another user\" or \"preview with restricted grants\" flows.\n */\n access?: WorkflowAccessOverride\n /**\n * URL path on the supplied client where the engine should fetch\n * grants when `access.grants` isn't supplied. Without grants the\n * rendered `$can` is undefined, so conditions referencing it fail\n * closed — and the real Sanity write boundary still enforces.\n *\n * Canvas resource example: `/canvases/<resourceId>/acl`.\n * Project/dataset example: `/projects/<id>/datasets/<dataset>/acl`.\n *\n * Result is cached per `(client, path)` for the lifetime of the\n * process — grants don't change often, and tearing them down per\n * call would mean a network round-trip on every fireAction.\n */\n grantsFromPath?: string\n /**\n * Optional resource-aware client routing — see\n * `StartInstanceArgs.resourceClients`. When the workflow's subject\n * (or any ancestor) lives in a different resource than the engine's\n * client, this resolver decides which client to read it through.\n * The evaluation hydrates a GDR-keyed snapshot from those reads and\n * runs `_id`-scoped conditions locally in groq-js — same model as the\n * cascade path.\n */\n resourceClients?: (parsed: ParsedGdr) => WorkflowClient | undefined\n}\n\nexport async function evaluateInstance(args: Clocked<EvaluateArgs>): Promise<WorkflowEvaluation> {\n const {client, tags, instanceId, resourceClients} = args\n // One clock reading for the whole projection so every condition's `$now`\n // agrees (and matches a frozen bench timeline). Pure read — never persisted.\n const now = (args.clock ?? wallClock)()\n validateTags(tags)\n // Resolve actor + grants together (one cached round-trip per client).\n // Caller can short-circuit by passing `access` (bench / impersonation\n // / preview). Caching lives in access.ts — same WeakMap pattern.\n const {actor, grants} = await resolveAccess(client, {\n ...(args.access !== undefined ? {override: args.access} : {}),\n ...(args.grantsFromPath !== undefined ? {grantsFromPath: args.grantsFromPath} : {}),\n })\n\n const instance = await client.getDocument<WorkflowInstance>(instanceId)\n if (!instance) {\n throw new Error(`Workflow instance \"${instanceId}\" not found`)\n }\n if (!tags.some((t) => instance.tags?.includes(t))) {\n throw new Error(`Workflow instance \"${instanceId}\" not visible to this engine (tag mismatch)`)\n }\n\n const definition = parseDefinitionSnapshot(instance)\n const clientForGdr =\n resourceClients !== undefined\n ? (parsed: ParsedGdr) => resourceClients(parsed) ?? client\n : () => client\n // Build the GDR-keyed snapshot ONCE; the pure evaluation threads it\n // through every condition check (groq-js, zero lake reads).\n const snapshot: HydratedSnapshot = await hydrateSnapshot({client, clientForGdr, instance})\n // Load the instance's guards so this fetch path agrees with a reactive\n // session fed by a guard stream — both produce `mutation-guard-denied`\n // for the same held state (and fireAction's soft-gate goes through here).\n // Engine-datasource only: a guard read from a foreign datasource must\n // never influence a verdict.\n const guards = await verdictGuardsForInstance(client, instance._id)\n\n return evaluateFromSnapshot({\n instance,\n definition,\n actor,\n snapshot,\n guards,\n now,\n ...(grants !== undefined ? {grants} : {}),\n })\n}\n\nexport interface EvaluateFromSnapshotArgs {\n instance: WorkflowInstance\n definition: WorkflowDefinition\n actor: Actor\n /**\n * Resolved grants for the actor. Omit to leave the rendered `$can`\n * undefined (conditions referencing it fail closed — the real lake\n * write boundary still enforces).\n */\n grants?: Grant[]\n /**\n * The in-memory snapshot to evaluate against. The caller assembles it\n * from whatever source — a fetch (see {@link evaluateInstance}) or a\n * live store. The `_id` of every doc must be in GDR-URI form, as\n * {@link buildSnapshot} produces.\n */\n snapshot: HydratedSnapshot\n /**\n * The `$now` reading every condition in this projection shares. Omit to\n * use {@link wallClock}; a reactive consumer (or the bench) passes its\n * own clock reading for a stable/deterministic timeline.\n */\n now?: string\n /**\n * Live lake mutation guards held for this instance (a reactive adapter's\n * guard stream). Every action commit is an `update` write to the instance\n * doc, so a guard that matches the instance and denies that write disables\n * every action with `mutation-guard-denied`. Omit to skip the gate — the\n * lake still enforces at commit time.\n */\n guards?: readonly MutationGuardDoc[]\n}\n\n/**\n * The pure projection at the heart of {@link evaluateInstance}: given an\n * instance, its definition, the resolved actor/grants, and a snapshot,\n * compute \"what can this actor do right now, and why not the rest.\" No\n * I/O — feed it a fresh snapshot (e.g. rebuilt from a live store on\n * change) for reactive re-evaluation. Best-effort by design: the lake's\n * mutation guards + ACL are the real enforcement.\n */\nexport async function evaluateFromSnapshot(\n args: EvaluateFromSnapshotArgs,\n): Promise<WorkflowEvaluation> {\n const {instance, definition, actor, grants, snapshot} = args\n const now = args.now ?? wallClock()\n const stage = definition.stages.find((s) => s.name === instance.currentStage)\n if (stage === undefined) {\n throw new Error(\n `Instance \"${instance._id}\" currentStage \"${instance.currentStage}\" not in definition`,\n )\n }\n\n const scope = await renderScope({instance, definition, actor, grants, snapshot, now})\n const currentTaskEntries = findOpenStageEntry(instance)?.tasks ?? []\n\n // One pre-flight for the whole projection: every action commit is the same\n // `update` write to the instance doc, so the guard verdict is shared.\n const guardDenial = await instanceGuardReason(instance, actor, args.guards)\n\n const taskEvaluations: TaskEvaluation[] = []\n for (const task of stage.tasks ?? []) {\n taskEvaluations.push(\n await evaluateTask({\n task,\n statusEntry: currentTaskEntries.find((t) => t.name === task.name),\n instance,\n actor,\n snapshot,\n scope,\n stageHasExits: !isTerminalStage(stage),\n guardDenial,\n }),\n )\n }\n\n const transitionEvaluations: TransitionEvaluation[] = []\n for (const transition of stage.transitions ?? []) {\n transitionEvaluations.push({\n transition,\n filterSatisfied: await evaluateCondition({\n condition: transition.filter,\n snapshot,\n params: scope,\n }),\n })\n }\n\n const currentStage: StageEvaluation = {\n stage,\n tasks: taskEvaluations,\n transitions: transitionEvaluations,\n }\n\n const pendingOnYou = taskEvaluations.filter((t) => t.pendingOnActor)\n const canInteract = taskEvaluations.some((t) => t.actions.some((a) => a.allowed))\n\n return {\n instance,\n definition,\n actor,\n currentStage,\n pendingOnYou,\n canInteract,\n }\n}\n\n/**\n * Assemble the projection's rendered scope once: instance built-ins,\n * `$actor`, the advisory `$can` (from grants when supplied), and the\n * author's nullary predicates pre-evaluated as boolean params. Per-task\n * vars (`$assigned`, the lexical `$state` overlay) layer on top.\n */\nasync function renderScope(args: {\n instance: WorkflowInstance\n definition: WorkflowDefinition\n actor: Actor\n grants: Grant[] | undefined\n snapshot: HydratedSnapshot\n now: string\n}): Promise<Record<string, unknown>> {\n const {instance, definition, actor, grants, snapshot, now} = args\n const base = buildParams({instance, now, snapshot})\n const params: Record<string, unknown> = {\n ...base,\n actor,\n assigned: false,\n can: await advisoryCan(instance, actor, grants),\n }\n const predicates = await evaluatePredicates({\n predicates: definition.predicates,\n snapshot,\n params,\n })\n return {...predicates, ...params}\n}\n\n/**\n * The advisory `$can` — per-permission booleans computed from the caller's\n * grants on the instance. Undefined without grants: never enforcement,\n * just the honest UX read.\n */\nexport async function advisoryCan(\n instance: WorkflowInstance,\n actor: Actor,\n grants: Grant[] | undefined,\n): Promise<Record<string, boolean> | undefined> {\n if (grants === undefined) return undefined\n const can: Record<string, boolean> = {}\n for (const permission of DOCUMENT_VALUE_PERMISSIONS) {\n can[permission] = await grantsPermissionOn({\n document: instance,\n grants,\n permission,\n userId: actor.id,\n })\n }\n return can\n}\n\ninterface EvaluateTaskArgs {\n task: Task\n statusEntry: TaskEntry | undefined\n instance: WorkflowInstance\n actor: Actor\n snapshot: HydratedSnapshot\n scope: Record<string, unknown>\n stageHasExits: boolean\n /** Shared instance-write guard verdict, precomputed once per evaluation. */\n guardDenial: DisabledReason | undefined\n}\n\nasync function evaluateTask(args: EvaluateTaskArgs): Promise<TaskEvaluation> {\n const {task, statusEntry, instance, actor, snapshot, scope, stageHasExits, guardDenial} = args\n const status: TaskStatus = statusEntry?.status ?? 'pending'\n const assigned = assignedFor(instance, task.name, actor)\n const taskScope = {\n ...scope,\n state: {\n ...(scope.state as Record<string, unknown>),\n ...scopedStateOverlay(instance, snapshot, task.name),\n },\n assigned,\n }\n\n const actions: ActionEvaluation[] = []\n for (const action of task.actions ?? []) {\n actions.push(\n await evaluateAction({\n action,\n status,\n instance,\n snapshot,\n taskScope,\n stageHasExits,\n guardDenial,\n }),\n )\n }\n\n return {\n task,\n status,\n // \"pending on actor\" treats both `pending` and `active` as waiting on\n // the assignee — pending tasks just haven't been activated yet, but\n // they're still inbox items. The inbox reads the assignees-kind state\n // entry BY KIND (who-data is state).\n pendingOnActor: (status === 'active' || status === 'pending') && assigned,\n actions,\n }\n}\n\n// Internal — per-action verdict\n\ninterface EvaluateActionArgs {\n action: Action\n status: TaskStatus\n instance: WorkflowInstance\n snapshot: HydratedSnapshot\n taskScope: Record<string, unknown>\n stageHasExits: boolean\n guardDenial: DisabledReason | undefined\n}\n\nasync function evaluateAction(args: EvaluateActionArgs): Promise<ActionEvaluation> {\n const {action, status, instance, snapshot, taskScope, stageHasExits, guardDenial} = args\n\n // Lifecycle gates first (most informative reason), then the guard\n // pre-flight (a denied instance write dooms every action), then the ONE\n // engine-side condition gate with the caller bound.\n const lifecycle = lifecycleReason(instance, status, stageHasExits)\n if (lifecycle !== undefined) return disabled(action, lifecycle)\n\n if (guardDenial !== undefined) return disabled(action, guardDenial)\n\n if (action.filter !== undefined) {\n const truthy = await evaluateCondition({\n condition: action.filter,\n snapshot,\n params: taskScope,\n })\n if (!truthy) {\n return disabled(action, {kind: 'filter-failed', filter: action.filter})\n }\n }\n\n return {action, allowed: true}\n}\n\n/**\n * Pre-flight the write every action commit performs — an `update` of the\n * instance doc — against the held live guards, via\n * {@link instanceWriteDenials} (which also drops foreign-datasource guards:\n * only guards in the instance's own datasource can enforce on this write).\n * An unconditional freeze (empty predicate) or a metadata/identity-driven\n * denial surfaces; a lifted guard (predicate `\"true\"`) allows; fail-closed.\n */\nasync function instanceGuardReason(\n instance: WorkflowInstance,\n actor: Actor,\n guards: readonly MutationGuardDoc[] | undefined,\n): Promise<DisabledReason | undefined> {\n if (guards === undefined || guards.length === 0) return undefined\n const denied = await instanceWriteDenials({instance, guards, identity: actor.id})\n if (denied.length === 0) return undefined\n return {\n kind: 'mutation-guard-denied',\n guardIds: denied.map((g) => g._id),\n detail: denied.map((g) => g.name ?? g._id).join(', '),\n }\n}\n\nfunction lifecycleReason(\n instance: WorkflowInstance,\n status: TaskStatus,\n stageHasExits: boolean,\n): DisabledReason | undefined {\n if (instance.completedAt !== undefined) {\n return {kind: 'instance-completed', completedAt: instance.completedAt}\n }\n // A stage with no transitions IS terminal — structural, not declared.\n if (!stageHasExits) {\n return {kind: 'stage-terminal', stage: instance.currentStage}\n }\n if (isTerminalTaskStatus(status)) {\n return {kind: 'task-not-active', status}\n }\n return undefined\n}\n\nfunction disabled(action: Action, reason: DisabledReason): ActionEvaluation {\n return {action, allowed: false, disabledReason: reason}\n}\n","import type {SanityDocument} from '@sanity/types'\n\nimport type {WorkflowResource} from '../core/refs.ts'\nimport {WORKFLOW_DEFINITION_TYPE, type WorkflowDefinition} from '../define/schema.ts'\nimport {definitionLookupGroq} from '../definition-query.ts'\nimport {canonicalTag} from '../tags.ts'\nimport type {WorkflowClient} from '../types/client.ts'\n\n/**\n * Mint the Sanity document `_id` for a workflow.definition. Bare form\n * — no GDR scheme prefix — because Sanity rejects `:` in document\n * IDs. Cross-resource references can construct the full GDR URI from\n * `(workflowResource, _id)` on demand.\n */\nexport function definitionDocId(\n _workflowResource: WorkflowResource,\n prefix: string,\n definition: string,\n version: number,\n): string {\n return `${prefix}.${definition}.v${version}`\n}\n\n/**\n * Topologically sort definitions so spawn-children land before their\n * parents. Refs pointing outside the batch are validated against the\n * lake — if a ref points neither to a doc in the batch nor to an\n * already-deployed definition, throw before any write.\n *\n * Cycles error.\n */\nexport async function sortByDependencies(\n client: WorkflowClient,\n definitions: WorkflowDefinition[],\n tags: string[],\n workflowResource: WorkflowResource,\n): Promise<WorkflowDefinition[]> {\n const prefix = canonicalTag(tags)\n // Track every definition name in this batch + the versions per name.\n // Logical refs match on name alone (or name + version when explicit).\n const byName = new Map<string, WorkflowDefinition[]>()\n for (const def of definitions) {\n const list = byName.get(def.name) ?? []\n list.push(def)\n byName.set(def.name, list)\n }\n const findInBatch = (ref: LogicalRef) => findRefInBatch(byName, ref)\n\n await assertCrossBatchRefsDeployed(client, definitions, {\n tags,\n workflowResource,\n prefix,\n findInBatch,\n })\n\n return topoSortDefinitions(definitions, {workflowResource, prefix, findInBatch})\n}\n\ninterface LogicalRef {\n name: string\n version?: number | 'latest'\n}\n\n/** Find the definition in the batch satisfying a logical ref: an exact\n * version match, or the highest version when the ref omits one. */\nfunction findRefInBatch(\n byName: Map<string, WorkflowDefinition[]>,\n ref: LogicalRef,\n): WorkflowDefinition | undefined {\n const candidates = byName.get(ref.name)\n if (candidates === undefined || candidates.length === 0) return undefined\n if (typeof ref.version === 'number') return candidates.find((c) => c.version === ref.version)\n return candidates.reduce<WorkflowDefinition | undefined>(\n (best, c) => (best === undefined || c.version > best.version ? c : best),\n undefined,\n )\n}\n\n/**\n * For every spawn ref not satisfied within the batch, confirm a matching\n * definition is already deployed and visible to this engine's\n * tags. Throws listing every unresolved ref. No-op when all resolve.\n */\nasync function assertCrossBatchRefsDeployed(\n client: WorkflowClient,\n definitions: WorkflowDefinition[],\n ctx: {\n tags: string[]\n workflowResource: WorkflowResource\n prefix: string\n findInBatch: (ref: LogicalRef) => WorkflowDefinition | undefined\n },\n): Promise<void> {\n const missing: {from: string; ref: string}[] = []\n for (const def of definitions) {\n const fromId = definitionDocId(ctx.workflowResource, ctx.prefix, def.name, def.version)\n for (const ref of refsOf(def)) {\n if (ctx.findInBatch(ref) !== undefined) continue // satisfied within batch\n const label = await resolveDeployedRefLabel(client, ref, ctx.tags)\n if (label !== undefined) missing.push({from: fromId, ref: label})\n }\n }\n if (missing.length === 0) return\n const lines = missing.map((m) => ` - ${m.from} → ${m.ref} (neither in batch nor deployed)`)\n throw new Error(\n `workflow.deployDefinitions: ${missing.length} unresolved reference${missing.length === 1 ? '' : 's'}:\\n` +\n lines.join('\\n'),\n )\n}\n\n/** Look up a logical ref in the lake. Returns undefined when a matching\n * deployed definition is visible to `tags`, or a human-readable label\n * for the unresolved ref otherwise. */\nasync function resolveDeployedRefLabel(\n client: WorkflowClient,\n ref: LogicalRef,\n tags: string[],\n): Promise<string | undefined> {\n const wantsExplicit = typeof ref.version === 'number'\n const params: Record<string, unknown> = {definition: ref.name, engineTags: tags}\n if (wantsExplicit) params.version = ref.version\n const doc = await client.fetch<(SanityDocument & {tags?: string[]}) | null>(\n definitionLookupGroq(wantsExplicit),\n params,\n )\n if (doc) return undefined\n return wantsExplicit ? `${ref.name} v${ref.version}` : ref.name\n}\n\n/** Children-before-parents topological sort over in-batch spawn refs.\n * Throws on a dependency cycle. */\nfunction topoSortDefinitions(\n definitions: WorkflowDefinition[],\n ctx: {\n workflowResource: WorkflowResource\n prefix: string\n findInBatch: (ref: LogicalRef) => WorkflowDefinition | undefined\n },\n): WorkflowDefinition[] {\n const visited = new Set<string>()\n const visiting = new Set<string>()\n const ordered: WorkflowDefinition[] = []\n\n const visit = (def: WorkflowDefinition): void => {\n const id = definitionDocId(ctx.workflowResource, ctx.prefix, def.name, def.version)\n if (visited.has(id)) return\n if (visiting.has(id)) {\n throw new Error(`workflow.deployDefinitions: dependency cycle involving \"${id}\"`)\n }\n visiting.add(id)\n for (const ref of refsOf(def)) {\n const child = ctx.findInBatch(ref)\n if (child !== undefined) visit(child)\n }\n visiting.delete(id)\n visited.add(id)\n ordered.push(def)\n }\n\n for (const def of definitions) visit(def)\n return ordered\n}\n\n// Collect every subworkflow ref a definition depends on as a logical\n// `{ name, version? }` reference. Hoisted out of\n// sortByDependencies so it doesn't re-capture closure on each call.\nfunction refsOf(def: WorkflowDefinition): LogicalRef[] {\n const out: LogicalRef[] = []\n for (const stage of def.stages) {\n for (const task of stage.tasks ?? []) {\n const ref = task.subworkflows?.definition\n if (ref !== undefined) {\n out.push({\n name: ref.name,\n ...(ref.version !== undefined ? {version: ref.version} : {}),\n })\n }\n }\n }\n return out\n}\n\n/**\n * Compare a deployed definition document to what we'd write next. Skip\n * Sanity-managed system fields (`_rev`, `_createdAt`, `_updatedAt`) —\n * those always differ. Everything else must match exactly for the\n * deploy to be a no-op.\n */\nexport function isDefinitionUnchanged(\n existing: Record<string, unknown>,\n expected: Record<string, unknown>,\n): boolean {\n return (\n stableStringify(stripSystemFields(existing)) === stableStringify(stripSystemFields(expected))\n )\n}\n\nexport function stripSystemFields(doc: Record<string, unknown>): Record<string, unknown> {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(doc)) {\n if (k === '_rev' || k === '_createdAt' || k === '_updatedAt') continue\n out[k] = v\n }\n return out\n}\n\n/**\n * Stable JSON.stringify with sorted keys so object key order can't\n * cause a false \"changed\" diff.\n */\nfunction stableStringify(value: unknown): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value)\n if (Array.isArray(value)) return `[${value.map(stableStringify).join(',')}]`\n const entries = Object.entries(value as Record<string, unknown>).toSorted(([a], [b]) =>\n a.localeCompare(b),\n )\n return `{${entries.map(([k, v]) => `${JSON.stringify(k)}:${stableStringify(v)}`).join(',')}}`\n}\n\nexport async function loadDefinition(\n client: WorkflowClient,\n definition: string,\n version: number | undefined,\n tags: string[],\n): Promise<WorkflowDefinition> {\n if (version !== undefined) {\n const doc = await client.fetch<(WorkflowDefinition & {tags?: string[]}) | null>(\n definitionLookupGroq(true),\n {definition, version, engineTags: tags},\n )\n if (!doc) {\n throw new Error(`Workflow definition ${definition} v${version} not deployed`)\n }\n return doc\n }\n const latest = await client.fetch<WorkflowDefinition | null>(definitionLookupGroq(false), {\n definition,\n engineTags: tags,\n })\n if (!latest) {\n throw new Error(`No deployed definition for workflow ${definition}`)\n }\n return latest\n}\n\n/**\n * Every deployed version of a workflow, newest first. Guard docs are stamped\n * with the version-less `definition`, so definition-level guard housekeeping\n * must union the datasources declared across all versions, not just the latest.\n */\nexport async function loadDefinitionVersions(\n client: WorkflowClient,\n definition: string,\n tags: string[],\n): Promise<WorkflowDefinition[]> {\n return client.fetch<WorkflowDefinition[]>(\n `*[_type == \"${WORKFLOW_DEFINITION_TYPE}\" && name == $definition && count(tags[@ in $engineTags]) > 0] | order(version desc)`,\n {definition, engineTags: tags},\n )\n}\n","import {selfGdr} from '../core/refs.ts'\nimport type {Action, Stage, Task} from '../define/schema.ts'\nimport {advisoryCan} from '../evaluate.ts'\nimport {randomKey} from '../keys.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {TaskName} from '../types/ids.ts'\nimport {ctxEvaluateCondition, type EngineContext, loadContext} from './context.ts'\nimport {queueEffects} from './effects.ts'\nimport {\n findCurrentTasks,\n findTaskInCurrentStage,\n requireMutationTaskEntry,\n startMutation,\n} from './mutation.ts'\nimport {isStateOp, runOps, validateActionParams} from './ops.ts'\nimport {\n type ActionResult,\n CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS,\n ConcurrentFireActionError,\n type EngineCallOptions,\n isRevisionConflict,\n} from './results.ts'\nimport {persistThenDeploy, refreshStageGuards} from './stages.ts'\n\n/**\n * Fire an action against an active task. The action's whole behaviour is\n * its ops + effects — task resolution included, via the `status.set` op the\n * authored `status:` field desugared to.\n *\n * Gating is ONE mechanism: the action's `filter` condition over the rendered\n * scope (`$actor`, `$assigned`, `$state`, …). Hard enforcement lives outside\n * the engine — the lake ACL on the documents, and guards; everything checked\n * here is authoring/UX.\n *\n * Each attempt reloads the instance (fresh `_rev`) and commits through\n * `persist`'s `ifRevisionId` guard, so two clients firing the same task\n * can't silently clobber each other. A commit that loses the race\n * reloads and retries across {@link CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS} attempts,\n * then throws {@link ConcurrentFireActionError}. Reloading also re-gates\n * the action, so a retry whose task the winning writer already completed\n * fails with the normal \"task must be active\" error rather than retrying.\n */\nexport async function fireAction(args: {\n client: WorkflowClient\n instanceId: string\n task: TaskName\n action: string\n /** Caller-supplied action params (validated against `Action.params[]`). */\n params?: Record<string, unknown>\n options?: EngineCallOptions\n}): Promise<ActionResult> {\n const {client, instanceId, task, action, params, options} = args\n for (let attempt = 1; attempt <= CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS; attempt++) {\n const ctx = await loadContext(client, instanceId, {\n ...(options?.clock ? {clock: options.clock} : {}),\n })\n try {\n return await commitAction(ctx, task, action, params, options)\n } catch (error) {\n if (!isRevisionConflict(error)) throw error\n // Lost the optimistic-locking race — reload and retry.\n }\n }\n throw new ConcurrentFireActionError({\n instanceId,\n task,\n action,\n attempts: CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS,\n })\n}\n\n/**\n * Resolve and gate an action fire: locate the task + action in the\n * current stage, evaluate the action's condition with the caller bound\n * (`$actor` / `$assigned`), require the live task entry to be `active`,\n * and validate caller params. Throws on any failure so no mutation begins.\n */\nasync function resolveActionCommit(\n ctx: EngineContext,\n taskName: TaskName,\n actionName: string,\n callerParams: Record<string, unknown> | undefined,\n options: EngineCallOptions | undefined,\n): Promise<{stage: Stage; task: Task; action: Action; params: Record<string, unknown>}> {\n const actor = options?.actor\n const {stage, task} = findTaskInCurrentStage(ctx, taskName)\n const action = (task.actions ?? []).find((a) => a.name === actionName)\n if (action === undefined) {\n throw new Error(`Action \"${actionName}\" not declared on task \"${taskName}\"`)\n }\n\n // Mirror the soft-gate's scope: when the caller's grants are supplied,\n // the advisory $can binds here too — otherwise a $can-gated action would\n // pass evaluate yet always fail the commit re-check.\n const can =\n options?.grants !== undefined && actor !== undefined\n ? await advisoryCan(ctx.instance, actor, options.grants)\n : undefined\n const filterOk = await ctxEvaluateCondition(ctx, action.filter, {\n taskName,\n ...(actor !== undefined ? {actor} : {}),\n ...(can !== undefined ? {vars: {can}} : {}),\n })\n if (!filterOk) {\n throw new Error(`Action \"${actionName}\" filter rejected on task \"${taskName}\"`)\n }\n\n const entry = findCurrentTasks(ctx.instance).find((t) => t.name === taskName)\n if (entry === undefined || entry.status !== 'active') {\n throw new Error(\n `Task \"${taskName}\" must be active to fire action \"${actionName}\"; status is ${entry?.status ?? 'missing'}`,\n )\n }\n\n // Validate caller params against `action.params[]` before any\n // mutation. The action does not commit if validation fails.\n const params = validateActionParams(action, taskName, callerParams)\n return {stage, task, action, params}\n}\n\nasync function commitAction(\n ctx: EngineContext,\n taskName: TaskName,\n actionName: string,\n callerParams: Record<string, unknown> | undefined,\n options: EngineCallOptions | undefined,\n): Promise<ActionResult> {\n const actor = options?.actor\n const {stage, action, params} = await resolveActionCommit(\n ctx,\n taskName,\n actionName,\n callerParams,\n options,\n )\n\n const mutation = startMutation(ctx.instance)\n const mutEntry = requireMutationTaskEntry(mutation, taskName)\n // One clock reading for the whole commit so the actionFired entry, ops,\n // any status flip, and queued effects all agree on the time.\n const now = ctx.now\n\n mutation.history.push({\n _key: randomKey(),\n _type: 'actionFired',\n at: now,\n stage: stage.name,\n task: taskName,\n action: actionName,\n ...(actor !== undefined ? {actor} : {}),\n })\n\n // Run ops inline. Sources resolve against the in-progress mutation so a\n // later op can read a value an earlier op wrote. Task resolution is just\n // another op: the authored `status:` desugared to a trailing `status.set`,\n // which stamps completion and its own audit row.\n const statusBefore = mutEntry.status\n const ranOps = await runOps({\n ops: action.ops,\n mutation,\n stage: stage.name,\n origin: {task: taskName, action: actionName},\n params,\n actor,\n self: selfGdr(ctx.instance),\n now,\n })\n const newStatus = mutEntry.status !== statusBefore ? mutEntry.status : undefined\n\n // Queue external effects — bindings evaluate over the rendered scope with\n // caller params and actor pinned for this commit.\n await queueEffects(ctx, mutation, action.effects, {kind: 'action', name: actionName}, actor, {\n callerParams: params,\n taskName,\n })\n\n // Ops may have changed state a guard reads; refresh this stage's guards so\n // they stay coherent without a transition (skipped when no state op ran). A\n // failed refresh rolls the commit back rather than leaving guards stale.\n await persistThenDeploy(ctx, mutation, () =>\n ranOps.some(isStateOp) ? refreshStageGuards(ctx, mutation, stage.name) : Promise.resolve(),\n )\n\n return {\n fired: true,\n task: taskName,\n action: actionName,\n ...(newStatus !== undefined ? {newStatus} : {}),\n ...(ranOps.length > 0 ? {ranOps} : {}),\n }\n}\n","// Workflow evaluation — the third concept. Derived projection of\n// (instance + definition + actor + grants + lake state) answering\n// \"what can this actor do right now, and why not the rest?\".\n//\n// Not stored. Computed by `workflow.evaluate`. Different actors see\n// different evaluations of the same instance.\n\nimport type {Action, Stage, Task, Transition, WorkflowDefinition} from '../define/schema.ts'\nimport type {Actor} from './actor.ts'\nimport type {TaskStatus, TerminalTaskStatus} from './enums.ts'\nimport type {ActionName, StageName, TaskName} from './ids.ts'\nimport type {WorkflowInstance} from './instance.ts'\n\nexport type DisabledReason =\n | {\n /**\n * The action's condition evaluated falsy for this actor — the ONE\n * engine-side gate (advisory: hard enforcement is the lake ACL +\n * guards). Sugar like `roles` desugared into this condition, so a\n * role miss surfaces here too.\n */\n kind: 'filter-failed'\n filter: string\n detail?: string\n }\n | {\n kind: 'task-not-active'\n status: TerminalTaskStatus\n }\n | {kind: 'stage-terminal'; stage: StageName}\n | {\n /**\n * A live lake mutation guard denies the instance write every action\n * commit performs. Advisory pre-flight of the lake's own enforcement;\n * carries the denying guard ids.\n */\n kind: 'mutation-guard-denied'\n guardIds: string[]\n detail?: string\n }\n | {kind: 'instance-completed'; completedAt: string}\n\nexport interface ActionEvaluation {\n action: Action\n allowed: boolean\n /** Present iff `allowed === false`. The first failing gate wins. */\n disabledReason?: DisabledReason\n}\n\nexport interface TaskEvaluation {\n task: Task\n status: TaskStatus\n /** Whether this task is the current actor's responsibility right now. */\n pendingOnActor: boolean\n actions: ActionEvaluation[]\n}\n\nexport interface TransitionEvaluation {\n transition: Transition\n /** Result of evaluating the transition's filter at read time. */\n filterSatisfied: boolean\n}\n\nexport interface StageEvaluation {\n stage: Stage\n tasks: TaskEvaluation[]\n transitions: TransitionEvaluation[]\n}\n\nexport interface WorkflowEvaluation {\n instance: WorkflowInstance\n definition: WorkflowDefinition\n actor: Actor\n currentStage: StageEvaluation\n /** Active tasks whose assignees-kind state entry matches the actor. */\n pendingOnYou: TaskEvaluation[]\n /** True if at least one action on any active task is allowed. */\n canInteract: boolean\n}\n\n// Typed error thrown by fireAction when the requested action's verdict\n// is `allowed: false`. Carries the structured reason so UIs can render\n// a precise message instead of parsing a string.\n\nexport class ActionDisabledError extends Error {\n readonly reason: DisabledReason\n readonly task: TaskName\n readonly action: ActionName\n\n constructor(args: {task: TaskName; action: ActionName; reason: DisabledReason}) {\n super(formatDisabledReason(args.task, args.action, args.reason))\n this.name = 'ActionDisabledError'\n this.reason = args.reason\n this.task = args.task\n this.action = args.action\n }\n}\n\ntype DisabledReasonDetail = {\n [K in DisabledReason['kind']]: (reason: Extract<DisabledReason, {kind: K}>) => string\n}\n\nconst disabledReasonDetail: DisabledReasonDetail = {\n 'filter-failed': (r) => `action filter returned false${r.detail ? ` (${r.detail})` : ''}`,\n 'task-not-active': (r) => `task status is \"${r.status}\"`,\n 'stage-terminal': (r) => `stage \"${r.stage}\" is terminal`,\n 'instance-completed': (r) => `instance completed at ${r.completedAt}`,\n 'mutation-guard-denied': (r) =>\n `blocked by mutation guard(s) [${r.guardIds.join(', ')}]${r.detail ? ` (${r.detail})` : ''}`,\n}\n\nfunction formatDisabledReason(task: TaskName, action: ActionName, reason: DisabledReason): string {\n const detail = (disabledReasonDetail[reason.kind] as (r: DisabledReason) => string)(reason)\n return `Action \"${task}:${action}\" is not allowed: ${detail}`\n}\n","import {resolveAccess, type WorkflowAccessOverride} from '../access.ts'\nimport type {Clock} from '../clock.ts'\nimport {extractDocumentId, type GlobalDocumentReference, type ParsedGdr} from '../core/refs.ts'\nimport type {LoadedDoc} from '../core/snapshot.ts'\nimport {fireAction as engineFireAction} from '../engine/actions.ts'\nimport {cascadeAutoTransitions, propagateToAncestors} from '../engine/cascade.ts'\nimport {invokeTask as engineInvokeTask} from '../engine/tasks.ts'\nimport {effectsContextEntry} from '../instance.ts'\nimport {validateTags} from '../tags.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {Grant} from '../types/authorization.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {EffectsContextEntry} from '../types/effects.ts'\nimport {ActionDisabledError, type WorkflowEvaluation} from '../types/evaluation.ts'\nimport {findOpenStageEntry} from '../types/instance-state.ts'\nimport type {WorkflowInstance} from '../types/instance.ts'\nimport type {ResourceClientResolver} from './types.ts'\n\n// Internal helpers\n\n/**\n * Resolve a spawn `instanceRef.id` to the bare doc `_id` used by GROQ.\n * A misconfigured caller could write a malformed GDR URI into history;\n * {@link extractDocumentId} throws on those, so skip them (return no id)\n * instead of crashing the whole {@link workflow.children} call.\n */\nexport function bareIdFromSpawnRef(uri: string): string[] {\n if (!uri.includes(':')) return [uri]\n try {\n return [extractDocumentId(uri)]\n } catch {\n return []\n }\n}\n\n/**\n * Shared verb preamble: validate tags, resolve the calling actor from\n * the access override (or the client's token), and build the\n * cross-resource routing function. Every `workflow.*` verb opens this\n * way.\n */\nexport async function resolveOperationContext(args: {\n client: WorkflowClient\n tags: string[]\n resourceClients?: ResourceClientResolver\n access?: WorkflowAccessOverride\n grantsFromPath?: string\n}): Promise<{\n access: Awaited<ReturnType<typeof resolveAccess>>\n actor: Awaited<ReturnType<typeof resolveAccess>>['actor']\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient\n}> {\n validateTags(args.tags)\n const access = await resolveAccess(args.client, {\n ...(args.access !== undefined ? {override: args.access} : {}),\n ...(args.grantsFromPath !== undefined ? {grantsFromPath: args.grantsFromPath} : {}),\n })\n return {\n access,\n actor: access.actor,\n clientForGdr: buildClientForGdr(args.client, args.resourceClients),\n }\n}\n\nexport async function cascade(\n client: WorkflowClient,\n instanceId: string,\n actor: Actor | undefined,\n clientForGdr?: (parsed: ParsedGdr) => WorkflowClient,\n clock?: Clock,\n overlay?: ReadonlyMap<string, LoadedDoc>,\n): Promise<number> {\n // The overlay is this instance's held content — pass it only to the\n // instance's own cascade. Ancestor propagation operates on other\n // instances with their own content, so it must refetch (no overlay).\n const count = await cascadeAutoTransitions(\n client,\n instanceId,\n actor,\n clientForGdr,\n clock,\n overlay,\n )\n await propagateToAncestors(client, instanceId, actor, clientForGdr, clock)\n return count\n}\n\n/**\n * Build the routing function from a resolver. Falls back to using the\n * default client when the resolver is absent or returns undefined.\n */\nexport function buildClientForGdr(\n defaultClient: WorkflowClient,\n resolver: ResourceClientResolver | undefined,\n): (parsed: ParsedGdr) => WorkflowClient {\n if (resolver === undefined) return () => defaultClient\n return (parsed) => resolver(parsed) ?? defaultClient\n}\n\nexport async function reload(\n client: WorkflowClient,\n instanceId: string,\n tags: string[],\n): Promise<WorkflowInstance> {\n const doc = await client.getDocument<WorkflowInstance>(instanceId)\n if (!doc) throw new Error(`Workflow instance ${instanceId} not found`)\n if (!intersectsTags(doc.tags, tags)) {\n throw new Error(`Workflow instance ${instanceId} not visible to this engine (tag mismatch)`)\n }\n return doc\n}\n\nexport function intersectsTags(\n docTags: string[] | undefined | null,\n engineTags: string[],\n): boolean {\n if (!docTags || docTags.length === 0) return false\n return engineTags.some((t) => docTags.includes(t))\n}\n\nexport function toEffectsContextEntries(\n ctx: Record<string, string | number | boolean | GlobalDocumentReference>,\n): EffectsContextEntry[] {\n return Object.entries(ctx).map(([id, value]) => effectsContextEntry(id, value))\n}\n\n/**\n * Soft-gate before any action write: throw {@link ActionDisabledError} if the\n * evaluation says the action is disabled. The lake mutation boundary is the\n * real enforcement; this surfaces a structured `reason` to the caller first.\n */\nexport function assertActionAllowed(\n evaluation: WorkflowEvaluation,\n task: string,\n action: string,\n): void {\n const actionEval = evaluation.currentStage.tasks\n .find((t) => t.task.name === task)\n ?.actions.find((a) => a.action.name === action)\n if (actionEval?.allowed === false && actionEval.disabledReason) {\n throw new ActionDisabledError({task, action, reason: actionEval.disabledReason})\n }\n}\n\n/**\n * Auto-invoke the task if it's still pending, then fire the action. Both the\n * `pending` check ({@link findOpenStageEntry}) and the fire operate on the\n * supplied instance; returns the action's `ranOps` (if any).\n */\nexport async function applyAction(args: {\n client: WorkflowClient\n instance: WorkflowInstance\n task: string\n action: string\n params?: Record<string, unknown>\n actor: Actor\n grants?: Grant[]\n clock?: Clock\n}): Promise<Awaited<ReturnType<typeof engineFireAction>>['ranOps']> {\n const {client, instance, task, action, params, actor, grants, clock} = args\n const options = {\n actor,\n ...(grants !== undefined ? {grants} : {}),\n ...(clock !== undefined ? {clock} : {}),\n }\n const pending =\n findOpenStageEntry(instance)?.tasks.find((t) => t.name === task)?.status === 'pending'\n if (pending) {\n await engineInvokeTask({client, instanceId: instance._id, task, options})\n }\n const result = await engineFireAction({\n client,\n instanceId: instance._id,\n task,\n action,\n ...(params !== undefined ? {params} : {}),\n options,\n })\n return result.ranOps\n}\n","/**\n * The workflow API — a single coherent SDK surface, five methods.\n *\n * The model:\n *\n * - **`deployDefinition`** — once at deploy time. Persists the definition.\n * - **`startInstance`** — once per workflow run. Pins a snapshot, seeds\n * `effectsContext` (stable params for effect handlers), enters the\n * initial stage. Cascades.\n * - **`fireAction`** — the universal \"something happened\" call. Editors\n * fire actions on tasks. Runtimes fire actions on tasks in response\n * to webhooks, timer firings, etc. External signals funnel through\n * this; nothing else.\n * - **`completeEffect`** — the runtime reports a queued effect's\n * outcome. Optionally carries `outputs` that get merged into\n * `effectsContext` so a downstream effect's bindings can reference\n * them (effect chains). The only path that mutates `effectsContext`\n * after start.\n * - **`tick`** — re-evaluate auto-transitions and resolve due waits.\n * Used after any change that might unblock a filter: a content\n * mutation in the lake, a timer crossing a `completeWhen` deadline,\n * a sibling workflow completing, etc. The runtime decides which\n * instances might need a tick; the engine just re-evaluates.\n *\n * What's NOT in the API:\n *\n * - No `requestTransition`. Workflow authors should not have a way to\n * \"force\" a stage transition outside of filters firing. If you want\n * \"cancel from anywhere,\" model cancellation as a task with an action\n * that flips it to `failed`, plus an auto-transition filtered on\n * `anyTaskFailed`. Same audit trail as everything else; same\n * mechanism.\n * - No `setContext`. `effectsContext` is set at start, then mutated\n * only by completed effects' `outputs`. External signals belong on\n * tasks (via `fireAction`) or in the lake (as document mutations\n * that filters can read).\n * - No `invokeTask`. Tasks auto-activate on stage entry. Editor's first\n * `fireAction` against a pending task auto-invokes it before\n * applying the action.\n *\n * What filters can read:\n *\n * - Task state on the instance (`*[_id == $self][0].stages[id == $stage && !defined(exitedAt)][0].tasks[...]`)\n * - Document content in the lake (`*[_type == \"...\" && ...]`)\n * - Reserved params: `$self`, `$state`, `$parent`, `$ancestors`, `$stage`,\n * `$now`, `$tasks`, `$allTasksDone`, `$anyTaskFailed`\n *\n * What filters must NOT read:\n *\n * - `effectsContext`. That field is for effect handler params only.\n *\n * The boundary keeps each thing doing one job: tasks are workflow state,\n * the lake is content state, effectsContext is handler fuel.\n */\n\nimport type {SanityDocument} from '@sanity/types'\nimport {evaluate as evaluateGroq, parse as parseGroq} from 'groq-js'\n\nimport {type Clocked, wallClock} from '../clock.ts'\nimport {assertInstanceWriteAllowed} from '../core/guards.ts'\nimport {buildParams} from '../core/params.ts'\nimport type {WorkflowResource} from '../core/refs.ts'\nimport {WORKFLOW_DEFINITION_TYPE} from '../define/schema.ts'\nimport {abortInstance as engineAbortInstance} from '../engine/abort.ts'\nimport {primeInitialStage, propagateToAncestors} from '../engine/cascade.ts'\nimport {completeEffect as engineCompleteEffect} from '../engine/effects.ts'\nimport {setStage as engineSetStage} from '../engine/stages.ts'\nimport {type EvaluateArgs, evaluateInstance} from '../evaluate.ts'\nimport {\n guardsForDefinition as queryGuardsForDefinition,\n guardsForInstance as queryGuardsForInstance,\n verdictGuardsForInstance,\n} from '../guards-query.ts'\nimport {buildInstanceBase} from '../instance.ts'\nimport {randomKey} from '../keys.ts'\nimport {\n fetchGrants as permFetchGrants,\n grantsPermissionOn as permGrantsPermissionOn,\n matchesFilter as permMatchesFilter,\n} from '../permissions.ts'\nimport {hydrateSnapshot} from '../snapshot.ts'\nimport {derivePerspectiveFromState, resolveDeclaredState} from '../state-resolution.ts'\nimport {canonicalTag, tagScopeFilter, validateTags} from '../tags.ts'\nimport type {MutationGuardDoc} from '../types/authorization.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {PendingEffect} from '../types/effects.ts'\nimport type {WorkflowEvaluation} from '../types/evaluation.ts'\nimport type {HistoryEntry} from '../types/history.ts'\nimport {findOpenStageEntry} from '../types/instance-state.ts'\nimport type {WorkflowInstance} from '../types/instance.ts'\nimport {\n definitionDocId,\n isDefinitionUnchanged,\n loadDefinition,\n loadDefinitionVersions,\n sortByDependencies,\n} from './deploy.ts'\nimport {\n applyAction,\n assertActionAllowed,\n bareIdFromSpawnRef,\n buildClientForGdr,\n cascade,\n intersectsTags,\n reload,\n resolveOperationContext,\n toEffectsContextEntries,\n} from './operations.ts'\nimport type {\n AbortInstanceArgs,\n CompleteEffectArgs,\n DeployDefinitionResult,\n DeployDefinitionsArgs,\n DeployDefinitionsResult,\n DispatchResult,\n FireActionArgs,\n OperationArgs,\n ResourceClientResolver,\n SetStageArgs,\n StartInstanceArgs,\n} from './types.ts'\nimport {validateDefinition} from './validate.ts'\n\n/**\n * The four-method workflow API.\n */\nexport const workflow = {\n /**\n * Deploy a set of workflow definitions as one call. Each lands as a\n * {@link WORKFLOW_DEFINITION_TYPE} document; subsequent versions are\n * stored alongside earlier ones — `startInstance` picks the highest\n * version by default. The SDK figures out the dependency order itself\n * (children before parents that spawn them via\n * `subworkflows.definition`), idempotently writes any definition\n * whose content has changed, and reports a per-definition outcome\n * (`created` / `updated` / `unchanged`).\n *\n * Refs may point inside the batch OR at already-deployed definitions\n * in the lake — both are valid. A ref pointing at neither errors with\n * a clear message naming the missing target.\n *\n * Cycles in the dependency graph error before any write happens.\n */\n deployDefinitions: async (args: DeployDefinitionsArgs): Promise<DeployDefinitionsResult> => {\n const {client, tags, workflowResource, definitions} = args\n validateTags(tags)\n\n // 1. Validate each definition's GROQ + structural invariants\n // individually. Fail fast before we touch the lake.\n for (const def of definitions) {\n validateDefinition(def)\n }\n\n // 2. Build the dependency graph and topologically sort.\n // Children-before-parents; refs pointing outside the batch are\n // validated against the lake once.\n const ordered = await sortByDependencies(client, definitions, tags, workflowResource)\n\n // 3. Compare against the existing doc to skip unchanged definitions,\n // then write everything that DID change in a single same-resource\n // transaction. All-or-nothing — if one definition's rev check\n // fails, none of the batch lands.\n const results: DeployDefinitionResult[] = []\n const prefix = canonicalTag(tags)\n const tx = client.transaction()\n let hasWrites = false\n for (const def of ordered) {\n const id = definitionDocId(workflowResource, prefix, def.name, def.version)\n const expected = {\n ...def,\n _id: id,\n _type: WORKFLOW_DEFINITION_TYPE,\n tags,\n }\n // `getDocument` returns the doc, or null/undefined when missing\n // (different clients return different falsy sentinels). Use a\n // truthy check rather than `=== null` to cover both.\n const existing = await client.getDocument<typeof expected & SanityDocument>(id)\n if (\n existing &&\n intersectsTags(existing.tags, tags) &&\n isDefinitionUnchanged(existing, expected)\n ) {\n results.push({definition: def.name, version: def.version, status: 'unchanged'})\n continue\n }\n if (existing) {\n // Patch with rev check — fail fast if another deploy raced us.\n //\n // `set()` is a *partial* update: it overwrites the listed fields\n // but leaves any extra top-level fields untouched. That's wrong\n // for definition deploys, where a schema change can rename or\n // drop a field (e.g. `name` → `title`) and stale values would\n // otherwise linger on the deployed doc forever. Compute the\n // top-level keys that exist on `existing` but not on `expected`\n // and chain an `.unset()` so the deployed shape matches source.\n // Sanity-managed `_*` fields stay (we can't unset them anyway).\n const expectedKeys = new Set(Object.keys(expected))\n const toUnset = Object.keys(existing).filter(\n (k) => !k.startsWith('_') && !expectedKeys.has(k),\n )\n const patch = client.patch(id).set(expected).ifRevisionId(existing._rev)\n if (toUnset.length > 0) patch.unset(toUnset)\n tx.patch(patch)\n } else {\n // Net-new — `create` errors on collision instead of clobbering.\n tx.create(expected)\n }\n hasWrites = true\n results.push({\n definition: def.name,\n version: def.version,\n status: existing ? 'updated' : 'created',\n })\n }\n if (hasWrites) await tx.commit()\n\n return {results}\n },\n\n /**\n * Spawn a new workflow instance from a deployed definition.\n *\n * Pins the snapshot at start-time, seeds `effectsContext`, enters\n * the initial stage (which builds taskStatus, queues onEnter\n * effects, auto-activates tasks). Then cascades auto-transitions\n * until stable. Returns the resulting instance.\n */\n startInstance: async (args: Clocked<StartInstanceArgs>): Promise<WorkflowInstance> => {\n const {\n client,\n tags,\n workflowResource,\n definition: definitionName,\n version,\n initialState,\n ancestors,\n effectsContext,\n instanceId,\n perspective,\n } = args\n const {actor, clientForGdr} = await resolveOperationContext(args)\n const clock = args.clock ?? wallClock\n\n const definition = await loadDefinition(client, definitionName, version, tags)\n // Bare `_id` — Sanity rejects `:` in document IDs, so we don't\n // use a GDR URI here. Cross-resource references build the GDR\n // URI from `(workflowResource, _id)` on demand.\n const id = instanceId ?? `${canonicalTag(tags)}.wf-instance.${randomKey()}`\n\n const initialStage = definition.stages.find((s) => s.name === definition.initialStage)\n if (initialStage === undefined) {\n throw new Error(\n `Initial stage \"${definition.initialStage}\" missing in ${definitionName} v${definition.version}`,\n )\n }\n\n const now = clock()\n const effectsContextEntries = effectsContext ? toEffectsContextEntries(effectsContext) : []\n // Workflow-scope state entries resolve in declaration order. Later\n // entries can read earlier ones via `$state.<name>` in their GROQ.\n // There's no privileged entry name — `$state` exposes every\n // declared entry keyed by its author-chosen name.\n const resolvedState = await resolveDeclaredState({\n entryDefs: definition.state ?? [],\n initialState: initialState ?? [],\n ctx: {\n client,\n now,\n selfId: id,\n tags,\n workflowResource,\n ...(perspective !== undefined ? {perspective} : {}),\n },\n randomKey,\n })\n\n // Perspective resolution: an explicit `perspective` arg wins;\n // otherwise derive it from a populated `release.ref` state entry. This is\n // what makes a release-targeting workflow self-describing — the\n // caller fills the state entry and the engine figures out the read\n // perspective, rather than every caller having to pass it.\n const effectivePerspective = perspective ?? derivePerspectiveFromState(resolvedState)\n\n const base = buildInstanceBase({\n id,\n now,\n tags,\n workflowResource,\n definitionName: definition.name,\n pinnedVersion: definition.version,\n definition,\n state: resolvedState,\n effectsContext: effectsContextEntries,\n ancestors: ancestors ?? [],\n perspective: effectivePerspective,\n initialStage: definition.initialStage,\n actor,\n })\n // Net-new doc: `create` errors loud if `_id` collides instead of\n // silently wiping an existing instance. Use the caller-supplied\n // `instanceId` at your own risk — collisions surface here.\n await client.create(base)\n\n await primeInitialStage(client, id, actor, clientForGdr, clock)\n await cascade(client, id, actor, clientForGdr, clock)\n\n return reload(client, id, tags)\n },\n\n /**\n * Fire an action against a task. If the task is pending, it is\n * auto-invoked first (pending → active) so callers don't have to know\n * the lifecycle. Cascades auto-transitions and propagates to ancestors\n * after the action commits.\n *\n * This is the universal \"something happened\" call. Editors fire it.\n * Runtimes fire it in response to webhooks, effect completions, and\n * timer firings. External signals never bypass this.\n */\n fireAction: async (args: Clocked<FireActionArgs>): Promise<DispatchResult> => {\n const {\n client,\n tags,\n workflowResource,\n instanceId,\n task,\n action,\n params,\n idempotent,\n resourceClients,\n } = args\n const {access, actor, clientForGdr} = await resolveOperationContext(args)\n const clock = args.clock ?? wallClock\n\n const before = await reload(client, instanceId, tags)\n const taskEntry = findOpenStageEntry(before)?.tasks.find((t) => t.name === task)\n if (taskEntry === undefined && idempotent === true) {\n return {instance: before, cascaded: 0, fired: false}\n }\n\n // Soft-gate via evaluation. We project the instance from the\n // actor's perspective and check the requested action's verdict\n // before invoking the engine. If denied, the structured\n // ActionDisabledError surfaces `reason` directly.\n //\n // Reuse the already-resolved `access` (no second token/grant\n // round-trip) by passing it through as the override.\n const evaluation = await evaluateInstance({\n client,\n tags,\n workflowResource,\n instanceId,\n access,\n clock,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n })\n assertActionAllowed(evaluation, task, action)\n\n const ranOps = await applyAction({\n client,\n instance: before,\n task,\n action,\n actor,\n ...(access.grants !== undefined ? {grants: access.grants} : {}),\n clock,\n ...(params !== undefined ? {params} : {}),\n })\n\n const cascaded = await cascade(client, instanceId, actor, clientForGdr, clock)\n return {\n instance: await reload(client, instanceId, tags),\n cascaded,\n fired: true,\n ...(ranOps !== undefined ? {ranOps} : {}),\n }\n },\n\n /**\n * Report a queued effect's outcome. Drains it from `pendingEffects`,\n * appends an `effectHistory` entry, and (if `outputs` are supplied\n * and the effect succeeded) upserts those values into\n * `effectsContext` by key — so downstream effect bindings can\n * reference them. Cascades after.\n */\n completeEffect: async (args: Clocked<CompleteEffectArgs>): Promise<DispatchResult> => {\n const {client, tags, instanceId, effectKey, status, outputs, detail, error, durationMs} = args\n const {actor, clientForGdr} = await resolveOperationContext(args)\n const clock = args.clock ?? wallClock\n await engineCompleteEffect({\n client,\n instanceId,\n effectKey,\n status,\n ...(outputs !== undefined ? {outputs} : {}),\n ...(detail !== undefined ? {detail} : {}),\n ...(error !== undefined ? {error} : {}),\n ...(durationMs !== undefined ? {durationMs} : {}),\n options: {...(actor !== undefined ? {actor} : {}), clock},\n })\n const cascaded = await cascade(client, instanceId, actor, clientForGdr, clock)\n return {\n instance: await reload(client, instanceId, tags),\n cascaded,\n fired: true,\n }\n },\n\n /**\n * Re-evaluate auto-transitions and resolve due waits until stable.\n *\n * Used by the runtime after any event that might affect the workflow\n * but isn't itself a task action: a subject doc was patched, a sibling\n * workflow completed, the clock crossed a `completeWhen` deadline, etc.\n * The runtime doesn't need to know what changed — it just nudges\n * affected instances and the engine re-evaluates.\n */\n tick: async (args: Clocked<OperationArgs>): Promise<DispatchResult> => {\n const {client, tags, instanceId} = args\n const {actor, clientForGdr} = await resolveOperationContext(args)\n const clock = args.clock ?? wallClock\n const current = await reload(client, instanceId, tags)\n // Fail fast before the multi-step cascade — same pre-flight as the\n // reactive session's tick, against the instance's deployed guards\n // (engine-datasource only — foreign reads must not influence verdicts).\n const guards = await verdictGuardsForInstance(client, current._id)\n await assertInstanceWriteAllowed({instance: current, guards, identity: actor.id})\n const cascaded = await cascade(client, instanceId, actor, clientForGdr, clock)\n return {\n instance: await reload(client, instanceId, tags),\n cascaded,\n fired: cascaded > 0,\n }\n },\n\n /**\n * Admin override — force the instance into `targetStage` regardless\n * of filters or declared transitions. ACL gating should be enforced\n * upstream; this verb performs the mechanical move.\n */\n setStage: async (args: Clocked<SetStageArgs>): Promise<DispatchResult> => {\n const {client, tags, instanceId, targetStage, reason} = args\n const {actor, clientForGdr} = await resolveOperationContext(args)\n const clock = args.clock ?? wallClock\n await reload(client, instanceId, tags)\n const result = await engineSetStage({\n client,\n instanceId,\n targetStage,\n ...(reason !== undefined ? {reason} : {}),\n options: {...(actor !== undefined ? {actor} : {}), clock},\n })\n const cascaded = result.fired\n ? await cascade(client, instanceId, actor, clientForGdr, clock)\n : 0\n return {\n instance: await reload(client, instanceId, tags),\n cascaded,\n fired: result.fired,\n }\n },\n\n /**\n * Admin override — hard-stop an in-flight instance where it stands.\n * No stage move, no transition effects, pending effects cancelled; see\n * the engine-level {@link engineAbortInstance} for the full contract.\n * Ancestors are propagated (not cascaded — the instance is terminal)\n * so a parent gate waiting on this child re-evaluates.\n */\n abortInstance: async (args: Clocked<AbortInstanceArgs>): Promise<DispatchResult> => {\n const {client, tags, instanceId, reason} = args\n const {actor, clientForGdr} = await resolveOperationContext(args)\n const clock = args.clock ?? wallClock\n await reload(client, instanceId, tags)\n const result = await engineAbortInstance({\n client,\n instanceId,\n ...(reason !== undefined ? {reason} : {}),\n options: {...(actor !== undefined ? {actor} : {}), clock},\n })\n if (result.fired) {\n await propagateToAncestors(client, instanceId, actor, clientForGdr, clock)\n }\n return {\n instance: await reload(client, instanceId, tags),\n cascaded: 0,\n fired: result.fired,\n }\n },\n\n /**\n * Fetch a workflow instance by id, scoped to the engine's tags.\n * Throws when the instance doesn't exist or isn't visible to this\n * engine.\n */\n getInstance: async (args: {\n client: WorkflowClient\n tags: string[]\n workflowResource: WorkflowResource\n instanceId: string\n }): Promise<WorkflowInstance> => {\n const {client, tags, instanceId} = args\n validateTags(tags)\n return reload(client, instanceId, tags)\n },\n\n guardsForInstance: async (args: {\n client: WorkflowClient\n tags: string[]\n workflowResource: WorkflowResource\n instanceId: string\n resourceClients?: ResourceClientResolver\n }): Promise<MutationGuardDoc[]> => {\n const {client, tags, instanceId, resourceClients} = args\n validateTags(tags)\n const instance = await reload(client, instanceId, tags)\n return queryGuardsForInstance({\n client,\n clientForGdr: buildClientForGdr(client, resourceClients),\n instance,\n })\n },\n\n guardsForDefinition: async (args: {\n client: WorkflowClient\n tags: string[]\n workflowResource: WorkflowResource\n /** The definition's `name`. */\n definition: string\n resourceClients?: ResourceClientResolver\n }): Promise<MutationGuardDoc[]> => {\n const {client, tags, workflowResource, definition, resourceClients} = args\n validateTags(tags)\n const definitions = await loadDefinitionVersions(client, definition, tags)\n if (definitions.length === 0) {\n throw new Error(`No deployed definition for workflow ${definition}`)\n }\n return queryGuardsForDefinition({\n client,\n clientForGdr: buildClientForGdr(client, resourceClients),\n workflowResource,\n definition,\n definitions,\n })\n },\n\n /**\n * Run a caller-supplied GROQ query with the engine's tags bound as\n * `$engineTags`. This does NOT rewrite the query — arbitrary GROQ\n * can't be safely tag-scoped after the fact — so the CALLER MUST\n * filter on `$engineTags` (e.g.\n * `count(tags[@ in $engineTags]) > 0`). To guard against accidental\n * cross-tenant reads, a query that never references `$engineTags` is\n * rejected before it reaches the lake. Caller is responsible for type\n * narrowing the result.\n */\n query: async <T = unknown>(args: {\n client: WorkflowClient\n tags: string[]\n workflowResource: WorkflowResource\n groq: string\n params?: Record<string, unknown>\n }): Promise<T> => {\n const {client, tags, groq, params} = args\n validateTags(tags)\n if (!groq.includes('$engineTags')) {\n throw new Error(\n `workflow.query: query must filter on $engineTags to stay tag-scoped (e.g. \"count(tags[@ in $engineTags]) > 0\"); got: ${groq}`,\n )\n }\n return client.fetch<T>(groq, {...params, engineTags: tags})\n },\n\n /**\n * Snapshot-aware GROQ — runs against the same in-memory view that\n * filters see for a given instance.\n *\n * Hydrates the instance's snapshot (instance + ancestors + every doc\n * declared by a `doc.ref` / `doc.refs` entry in scope), then\n * evaluates the supplied GROQ in groq-js against that dataset. The\n * rendered scope is auto-bound: `$self`, `$state`, `$parent`,\n * `$ancestors`, `$stage`, `$now`, `$effects`, `$tasks`,\n * `$allTasksDone`, `$anyTaskFailed` — ids in GDR URI form to match\n * the snapshot's keying.\n *\n * Use when an external consumer (a UI, a debug pane, a test) wants\n * to ask \"what does the engine see for this workflow right now?\"\n * without re-implementing hydration. Pure read — never writes.\n */\n queryInScope: async <T = unknown>(\n args: Clocked<{\n client: WorkflowClient\n tags: string[]\n workflowResource: WorkflowResource\n resourceClients?: ResourceClientResolver\n instanceId: string\n groq: string\n params?: Record<string, unknown>\n }>,\n ): Promise<T> => {\n const {client, tags, instanceId, groq, params, resourceClients} = args\n const clock = args.clock ?? wallClock\n validateTags(tags)\n const instance = await reload(client, instanceId, tags)\n const clientForGdr = buildClientForGdr(client, resourceClients)\n const snapshot = await hydrateSnapshot({client, clientForGdr, instance})\n const reserved = buildParams({instance, now: clock(), snapshot})\n const tree = parseGroq(groq, {params: {...reserved, ...params}})\n const evaluated = await evaluateGroq(tree, {\n dataset: snapshot.docs,\n params: {...reserved, ...params},\n })\n return (await evaluated.get()) as T\n },\n\n /**\n * List every pending effect on the instance. Returns the same entries\n * the runtime would see — claimed and unclaimed alike.\n */\n listPendingEffects: async (args: {\n client: WorkflowClient\n tags: string[]\n workflowResource: WorkflowResource\n instanceId: string\n }): Promise<PendingEffect[]> => {\n const inst = await reload(args.client, args.instanceId, args.tags)\n return inst.pendingEffects\n },\n\n /**\n * Filter pending effects on the instance by criteria. `claimed`\n * filters on claim presence; `names` restricts to specific effect\n * names. Both filters compose (AND).\n */\n findPendingEffects: async (args: {\n client: WorkflowClient\n tags: string[]\n workflowResource: WorkflowResource\n instanceId: string\n claimed?: boolean\n names?: string[]\n }): Promise<PendingEffect[]> => {\n const inst = await reload(args.client, args.instanceId, args.tags)\n return inst.pendingEffects.filter((e) => {\n if (args.claimed === true && e.claim === undefined) return false\n if (args.claimed === false && e.claim !== undefined) return false\n if (args.names !== undefined && !args.names.includes(e.name)) return false\n return true\n })\n },\n\n /**\n * Project the instance from a given actor's perspective. Returns a\n * `WorkflowEvaluation` with per-action verdicts (`allowed` + a\n * structured `disabledReason`). Pure read; never writes.\n *\n * Used by UIs to render disabled-with-reason buttons and by\n * `fireAction` to gate writes via the same logic.\n */\n evaluate: async (args: Clocked<EvaluateArgs>): Promise<WorkflowEvaluation> => {\n return evaluateInstance(args)\n },\n\n /**\n * Materialised spawned children of a parent instance.\n *\n * Walks `history` for `spawned` events — the durable\n * record. (The per-task `spawnedInstances` field on the active stage\n * only exists while that stage is current; history survives.) Strips\n * the GDR URI on each `instanceRef` to a bare `_id`, fetches the\n * instances, drops any that aren't visible to this engine's tags, and\n * returns them sorted by `startedAt` ascending.\n *\n * Pass `task` to restrict to a single spawning task on the parent.\n */\n children: async (args: {\n client: WorkflowClient\n tags: string[]\n workflowResource: WorkflowResource\n instanceId: string\n task?: string\n }): Promise<WorkflowInstance[]> => {\n const {client, tags, instanceId, task} = args\n validateTags(tags)\n const parent = await reload(client, instanceId, tags)\n const isSpawned = (h: HistoryEntry): h is Extract<HistoryEntry, {_type: 'spawned'}> =>\n h._type === 'spawned'\n const ids = parent.history\n .filter(isSpawned)\n .filter((h) => task === undefined || h.task === task)\n .flatMap((h) => bareIdFromSpawnRef(h.instanceRef.id))\n if (ids.length === 0) return []\n // Single GROQ — server-side filters by id set + engine tags, sorts\n // by startedAt. Beats N `getDocument` roundtrips for fan-outs.\n //\n // Visibility: this assumes spawn writes were committed with default\n // `visibility: \"sync\"` (which is what @sanity/client does and what\n // the engine relies on everywhere else). If a write path ever opts\n // into `async`, this query will silently miss freshly-spawned\n // children — but every other GROQ in the engine has the same\n // assumption, so we're not making things worse here.\n return client.fetch<WorkflowInstance[]>(\n `*[_id in $ids && ${tagScopeFilter()}] | order(startedAt asc)`,\n {ids, engineTags: tags},\n )\n },\n\n /**\n * Permission helpers — Sanity ACL grants evaluated against documents\n * via GROQ. Used by `workflow.evaluate` to soft-gate actions when the\n * caller supplies grants.\n */\n permissions: {\n matchesFilter: permMatchesFilter,\n grantsPermissionOn: permGrantsPermissionOn,\n fetchGrants: permFetchGrants,\n },\n}\n","import type {WorkflowAccessOverride} from '../access.ts'\nimport type {GlobalDocumentReference, WorkflowResource} from '../core/refs.ts'\nimport {WORKFLOW_DEFINITION_TYPE, type Effect, type WorkflowDefinition} from '../define/schema.ts'\nimport {isRevisionConflict} from '../engine/results.ts'\nimport {tagScopeFilter, validateTags} from '../tags.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {PendingEffect} from '../types/effects.ts'\nimport type {WorkflowInstance} from '../types/instance.ts'\nimport {reload} from './operations.ts'\nimport type {\n DrainEffectsResult,\n EffectHandler,\n EngineLogger,\n LoggerFactory,\n MissingHandlerDeployInfo,\n MissingHandlerInfo,\n MissingHandlerPolicy,\n ResourceClientResolver,\n VerifyDeployedDefinitionsResult,\n} from './types.ts'\nimport {workflow} from './workflow.ts'\n\nexport async function verifyDeployedDefinitionsInternal(args: {\n client: WorkflowClient\n tags: string[]\n effectHandlers: Record<string, EffectHandler>\n missingHandler: MissingHandlerPolicy\n logger: LoggerFactory\n}): Promise<VerifyDeployedDefinitionsResult> {\n const {client, tags, effectHandlers, missingHandler, logger} = args\n validateTags(tags)\n const log = logger('verifyDeployedDefinitions')\n const definitions = await client.fetch<(WorkflowDefinition & {_id: string})[]>(\n `*[_type == \"${WORKFLOW_DEFINITION_TYPE}\" && ${tagScopeFilter()}] | order(name asc, version asc)`,\n {engineTags: tags},\n )\n\n const seen: VerifyDeployedDefinitionsResult['definitions'] = []\n const missingByName = new Map<string, {definitionId: string; locations: Set<string>}>()\n for (const def of definitions) {\n seen.push({name: def.name, version: def.version, _id: def._id})\n walkEffectNames(def, (name, location) => {\n if (effectHandlers[name] !== undefined) return\n const key = `${name}@@${def._id}`\n let bucket = missingByName.get(key)\n if (bucket === undefined) {\n bucket = {definitionId: def._id, locations: new Set()}\n missingByName.set(key, bucket)\n }\n bucket.locations.add(location)\n })\n }\n\n const missing: VerifyDeployedDefinitionsResult['missing'] = []\n for (const [key, bucket] of missingByName.entries()) {\n const name = key.split('@@')[0]!\n missing.push({\n name,\n definitionId: bucket.definitionId,\n locations: [...bucket.locations].toSorted(),\n })\n }\n\n for (const m of missing) {\n const info: MissingHandlerDeployInfo = {\n phase: 'deploy',\n name: m.name,\n locations: m.locations,\n definitionId: m.definitionId,\n }\n const verdict = await applyMissingHandler(missingHandler, info, log)\n if (verdict === 'fail') {\n throw new Error(\n `verifyDeployedDefinitions: missing handler for \"${m.name}\" referenced by ${m.definitionId} at ${m.locations.join(', ')}`,\n )\n }\n }\n\n return {definitions: seen, missing}\n}\n\n/** Walk every external effect reference in a definition, invoking the\n * visitor with each name + a structural location string. */\nfunction walkEffectNames(\n def: WorkflowDefinition & {_id?: string},\n visit: (id: string, location: string) => void,\n): void {\n const visitEffects = (effects: Effect[] | undefined, location: string) => {\n for (const e of effects ?? []) visit(e.name, location)\n }\n for (const stage of def.stages ?? []) {\n for (const t of stage.tasks ?? []) {\n visitEffects(t.effects, `stage[${stage.name}].task[${t.name}].effects`)\n for (const a of t.actions ?? []) {\n visitEffects(a.effects, `stage[${stage.name}].task[${t.name}].action[${a.name}].effects`)\n }\n }\n for (const tr of stage.transitions ?? []) {\n visitEffects(tr.effects, `stage[${stage.name}].transition[${tr.name}].effects`)\n }\n }\n}\n\n// drainEffects — three-write claim protocol per pending entry.\n//\n// 1. CLAIM: load instance (rev R0). Stamp `claim` on an unclaimed entry.\n// Persist via patch().set().ifRevisionId(R0). On rev mismatch\n// (someone else committed), restart and pick a different entry.\n// 2. DISPATCH: invoke the registered handler in a try/catch.\n// 3. COMPLETE: call `completeEffect` which moves the entry from\n// `pendingEffects[]` to `effectHistory[]` and cascades.\n//\n// Returns drained / failed / skipped buckets. Skipped means missing\n// handler (subject to the engine's missingHandler policy).\n\nexport async function drainEffectsInternal(args: {\n client: WorkflowClient\n tags: string[]\n workflowResource: WorkflowResource\n resourceClients?: ResourceClientResolver\n instanceId: string\n effectHandlers: Record<string, EffectHandler>\n missingHandler: MissingHandlerPolicy\n logger: LoggerFactory\n /** Identity override for the drainer. Defaults to a system actor. */\n access?: WorkflowAccessOverride\n}): Promise<DrainEffectsResult> {\n const {\n client,\n tags,\n workflowResource,\n resourceClients,\n instanceId,\n effectHandlers,\n missingHandler,\n logger,\n } = args\n const drainerActor: Actor = args.access?.actor ?? {kind: 'system', id: 'engine.drainEffects'}\n // The completion call goes through workflow.completeEffect which\n // also accepts WorkflowAccessOverride; we hand it the drainer's\n // identity (override.actor or the system fallback) and pass any\n // explicit grants through verbatim.\n const completionAccess: WorkflowAccessOverride = {\n actor: drainerActor,\n ...(args.access?.grants !== undefined ? {grants: args.access.grants} : {}),\n }\n validateTags(tags)\n const log = logger('drainEffects')\n const drained: PendingEffect[] = []\n const failed: PendingEffect[] = []\n const skipped: PendingEffect[] = []\n // Keys of entries we've decided to skip (missing handler, policy\n // allows). We never claim them, so a plain `continue` would re-pick\n // the same entry forever — exclude them from the candidate search so\n // later entries that DO have handlers still drain.\n const skippedKeys = new Set<string>()\n\n while (true) {\n const before = await reload(client, instanceId, tags)\n const candidate = before.pendingEffects.find(\n (e) => e.claim === undefined && !skippedKeys.has(e._key),\n )\n if (candidate === undefined) break\n\n const handler = effectHandlers[candidate.name]\n if (handler === undefined) {\n await assertSkippableOrThrow(missingHandler, candidate, instanceId, log)\n skipped.push(candidate)\n skippedKeys.add(candidate._key)\n continue\n }\n\n const claimed = await claimPendingEffect(client, before, candidate._key, drainerActor)\n if (!claimed) continue // 409 — re-read and retry a fresh candidate.\n\n const {outputs, dispatchError} = await dispatchEffect(handler, candidate, {\n client,\n instanceId,\n logger,\n })\n\n await reportEffectOutcome({\n client,\n tags,\n workflowResource,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n instanceId,\n effectKey: candidate._key,\n access: completionAccess,\n outputs,\n dispatchError,\n })\n\n if (dispatchError === undefined) drained.push(candidate)\n else failed.push(candidate)\n }\n\n return {drained, failed, skipped}\n}\n\n/** Report a dispatched effect's outcome through `workflow.completeEffect`,\n * translating the dispatch result into the `done`/`failed` status +\n * optional outputs/error the API expects. */\nasync function reportEffectOutcome(args: {\n client: WorkflowClient\n tags: string[]\n workflowResource: WorkflowResource\n resourceClients?: ResourceClientResolver\n instanceId: string\n effectKey: string\n access: WorkflowAccessOverride\n outputs: Record<string, string | number | boolean | GlobalDocumentReference> | undefined\n dispatchError: {message: string; stack?: string} | undefined\n}): Promise<void> {\n const {outputs, dispatchError, resourceClients, ...rest} = args\n await workflow.completeEffect({\n ...rest,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n status: dispatchError === undefined ? 'done' : 'failed',\n ...(outputs !== undefined ? {outputs} : {}),\n ...(dispatchError !== undefined ? {error: dispatchError} : {}),\n })\n}\n\n/** Apply the missing-handler policy to an unhandled candidate. Throws\n * when the policy resolves to `fail`; returns when the entry may be\n * skipped. */\nasync function assertSkippableOrThrow(\n missingHandler: MissingHandlerPolicy,\n candidate: PendingEffect,\n instanceId: string,\n log: EngineLogger,\n): Promise<void> {\n const policyResult = await applyMissingHandler(\n missingHandler,\n {phase: 'drain', name: candidate.name, effectKey: candidate._key, instanceId},\n log,\n )\n if (policyResult === 'fail') {\n throw new Error(\n `drainEffects: no handler registered for \"${candidate.name}\" (effectKey=${candidate._key}, instanceId=${instanceId})`,\n )\n }\n}\n\n/**\n * Claim a single pending entry by stamping `claim` conditional on the\n * instance's current `_rev`. Returns false on a 409 rev mismatch (a\n * concurrent writer raced us) so the caller re-reads and retries.\n */\nasync function claimPendingEffect(\n client: WorkflowClient,\n instance: WorkflowInstance,\n effectKey: string,\n drainerActor: Actor,\n): Promise<boolean> {\n const claim = {\n _type: 'pendingEffect.claim' as const,\n claimedAt: new Date().toISOString(),\n claimedBy: drainerActor,\n }\n try {\n await client\n .patch(instance._id)\n .ifRevisionId(instance._rev)\n .set({[`pendingEffects[_key==\"${effectKey}\"].claim`]: claim})\n .commit()\n return true\n } catch (error) {\n // Only a lost rev race means \"another drainer claimed it\" — re-read and\n // try a fresh candidate. A real error (network, malformed patch) must\n // surface rather than masquerade as a benign claim miss.\n if (!isRevisionConflict(error)) throw error\n return false\n }\n}\n\n/** Invoke a handler, capturing its `outputs` or shaping a thrown error\n * into the `{message, stack?}` envelope `completeEffect` expects. */\nasync function dispatchEffect(\n handler: EffectHandler,\n candidate: PendingEffect,\n ctx: {client: WorkflowClient; instanceId: string; logger: LoggerFactory},\n): Promise<{\n outputs?: Record<string, string | number | boolean | GlobalDocumentReference>\n dispatchError?: {message: string; stack?: string}\n}> {\n try {\n const result = await handler(candidate.params, {\n client: ctx.client,\n instanceId: ctx.instanceId,\n effectKey: candidate._key,\n log: (message, extra) => ctx.logger(`effect.${candidate.name}`).info(message, extra),\n })\n return result?.outputs !== undefined ? {outputs: result.outputs} : {}\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n const stack = err instanceof Error && err.stack !== undefined ? err.stack : undefined\n return {dispatchError: stack !== undefined ? {message, stack} : {message}}\n }\n}\n\nasync function applyMissingHandler(\n policy: MissingHandlerPolicy,\n info: MissingHandlerInfo,\n log: EngineLogger,\n): Promise<'fail' | 'skip'> {\n if (policy === 'fail') return 'fail'\n if (policy === 'skip') {\n log.warn(`Missing effect handler \"${info.name}\" — skipping`, {info})\n return 'skip'\n }\n try {\n await policy(info)\n return 'skip'\n } catch {\n return 'fail'\n }\n}\n","/**\n * Reactive instance session — the engine held \"live\" on document state the\n * consumer pushes. Opt in with `engine.instance(instanceDoc)`. The session\n * holds the instance + an owned content snapshot you {@link InstanceSession.update};\n * `evaluate`/`tick`/`fireAction` run against the held state — content you've\n * pushed is never refetched.\n *\n * Observation-agnostic: the consumer (Studio / SDK / a Function) observes in\n * its own store semantics and feeds values in via `update`. The session never\n * subscribes and never ticks on its own.\n *\n * Discipline:\n * - `update` is **last-write-wins**, scoped to the watch-set: it replaces the\n * held content (deep-copied → decoupled from the consumer's live objects),\n * and a self-doc updates the held instance.\n * - It is **gated**: an `update` that arrives while a `tick`/`fireAction` is\n * committing is buffered and applied once the commit settles (single-writer).\n * - Each operation **captures** the held content at entry and runs against\n * that snapshot for its whole duration — no mutation or field-swap leaks in.\n * - `tick`/`fireAction` commit through the lake (`ifRevisionId` + guards); a\n * conflict surfaces (no internal retry). The instance reloads its own writes;\n * only content comes from the overlay.\n */\n\nimport type {SanityDocument} from '@sanity/types'\n\nimport {resolveAccess, type WorkflowAccessOverride} from '../access.ts'\nimport type {Clock} from '../clock.ts'\nimport {assertInstanceWriteAllowed} from '../core/guards.ts'\nimport {gdrFromResource} from '../core/refs.ts'\nimport {buildSnapshot, type HydratedSnapshot, type LoadedDoc} from '../core/snapshot.ts'\nimport {evaluateFromSnapshot} from '../evaluate.ts'\nimport {subscriptionDocumentsForInstance, type WatchSet} from '../subscription-documents.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {Grant, MutationGuardDoc} from '../types/authorization.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {WorkflowEvaluation} from '../types/evaluation.ts'\nimport {\n parseDefinitionSnapshot,\n WORKFLOW_INSTANCE_TYPE,\n type WorkflowInstance,\n} from '../types/instance.ts'\nimport {applyAction, assertActionAllowed, buildClientForGdr, cascade, reload} from './operations.ts'\nimport type {DispatchResult, ResourceClientResolver} from './types.ts'\n\nexport interface InstanceSession {\n /** The watch-set to feed via {@link InstanceSession.update}, derived from the\n * held instance. Recompute after the instance changes (a new stage changes it). */\n readonly subscriptionDocuments: WatchSet\n /** Replace the held content with the current values the consumer observed\n * (last-write-wins, scoped). A doc whose id is the instance itself updates\n * the held instance. Buffered if a commit is in flight. */\n update(docs: LoadedDoc[]): void\n /** Replace the held live guards (the consumer's guard stream,\n * last-write-wins). Guards are a separate stream from the watch-set:\n * {@link InstanceSession.evaluate} pre-flights the instance write against\n * them so action verdicts surface `mutation-guard-denied` while a matching\n * guard denies. Unlike {@link InstanceSession.update}, this is NOT buffered\n * behind an in-flight commit — guards aren't part of the held-snapshot\n * consistency story, and tick's pre-flight reads them at commit start. */\n updateGuards(guards: readonly MutationGuardDoc[]): void\n /** Best-effort projection against the held content + held guards. No network\n * (async only because filter evaluation runs on groq-js). */\n evaluate(): Promise<WorkflowEvaluation>\n /** Advance the instance against the held content: cascade auto-transitions,\n * deploy guards, queue effects, commit with `ifRevisionId`. */\n tick(): Promise<DispatchResult>\n /** Fire an action against a task, gated on the held content, then cascade. */\n fireAction(args: {\n task: string\n action: string\n params?: Record<string, unknown>\n }): Promise<DispatchResult>\n}\n\nexport interface CreateInstanceSessionArgs {\n client: WorkflowClient\n tags: string[]\n instance: WorkflowInstance\n resourceClients?: ResourceClientResolver\n /** Resolved actor/grants. Omit to token-resolve from the client. */\n access?: WorkflowAccessOverride\n grantsFromPath?: string\n /** Clock for `$now` / time-based filters; omit for wall-clock. The bench\n * passes a frozen clock for deterministic reactive evaluation. */\n clock?: Clock\n}\n\nexport function createInstanceSession(args: CreateInstanceSessionArgs): InstanceSession {\n const {client, tags, clock} = args\n const clientForGdr = buildClientForGdr(client, args.resourceClients)\n\n // Held state. Validate at construction the same way `update` validates a\n // pushed self-doc — the instance often comes from a consumer's live store\n // (a reactive adapter), so a malformed doc must fail hard here too.\n let instance = asHeldInstance(args.instance)\n let overlay = new Map<string, LoadedDoc>()\n // Live guards are a separate stream from the watch-set; last-write-wins,\n // deep-copied like the overlay so the consumer's store can't leak in.\n let heldGuards: readonly MutationGuardDoc[] = []\n // Single-writer gate: an update that lands during a commit is buffered\n // (last-write-wins — only the newest buffered set matters) and applied when\n // the commit settles.\n let committing = false\n let buffered: LoadedDoc[] | undefined\n\n const selfUri = (): string => gdrFromResource(instance.workflowResource, instance._id)\n\n const applyUpdate = (docs: LoadedDoc[]): void => {\n const next = new Map<string, LoadedDoc>()\n for (const ld of docs) {\n // Deep-copy so the held content is decoupled from the consumer's live\n // store objects — a later mutation there can't leak into an operation.\n const owned: LoadedDoc = {doc: structuredClone(ld.doc), resource: ld.resource}\n const uri = gdrFromResource(owned.resource, owned.doc._id)\n if (uri === selfUri()) {\n instance = asHeldInstance(owned.doc)\n continue\n }\n next.set(uri, owned)\n }\n overlay = next\n }\n\n const access = (): Promise<{actor: Actor; grants?: Grant[]}> =>\n resolveAccess(client, {\n ...(args.access !== undefined ? {override: args.access} : {}),\n ...(args.grantsFromPath !== undefined ? {grantsFromPath: args.grantsFromPath} : {}),\n })\n\n const snapshotFrom = (held: ReadonlyMap<string, LoadedDoc>): HydratedSnapshot =>\n buildSnapshot({docs: [{doc: instance, resource: instance.workflowResource}, ...held.values()]})\n\n const evaluateWith = async (\n held: ReadonlyMap<string, LoadedDoc>,\n guards: readonly MutationGuardDoc[],\n ): Promise<WorkflowEvaluation> => {\n const {actor, grants} = await access()\n return evaluateFromSnapshot({\n instance,\n definition: parseDefinitionSnapshot(instance),\n actor,\n snapshot: snapshotFrom(held),\n guards,\n ...(clock !== undefined ? {now: clock()} : {}),\n ...(grants !== undefined ? {grants} : {}),\n })\n }\n\n // Run a commit single-writer: capture the held content, hold it for the whole\n // op, buffer any concurrent update, apply the buffered one when done.\n const commit = async (\n run: (actor: Actor, held: ReadonlyMap<string, LoadedDoc>) => Promise<DispatchResult>,\n ): Promise<DispatchResult> => {\n committing = true\n const held = new Map(overlay)\n try {\n const {actor} = await access()\n return await run(actor, held)\n } finally {\n committing = false\n if (buffered !== undefined) {\n const next = buffered\n buffered = undefined\n applyUpdate(next)\n }\n }\n }\n\n return {\n get subscriptionDocuments() {\n return subscriptionDocumentsForInstance(instance)\n },\n\n update(docs) {\n if (committing) {\n buffered = docs\n return\n }\n applyUpdate(docs)\n },\n\n updateGuards(guards) {\n heldGuards = guards.map((guard) => structuredClone(guard))\n },\n\n evaluate() {\n return evaluateWith(overlay, heldGuards)\n },\n\n tick() {\n return commit(async (actor, held) => {\n // Fail fast before entering the multi-step cascade (commit → deploy\n // guards → effects): a held guard that denies the instance write\n // would doom the first commit, and later steps aren't all reversible.\n await assertInstanceWriteAllowed({instance, guards: heldGuards, identity: actor.id})\n const cascaded = await cascade(client, instance._id, actor, clientForGdr, clock, held)\n instance = await reload(client, instance._id, tags)\n return {instance, cascaded, fired: cascaded > 0}\n })\n },\n\n fireAction({task, action, params}) {\n return commit(async (actor, held) => {\n // Soft-gate on the held content + live guards — the same projection\n // the UI rendered (a guard-denied action throws before any write).\n assertActionAllowed(await evaluateWith(held, heldGuards), task, action)\n const {grants} = await access()\n // Apply the action against the instance (reloading its own writes);\n // content stays overlaid in the cascade below.\n const ranOps = await applyAction({\n client,\n instance,\n task,\n action,\n actor,\n ...(grants !== undefined ? {grants} : {}),\n ...(clock !== undefined ? {clock} : {}),\n ...(params !== undefined ? {params} : {}),\n })\n const cascaded = await cascade(client, instance._id, actor, clientForGdr, clock, held)\n instance = await reload(client, instance._id, tags)\n return {instance, cascaded, fired: true, ...(ranOps !== undefined ? {ranOps} : {})}\n })\n },\n }\n}\n\n/**\n * Validate a pushed self-doc before it becomes the held instance. The doc comes\n * from the consumer's live store, so a malformed push must fail hard at the\n * boundary rather than silently corrupting the state that drives\n * `evaluate`/`subscriptionDocuments`.\n */\nfunction asHeldInstance(doc: SanityDocument): WorkflowInstance {\n const candidate = doc as Partial<WorkflowInstance>\n if (\n candidate._type !== WORKFLOW_INSTANCE_TYPE ||\n typeof candidate.currentStage !== 'string' ||\n !Array.isArray(candidate.stages)\n ) {\n throw new Error(`update: self-doc ${doc._id} is not a valid workflow.instance`)\n }\n return doc as WorkflowInstance\n}\n","import type {WorkflowAccessOverride} from '../access.ts'\nimport type {Clock} from '../clock.ts'\nimport type {WorkflowResource} from '../core/refs.ts'\nimport {type EvaluateArgs, evaluateInstance} from '../evaluate.ts'\nimport {subscriptionDocumentsForInstance, type WatchSet} from '../subscription-documents.ts'\nimport {validateTags} from '../tags.ts'\nimport type {MutationGuardDoc} from '../types/authorization.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {PendingEffect} from '../types/effects.ts'\nimport type {WorkflowInstance} from '../types/instance.ts'\nimport {drainEffectsInternal, verifyDeployedDefinitionsInternal} from './drain.ts'\nimport {createInstanceSession, type InstanceSession} from './instance-session.ts'\nimport type {\n CompleteEffectArgs,\n DeployDefinitionsArgs,\n DeployDefinitionsResult,\n DispatchResult,\n DrainEffectsResult,\n EffectHandler,\n AbortInstanceArgs,\n EngineLogger,\n FireActionArgs,\n LoggerFactory,\n MissingHandlerPolicy,\n OperationArgs,\n ResourceClientResolver,\n SetStageArgs,\n StartInstanceArgs,\n VerifyDeployedDefinitionsResult,\n} from './types.ts'\nimport {workflow} from './workflow.ts'\n\n// createEngine factory.\n//\n// Pre-binds `client`, `tags`, `workflowResource` (and optional\n// `effectHandlers`, `missingHandler`, `loggerFactory`) so callers don't\n// repeat them on every call. Exposes the same verb surface as the\n// `workflow.*` namespace; the namespace stays for callers that want the\n// raw, unbound functions.\n\nexport interface CreateEngineArgs {\n client: WorkflowClient\n workflowResource: WorkflowResource\n tags: string[]\n /**\n * Optional routing for cross-resource reads. When the engine needs\n * a doc whose GDR points at a resource other than its own, it calls\n * the resolver; if the resolver returns a client, that one is used.\n * Otherwise the engine's default `client` is used (best for\n * single-resource setups — most demos).\n */\n resourceClients?: ResourceClientResolver\n effectHandlers?: Record<string, EffectHandler>\n missingHandler?: MissingHandlerPolicy\n loggerFactory?: LoggerFactory\n /**\n * Deterministic-time seam, pinned once for this engine and threaded\n * into every verb it drives — `$now`, the `now` op-source, and the\n * timestamps the engine stamps all read from it. Omit (the default) to\n * use real wall-clock time; production never sets this. The test bench\n * (`@sanity/workflow-engine-test`) wraps this same seam as `setNow` /\n * `advance`. Deliberately engine-construction config, NOT a per-verb\n * option.\n */\n clock?: Clock\n}\n\ntype Bound<\n Args extends {client: WorkflowClient; tags: string[]; workflowResource: WorkflowResource},\n> = Omit<Args, 'client' | 'tags' | 'workflowResource'>\n\nexport interface Engine {\n /** Engine-scoped bindings — exposed for the few advanced consumers\n * (e.g. test bench, drain workers) that need them; the verbs already\n * thread them through internally. */\n readonly client: WorkflowClient\n readonly tags: readonly string[]\n readonly workflowResource: WorkflowResource\n readonly effectHandlers: Readonly<Record<string, EffectHandler>>\n readonly missingHandler: MissingHandlerPolicy\n readonly logger: LoggerFactory\n\n deployDefinitions: (args: Bound<DeployDefinitionsArgs>) => Promise<DeployDefinitionsResult>\n startInstance: (args: Bound<StartInstanceArgs>) => Promise<WorkflowInstance>\n fireAction: (args: Bound<FireActionArgs>) => Promise<DispatchResult>\n completeEffect: (args: Bound<CompleteEffectArgs>) => Promise<DispatchResult>\n tick: (args: Bound<OperationArgs>) => Promise<DispatchResult>\n evaluateInstance: (args: Bound<EvaluateArgs>) => ReturnType<typeof evaluateInstance>\n\n /** Admin override — bypass filters/transitions and force the stage. */\n setStage: (args: Bound<SetStageArgs>) => Promise<DispatchResult>\n /** Admin override — hard-stop an in-flight instance where it stands. */\n abortInstance: (args: Bound<AbortInstanceArgs>) => Promise<DispatchResult>\n /** Fetch a workflow instance by id. */\n getInstance: (args: {instanceId: string}) => Promise<WorkflowInstance>\n /** The reactive {@link WatchSet} for an instance — every document whose\n * change should re-evaluate it (the instance, its ancestors, and the docs\n * named by `doc.ref`/`doc.refs`/`release.ref` state entries on the workflow scope\n * + current stage) as exploded {@link SubscriptionDocument}s, plus the\n * instance's read perspective. Fetches the instance, then derives. A\n * reactive adapter that already holds the live instance calls the pure\n * `subscriptionDocumentsForInstance` directly instead, to avoid the re-fetch. */\n subscriptionDocumentsForInstance: (args: {instanceId: string}) => Promise<WatchSet>\n /** Opt into reactivity: bind the engine to an instance doc and get a stateful\n * {@link InstanceSession}. Push the docs it lists in `subscriptionDocuments`\n * via `update`, then `evaluate`/`tick`/`fireAction` against the held state —\n * pushed content is never refetched. The session never observes or ticks on\n * its own; the consumer drives it. */\n instance: (\n instanceDoc: WorkflowInstance,\n opts?: {access?: WorkflowAccessOverride; grantsFromPath?: string},\n ) => InstanceSession\n /** Every lake mutation guard this instance registered, unioned across the\n * instance's own resource and the resource of each `doc.ref`/`doc.refs`\n * GDR it holds in state. For coherency refresh and housekeeping. */\n guardsForInstance: (args: {instanceId: string}) => Promise<MutationGuardDoc[]>\n /** Every lake mutation guard a workflow deployed (any version), across the\n * datasources its guards statically name — the workflow resource plus any\n * literal-GDR state entries, unioned over all deployed versions.\n * Needs no live instance. Guards whose resource is only known per-instance\n * (init/runtime-sourced entries) are not reachable here — use\n * {@link Engine.guardsForInstance}. For housekeeping. Takes the\n * definition's `name`. */\n guardsForDefinition: (args: {definition: string}) => Promise<MutationGuardDoc[]>\n /** Spawned children of a parent instance, optionally filtered by the\n * spawning task. Sorted by `startedAt` asc. */\n children: (args: {instanceId: string; task?: string}) => Promise<WorkflowInstance[]>\n /** GROQ query against the engine's workflow resource. `$engineTags`\n * is bound for tag-aware filtering. */\n query: <T = unknown>(args: {groq: string; params?: Record<string, unknown>}) => Promise<T>\n /** Snapshot-aware GROQ — runs against the same in-memory view the\n * engine's filters see for the supplied instance. The rendered scope\n * (`$self`, `$state`, `$parent`, `$ancestors`, `$stage`, `$now`,\n * `$effects`, `$tasks`, `$allTasksDone`, `$anyTaskFailed`) is bound,\n * ids in GDR URI form to match the snapshot's keying. */\n queryInScope: <T = unknown>(args: {\n instanceId: string\n groq: string\n params?: Record<string, unknown>\n }) => Promise<T>\n /** List every pending effect on an instance. */\n listPendingEffects: (args: {instanceId: string}) => Promise<PendingEffect[]>\n /** Filter pending effects by claimed status and/or effect names. */\n findPendingEffects: (args: {\n instanceId: string\n claimed?: boolean\n names?: string[]\n }) => Promise<PendingEffect[]>\n /** Dispatch unclaimed effects through registered handlers. The\n * drainer's identity defaults to a `{ kind: \"system\", id: \"engine.drainEffects\" }`\n * actor; pass `access` to override (e.g. impersonate a real user\n * whose grants you want the dispatch to respect). */\n drainEffects: (args: {\n instanceId: string\n access?: WorkflowAccessOverride\n }) => Promise<DrainEffectsResult>\n /**\n * Inspect every deployed definition in the engine's tags and apply\n * the configured missingHandler policy at `phase: \"deploy\"` for any\n * effect name without a registered handler. Catches \"definition\n * shipped, handler removed\" misconfigurations at startup instead of\n * three days later when the effect fires.\n *\n * Returns the list of (definitionId, name, locations) tuples it saw.\n * Throws if missingHandler resolved as \"fail\" for any of them.\n */\n verifyDeployedDefinitions: () => Promise<VerifyDeployedDefinitionsResult>\n}\n\n/**\n * Default LoggerFactory — writes through the global `console`. Exposed\n * so callers outside `createEngine` (drive scripts, the\n * drain-effects helper) can use the same logger shape the engine uses\n * internally. Returns a fresh `EngineLogger` per call; the `name`\n * shows up as a `[name]` prefix on every line.\n */\nexport const defaultLoggerFactory: LoggerFactory = (name) => ({\n // info/warn/error all go to stderr — these are diagnostic, not\n // program output. Keeps stdout reserved for the caller's own data\n // so progress markers (process.stdout.write) and logger lines\n // don't interleave on the same line.\n info: (message, extra) => console.error(`[${name}] ${message}`, extra !== undefined ? extra : ''),\n warn: (message, extra) => console.warn(`[${name}] ${message}`, extra !== undefined ? extra : ''),\n error: (message, extra) =>\n console.error(`[${name}] ${message}`, extra !== undefined ? extra : ''),\n})\n\n/**\n * No-op logger. Default for library callers that don't want any\n * output unless explicitly opted in.\n */\nexport const silentLogger: EngineLogger = {\n info: () => {},\n warn: () => {},\n error: () => {},\n}\n\n/**\n * Construct an engine bound to a workflow resource + tags. The returned\n * object exposes the same verbs as the `workflow.*` namespace, minus\n * the boilerplate config arguments (client / tags / workflowResource)\n * which are pinned at construction.\n *\n * Effect handlers + missingHandler are stored for future drain wiring\n * (Step 10). They have no effect on `fireAction` / `tick` /\n * `completeEffect` today — those still expect the runtime to dispatch\n * effects and report back via `completeEffect`.\n */\nexport function createEngine(args: CreateEngineArgs): Engine {\n const {client, workflowResource, tags, resourceClients, clock} = args\n validateTags(tags)\n const effectHandlers = args.effectHandlers ?? {}\n const missingHandler = args.missingHandler ?? 'fail'\n const logger = args.loggerFactory ?? defaultLoggerFactory\n\n const bind = <\n A extends {client: WorkflowClient; tags: string[]; workflowResource: WorkflowResource},\n >(\n rest: Omit<A, 'client' | 'tags' | 'workflowResource'>,\n ): A =>\n ({\n client,\n tags,\n workflowResource,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n ...(clock !== undefined ? {clock} : {}),\n ...rest,\n }) as A\n\n return {\n client,\n tags,\n workflowResource,\n effectHandlers,\n missingHandler,\n logger,\n deployDefinitions: (rest) => workflow.deployDefinitions(bind<DeployDefinitionsArgs>(rest)),\n startInstance: (rest) => workflow.startInstance(bind<StartInstanceArgs>(rest)),\n fireAction: (rest) => workflow.fireAction(bind<FireActionArgs>(rest)),\n completeEffect: (rest) => workflow.completeEffect(bind<CompleteEffectArgs>(rest)),\n tick: (rest) => workflow.tick(bind<OperationArgs>(rest)),\n evaluateInstance: (rest) => evaluateInstance(bind<EvaluateArgs>(rest)),\n\n setStage: (rest) => workflow.setStage(bind<SetStageArgs>(rest)),\n abortInstance: (rest) => workflow.abortInstance(bind<AbortInstanceArgs>(rest)),\n getInstance: ({instanceId}) =>\n workflow.getInstance({client, tags, workflowResource, instanceId}),\n subscriptionDocumentsForInstance: ({instanceId}) =>\n workflow\n .getInstance({client, tags, workflowResource, instanceId})\n .then(subscriptionDocumentsForInstance),\n instance: (instanceDoc, opts) =>\n createInstanceSession({\n client,\n tags,\n instance: instanceDoc,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n ...(clock !== undefined ? {clock} : {}),\n ...(opts?.access !== undefined ? {access: opts.access} : {}),\n ...(opts?.grantsFromPath !== undefined ? {grantsFromPath: opts.grantsFromPath} : {}),\n }),\n guardsForInstance: ({instanceId}) =>\n workflow.guardsForInstance({\n client,\n tags,\n workflowResource,\n instanceId,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n }),\n guardsForDefinition: ({definition}) =>\n workflow.guardsForDefinition({\n client,\n tags,\n workflowResource,\n definition,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n }),\n children: ({instanceId, task}) =>\n workflow.children({\n client,\n tags,\n workflowResource,\n instanceId,\n ...(task !== undefined ? {task} : {}),\n }),\n query: ({groq, params}) =>\n workflow.query({\n client,\n tags,\n workflowResource,\n groq,\n ...(params !== undefined ? {params} : {}),\n }),\n queryInScope: ({instanceId, groq, params}) =>\n workflow.queryInScope({\n client,\n tags,\n workflowResource,\n instanceId,\n groq,\n ...(params !== undefined ? {params} : {}),\n ...(clock !== undefined ? {clock} : {}),\n }),\n listPendingEffects: ({instanceId}) =>\n workflow.listPendingEffects({client, tags, workflowResource, instanceId}),\n findPendingEffects: ({instanceId, claimed, names}) =>\n workflow.findPendingEffects({\n client,\n tags,\n workflowResource,\n instanceId,\n ...(claimed !== undefined ? {claimed} : {}),\n ...(names !== undefined ? {names} : {}),\n }),\n drainEffects: ({instanceId, access}) =>\n drainEffectsInternal({\n client,\n tags,\n workflowResource,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n instanceId,\n effectHandlers,\n missingHandler,\n logger,\n ...(access !== undefined ? {access} : {}),\n }),\n verifyDeployedDefinitions: () =>\n verifyDeployedDefinitionsInternal({\n client,\n tags,\n effectHandlers,\n missingHandler,\n logger,\n }),\n }\n}\n","/**\n * Display metadata for the discriminator literals the engine persists\n * (history entries, state-entry kinds, ops, effects-context entry\n * kinds, document and effect-queue types). Each entry exposes\n *\n * - `title` — short label for chips, badges, headings\n * - `description` — longer prose for tooltips / inspector panes\n *\n * UIs that render an instance audit log should NEVER show\n * `transitionFired` raw — they look it up here and\n * render `\"Transition fired\"` instead.\n *\n * Each family map is checked (`satisfies`) against the canonical union\n * for that family, so adding or removing a discriminator in the engine\n * fails tsc here until the display entry follows.\n */\n\nimport {WORKFLOW_DEFINITION_TYPE, type Op} from './define/schema.ts'\nimport type {EffectsContextEntry, PendingEffect, PendingEffectClaim} from './types/effects.ts'\nimport type {HistoryEntry} from './types/history.ts'\nimport {WORKFLOW_INSTANCE_TYPE} from './types/instance.ts'\nimport type {StateKind} from './types/state-values.ts'\n\nexport interface DisplayMetadata {\n readonly title: string\n readonly description: string\n}\n\n/**\n * History-entry `_type` discriminators. Order roughly matches the\n * order a typical run produces them in a single fire-action commit.\n */\nexport const HISTORY_DISPLAY = {\n stageEntered: {\n title: 'Stage entered',\n description: 'The instance crossed into a new stage.',\n },\n stageExited: {\n title: 'Stage exited',\n description: 'The instance left a stage on the way to the next one.',\n },\n taskActivated: {\n title: 'Task activated',\n description: 'A task flipped from `pending` to `active` and its onEnter effects queued.',\n },\n taskStatusChanged: {\n title: 'Task status changed',\n description: \"An action or op flipped a task's status (active → done / skipped / failed).\",\n },\n actionFired: {\n title: 'Action fired',\n description:\n 'An action was invoked against a task — ops ran, status may have flipped, effects queued.',\n },\n transitionFired: {\n title: 'Transition fired',\n description: 'A transition committed and the instance moved to a new stage.',\n },\n effectQueued: {\n title: 'Effect queued',\n description: 'A pending effect was added to the queue, waiting for a drainer to dispatch it.',\n },\n effectCompleted: {\n title: 'Effect completed',\n description:\n 'A drainer ran an effect handler to completion (done or failed) and merged its outputs into effectsContext.',\n },\n spawned: {\n title: 'Spawned child',\n description: \"A task's `subworkflows` declaration spawned a child workflow instance.\",\n },\n aborted: {\n title: 'Instance aborted',\n description:\n 'An admin hard-stopped the instance — pending effects cancelled, stage guards lifted, abortedAt + completedAt stamped.',\n },\n opApplied: {\n title: 'Op applied',\n description:\n 'An inline state-mutation op (state.set / state.append / status.set / etc.) ran during an action commit.',\n },\n} satisfies Record<HistoryEntry['_type'], DisplayMetadata>\n\n/**\n * State-entry `_type` discriminators. The entry's kind defines what\n * shape `value` takes (single GDR vs array, scalar vs notes log).\n */\nexport const STATE_SLOT_DISPLAY = {\n 'doc.ref': {\n title: 'Document reference',\n description: 'Single GDR pointer at a document in this or another resource.',\n },\n 'doc.refs': {\n title: 'Document references',\n description: 'Ordered list of GDR pointers — multi-doc selection.',\n },\n 'release.ref': {\n title: 'Content Release reference',\n description:\n \"GDR pointer at a Content Release system doc, carrying the release name the engine derives the instance's read perspective from.\",\n },\n query: {\n title: 'Query result',\n description:\n 'Snapshot of a GROQ projection captured at entry-resolve time; resolvedAt is stamped on the value.',\n },\n 'value.string': {\n title: 'String value',\n description: 'Free-form string entry.',\n },\n 'value.url': {\n title: 'URL value',\n description: 'Validated URL entry.',\n },\n 'value.number': {\n title: 'Number value',\n description: 'Numeric entry.',\n },\n 'value.boolean': {\n title: 'Boolean value',\n description: 'True/false entry.',\n },\n 'value.dateTime': {\n title: 'Date / time value',\n description: 'ISO-timestamp entry.',\n },\n 'value.actor': {\n title: 'Actor value',\n description: 'A typed (user|ai|system) actor identity.',\n },\n checklist: {\n title: 'Checklist',\n description: 'Append-only list of checkable items; ops add/update/remove entries.',\n },\n notes: {\n title: 'Notes log',\n description: 'Append-only structured-note log (signoffs, comments, audit rows).',\n },\n assignees: {\n title: 'Assignees',\n description: 'Ordered list of typed (user|role) assignees.',\n },\n} satisfies Record<StateKind, DisplayMetadata>\n\n/**\n * Op `type` discriminators — the stored mutation primitives.\n */\nexport const OP_DISPLAY = {\n 'state.set': {\n title: 'Set state entry',\n description: \"Overwrite a state entry's value with a resolved Source.\",\n },\n 'state.unset': {\n title: 'Unset state entry',\n description: 'Reset a state entry to its default (null for scalars, [] for array kinds).',\n },\n 'state.append': {\n title: 'Append to state entry',\n description:\n 'Push a resolved item onto an array-kind entry (notes, checklist, assignees, refs).',\n },\n 'state.updateWhere': {\n title: 'Update matching rows',\n description: 'Merge fields into rows of an array-kind entry that match the predicate.',\n },\n 'state.removeWhere': {\n title: 'Remove matching rows',\n description: 'Drop rows of an array-kind entry that match the predicate.',\n },\n 'status.set': {\n title: 'Set task status',\n description:\n \"Flip a task's status explicitly (the action-level `status:` sugar desugars to this).\",\n },\n} satisfies Record<Op['type'], DisplayMetadata>\n\n/**\n * EffectsContext entry kinds.\n */\nexport const EFFECTS_CONTEXT_DISPLAY = {\n 'effectsContext.string': {\n title: 'String',\n description: 'Stable string parameter for effect handlers.',\n },\n 'effectsContext.number': {\n title: 'Number',\n description: 'Stable numeric parameter for effect handlers.',\n },\n 'effectsContext.boolean': {\n title: 'Boolean',\n description: 'Stable boolean parameter for effect handlers.',\n },\n 'effectsContext.ref': {\n title: 'GDR reference',\n description: 'Stable GDR pointer parameter for effect handlers.',\n },\n 'effectsContext.json': {\n title: 'JSON',\n description: 'Stable JSON payload for effect handlers.',\n },\n} satisfies Record<EffectsContextEntry['_type'], DisplayMetadata>\n\n/**\n * Persisted document and effect-queue `_type` discriminators.\n */\nexport const AUTHORING_DISPLAY = {\n pendingEffect: {\n title: 'Pending effect',\n description: 'An effect that has been queued but not yet dispatched.',\n },\n 'pendingEffect.claim': {\n title: 'Claim',\n description: \"A drainer's lock on a pending effect while it dispatches.\",\n },\n [WORKFLOW_DEFINITION_TYPE]: {\n title: 'Workflow definition',\n description: 'An immutable workflow blueprint, addressed by `name` + `version`.',\n },\n [WORKFLOW_INSTANCE_TYPE]: {\n title: 'Workflow instance',\n description: 'A running (or finished) workflow against its declared state.',\n },\n} satisfies Record<\n | NonNullable<PendingEffect['_type']>\n | PendingEffectClaim['_type']\n | typeof WORKFLOW_DEFINITION_TYPE\n | typeof WORKFLOW_INSTANCE_TYPE,\n DisplayMetadata\n>\n\n/**\n * Single combined map for callers that don't care which family the\n * key belongs to (e.g. an audit row showing any `_type`).\n */\nexport const DISPLAY: Record<string, DisplayMetadata> = {\n ...HISTORY_DISPLAY,\n ...STATE_SLOT_DISPLAY,\n ...OP_DISPLAY,\n ...EFFECTS_CONTEXT_DISPLAY,\n ...AUTHORING_DISPLAY,\n}\n\n/**\n * Lookup helper. Returns a friendly title for any known `_type`, or\n * the original key when unknown so UIs degrade gracefully.\n */\nexport function displayTitle(typeKey: string | undefined): string {\n if (!typeKey) return ''\n return DISPLAY[typeKey]?.title ?? typeKey\n}\n\n/**\n * Same idea but returns the description, or undefined when unknown.\n */\nexport function displayDescription(typeKey: string | undefined): string | undefined {\n if (!typeKey) return undefined\n return DISPLAY[typeKey]?.description\n}\n"],"names":["v","parseGroq","currentTasks","gdrUri","doc","randomKey","engineInvokeTask","engineFireAction","engineCompleteEffect","engineSetStage","engineAbortInstance","queryGuardsForInstance","queryGuardsForDefinition","evaluateGroq"],"mappings":"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"}
|