@sanity/workflow-engine 0.7.0 → 0.9.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/core/path.ts","../src/core/refs.ts","../src/guard-bindings.ts","../src/api/validate.ts","../src/available-actions.ts","../src/clock.ts","../src/types/authorization.ts","../src/core/guards.ts","../src/types/instance-state.ts","../src/core/params.ts","../src/diagnostics.ts","../src/core/snapshot.ts","../src/types/instance.ts","../src/subscription-documents.ts","../src/snapshot.ts","../src/guards-query.ts","../src/types/client.ts","../src/guards-lifecycle.ts","../src/keys.ts","../src/core/eval.ts","../src/core/state-validation.ts","../src/state-resolution.ts","../src/engine/context.ts","../src/engine/results.ts","../src/engine/guard-commit.ts","../src/engine/history-entries.ts","../src/engine/mutation.ts","../src/tags.ts","../src/definition-query.ts","../src/discover.ts","../src/instance.ts","../src/engine/spawn.ts","../src/core/bindings.ts","../src/engine/effects.ts","../src/core/source.ts","../src/engine/ops.ts","../src/engine/tasks.ts","../src/engine/stages.ts","../src/engine/cascade.ts","../src/permissions.ts","../src/access.ts","../src/evaluate.ts","../src/api/deploy.ts","../src/engine/abort.ts","../src/engine/actions.ts","../src/types/evaluation.ts","../src/api/operations.ts","../src/api/delete-definition.ts","../src/api/workflow.ts","../src/api/drain.ts","../src/api/instance-session.ts","../src/api/engine-factory.ts","../src/definition-diff.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 {@link WorkflowResource} a GDR URI addresses — the inverse of\n * {@link gdrFromResource}, dropping the document-id tail. Returns\n * `undefined` for a non-GDR string so callers can treat \"unparseable\"\n * as \"no resource\" rather than handling a throw.\n */\nexport function resourceFromGdrUri(uri: string): WorkflowResource | undefined {\n let parsed: ParsedGdr\n try {\n parsed = parseGdr(uri)\n } catch {\n return undefined\n }\n // The `undefined` guards narrow the cross-scheme-optional `ParsedGdr`\n // fields; `parseGdr` already guarantees them per scheme, so they don't\n // fire in practice — they keep the function total without a cast.\n if (parsed.scheme === 'dataset') {\n if (parsed.projectId === undefined || parsed.dataset === undefined) return undefined\n return {type: 'dataset', id: `${parsed.projectId}.${parsed.dataset}`}\n }\n if (parsed.resourceId === undefined) return undefined\n return {type: parsed.scheme, id: parsed.resourceId}\n}\n\n/** Whether two workflow resources address the same place. */\nexport function sameResource(a: WorkflowResource, b: WorkflowResource): boolean {\n return a.type === b.type && a.id === b.id\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 [name, groq] of Object.entries(task.requirements ?? {})) {\n v.checkCondition(groq, `${where}.requirements \"${name}\"`)\n }\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","// Available-actions projection — flatten an instance's current-stage tasks\n// into the actions an actor could fire, each carrying whether it's allowed\n// (and the structured reason when not). Pure reasoning over a\n// `WorkflowEvaluation`; consumers (CLI list mode, MCP, a UI) render it\n// their own way. The `workflow.availableActions` verb composes `evaluate`\n// with this so a consumer can ask \"what can I fire on this instance\" by id.\n\nimport type {ActionParam} from './define/schema.ts'\nimport type {TaskStatus} from './types/enums.ts'\nimport type {\n ActionEvaluation,\n DisabledReason,\n TaskEvaluation,\n WorkflowEvaluation,\n} from './types/evaluation.ts'\n\nexport interface AvailableAction {\n task: string\n taskStatus: TaskStatus\n action: string\n title: string | undefined\n allowed: boolean\n disabledReason: DisabledReason | undefined\n params: ActionParam[]\n}\n\n/** The `workflow.availableActions` result — the projected actions plus the\n * evaluation they came from, so a consumer can read the instance/stage\n * context without a second projection. */\nexport interface AvailableActionsResult {\n evaluation: WorkflowEvaluation\n actions: AvailableAction[]\n}\n\n/** The fireable-action verdict for one action on a task — its `allowed`\n * state, structured `disabledReason`, and declared params, tagged with the\n * owning task. The per-action atom both projections share:\n * {@link availableActions} flattens it across a stage's tasks; a consumer\n * that keeps per-task nesting (e.g. the MCP) maps it over a task's actions\n * directly, so the verdict shape has a single source. */\nexport function actionVerdict(task: TaskEvaluation, action: ActionEvaluation): AvailableAction {\n return {\n task: task.task.name,\n taskStatus: task.status,\n action: action.action.name,\n title: action.action.title,\n allowed: action.allowed,\n disabledReason: action.disabledReason,\n params: action.action.params ?? [],\n }\n}\n\n/** Flatten an evaluation's current-stage tasks into the actions the actor\n * could fire, each carrying whether it's allowed (and why not). */\nexport function availableActions(tasks: TaskEvaluation[]): AvailableAction[] {\n return tasks.flatMap((t) => t.actions.map((a) => actionVerdict(t, a)))\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 /**\n * The filter evaluated to GROQ `null` — a referenced operand was missing\n * or incomparable, so it couldn't be decided. The engine fails closed\n * (keeps the task in scope) rather than reading this as a deliberate\n * `false`; `truthy` is `false` here but the task is NOT skipped.\n */\n unevaluable?: 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","// Instance diagnostics — classify *why* an instance is or isn't\n// progressing, from the instance doc + its evaluation, and name the\n// structured remediations that would unstick it. Pure reasoning, no\n// rendering: the CLI and MCP each present a `Diagnosis` their own way.\n// The `workflow.diagnose` verb composes `evaluate` + this classifier so\n// a consumer can diagnose by instance id in one call.\n\nimport type {EffectHistoryEntry, PendingEffect} from './types/effects.ts'\nimport type {TaskStatus} from './types/enums.ts'\nimport type {TaskEvaluation, TransitionEvaluation, WorkflowEvaluation} from './types/evaluation.ts'\nimport type {HistoryEntry} from './types/history.ts'\nimport {findOpenStageEntry, type StageEntry} from './types/instance-state.ts'\nimport type {WorkflowInstance} from './types/instance.ts'\nimport type {Assignee, ResolvedStateEntry} from './types/state-values.ts'\n\n/**\n * Why an in-flight instance is genuinely blocked — nothing advances it on its\n * own OR via a normal action. Ordered most- to least-actionable in\n * {@link diagnoseInstance}: a failed effect is the root cause even when it left\n * its task looking merely \"active\", so it wins over the task- and\n * transition-level symptoms it produces. Note an active task awaiting a human\n * action is NOT here — that's the healthy {@link Diagnosis} `waiting` state.\n */\nexport type StuckCause =\n | {kind: 'failed-effect'; effect: EffectHistoryEntry}\n | {kind: 'hung-effect'; effect: PendingEffect}\n | {kind: 'failed-task'; task: string}\n | {kind: 'no-transition-fires'}\n /**\n * Every task resolved, but an exit transition's filter is *unevaluable*\n * (GROQ `null` — a referenced operand is missing/unreadable), so selection\n * halts. Unlike {@link StuckCause} `no-transition-fires` this is recoverable:\n * the cascade re-fires once the operand resolves (e.g. the subject is\n * published or the field is filled). Carries the undecidable transitions.\n */\n | {kind: 'transition-unevaluable'; transitions: string[]}\n\nexport type Diagnosis =\n | {state: 'progressing'}\n // Healthy in-flight: an active task has an available action; it advances when\n // someone acts. NOT stuck — we deliberately don't judge how long a given\n // workflow is \"allowed\" to wait, since that's workflow- and team-specific.\n | {state: 'waiting'; task: string; assignees: Assignee[]; actions: string[]}\n // Healthy in-flight, but not yet actionable: an active task whose declared\n // requirements aren't all met — the readiness axis. It flips to `waiting`\n // once the preconditions hold (typically when a sibling task completes or\n // content lands). NOT stuck: \"visible but not yet executable\" is an expected,\n // transient state, and only surfaces when nothing else is actionable.\n | {state: 'blocked'; task: string; requirements: string[]; assignees: Assignee[]}\n | {state: 'completed'; at: string}\n | {state: 'aborted'; at: string; reason?: string}\n | {state: 'stuck'; cause: StuckCause}\n\n/**\n * A verb that would unstick a {@link StuckCause} — the *what to do about it*\n * half of a diagnosis. Surface-neutral identifiers; a consumer maps each to\n * its own command or button. `retry-effect`, `drain-effects` and `reset-task`\n * are not yet callable engine operations — see {@link SuggestedRemediation.available}.\n */\nexport type RemediationVerb =\n | 'retry-effect'\n | 'drain-effects'\n | 'reset-task'\n | 'set-stage'\n | 'abort'\n\nexport interface SuggestedRemediation {\n verb: RemediationVerb\n /** True iff a consumer can run this as an engine operation today. `false`\n * marks a remediation we can name but not yet execute — a planned verb, or\n * an operational step (re-running the effect drainer). */\n available: boolean\n /** Surface-neutral one-line rationale — no color or terminal symbols; a\n * consumer decorates it for its own surface. */\n rationale: string\n}\n\n/**\n * The slice of an instance + its {@link WorkflowEvaluation} the classifier\n * reads. Narrowed so callers (and tests) can craft an exact stuck permutation\n * without standing up a full evaluation; {@link diagnoseInputFromEvaluation}\n * builds it from a real {@link WorkflowEvaluation}.\n */\nexport interface DiagnoseInput {\n instance: Pick<\n WorkflowInstance,\n 'currentStage' | 'completedAt' | 'abortedAt' | 'effectHistory' | 'pendingEffects' | 'history'\n >\n tasks: TaskEvaluation[]\n transitions: TransitionEvaluation[]\n assignees: Record<string, Assignee[]>\n}\n\n/** The `workflow.diagnose` result — the verdict, the structured remediations\n * that would unstick it (empty unless `stuck`), and the evaluation it was\n * derived from, so a consumer can render the supporting evidence (current\n * stage tasks + transitions) without a second projection. */\nexport interface DiagnoseResult {\n evaluation: WorkflowEvaluation\n diagnosis: Diagnosis\n remediations: SuggestedRemediation[]\n}\n\n/** The free-text reason recorded on the aborted history entry, if any. */\nexport function abortReason(instance: Pick<WorkflowInstance, 'history'>): string | undefined {\n const entry = instance.history.find(\n (h): h is Extract<HistoryEntry, {_type: 'aborted'}> => h._type === 'aborted',\n )\n return entry?.reason\n}\n\n/** Narrow a full {@link WorkflowEvaluation} to the {@link DiagnoseInput} the\n * classifier reads. */\nexport function diagnoseInputFromEvaluation(evaluation: WorkflowEvaluation): DiagnoseInput {\n const stage = openStage(evaluation.instance)\n\n return {\n instance: evaluation.instance,\n tasks: evaluation.currentStage.tasks,\n transitions: evaluation.currentStage.transitions,\n assignees: Object.fromEntries(\n evaluation.currentStage.tasks.map((t) => [t.task.name, assigneesOf(stage, t.task.name)]),\n ),\n }\n}\n\n/** The instance's current, not-yet-exited {@link StageEntry}, if it has one —\n * the engine's canonical {@link findOpenStageEntry}, over the diagnosis input. */\nfunction openStage(\n instance: Pick<WorkflowInstance, 'currentStage' | 'stages'>,\n): StageEntry | undefined {\n return findOpenStageEntry(instance)\n}\n\n/** The assignees recorded for a task in a stage — the runtime half of the\n * \"who is this waiting on\" answer. Empty when the task is unassigned. */\nfunction assigneesOf(stage: StageEntry | undefined, taskName: string): Assignee[] {\n const entry = stage?.tasks.find((t) => t.name === taskName)\n return (entry?.state ?? [])\n .filter((s): s is Extract<ResolvedStateEntry, {_type: 'assignees'}> => s._type === 'assignees')\n .flatMap((s) => s.value)\n}\n\n/** A task that has resolved one way or another — done or skipped. */\nfunction isResolved(status: TaskStatus): boolean {\n return status === 'done' || status === 'skipped'\n}\n\n/**\n * A failed effect whose origin task is still unresolved in the current\n * stage. The origin link is what makes it the blocker (not just any old\n * failure in history): the task that queued it can't complete until the\n * effect succeeds, so the stage can't advance.\n */\nfunction failedEffectCause(input: DiagnoseInput): StuckCause | undefined {\n const stalled = new Set(input.tasks.filter((t) => !isResolved(t.status)).map((t) => t.task.name))\n const effect = [...input.instance.effectHistory]\n .reverse()\n .find((e) => e.status === 'failed' && e.origin.kind === 'task' && stalled.has(e.origin.name))\n return effect ? {kind: 'failed-effect', effect} : undefined\n}\n\n/** A pending effect a drainer claimed but never reported back on — the\n * drainer died mid-dispatch, so the entry will never drain on its own. */\nfunction hungEffectCause(input: DiagnoseInput): StuckCause | undefined {\n const effect = input.instance.pendingEffects.find((e) => e.claim !== undefined)\n return effect ? {kind: 'hung-effect', effect} : undefined\n}\n\nfunction failedTaskCause(input: DiagnoseInput): StuckCause | undefined {\n const failed = input.tasks.find((t) => t.status === 'failed')\n return failed ? {kind: 'failed-task', task: failed.task.name} : undefined\n}\n\n/** An active task with an available action — the instance advances as soon as\n * someone acts on it. Healthy, not stuck; we don't judge how long that wait\n * is \"allowed\" to be. */\nfunction waitingState(input: DiagnoseInput): Extract<Diagnosis, {state: 'waiting'}> | undefined {\n // A task held by an unmet requirement isn't \"waiting on a human to act\" — no\n // action can fire yet. Skip it here so a genuinely actionable sibling wins;\n // {@link blockedState} reports the readiness hold when nothing is actionable.\n const active = input.tasks.find(\n (t) =>\n t.status === 'active' &&\n (t.task.actions ?? []).length > 0 &&\n (t.unmetRequirements ?? []).length === 0,\n )\n\n if (active === undefined) {\n return undefined\n }\n\n return {\n state: 'waiting',\n task: active.task.name,\n assignees: input.assignees[active.task.name] ?? [],\n actions: (active.task.actions ?? []).map((a) => a.name),\n }\n}\n\n/** An active task held by the readiness axis — its declared requirements\n * aren't all met, so none of its actions can fire yet. Requires the task to\n * HAVE actions (readiness gates executability — a no-action machine step has\n * nothing to block). Reported only after {@link waitingState}, so it never\n * masks an actionable task elsewhere; the hold is not a stuck cause. */\nfunction blockedState(input: DiagnoseInput): Extract<Diagnosis, {state: 'blocked'}> | undefined {\n const blocked = input.tasks.find(\n (t) =>\n t.status === 'active' &&\n (t.task.actions ?? []).length > 0 &&\n (t.unmetRequirements ?? []).length > 0,\n )\n if (blocked === undefined) {\n return undefined\n }\n return {\n state: 'blocked',\n task: blocked.task.name,\n requirements: blocked.unmetRequirements ?? [],\n assignees: input.assignees[blocked.task.name] ?? [],\n }\n}\n\n/**\n * Every task resolved, exits declared, but none fires. Two distinct causes:\n * an *unevaluable* filter (GROQ `null` — a missing/unreadable operand) is a\n * recoverable hold the cascade re-fires once the operand resolves; otherwise\n * every filter is a definite `false` — a routing dead-end (a state value a\n * filter reads never got written).\n */\nfunction noTransitionFiresCause(input: DiagnoseInput): StuckCause | undefined {\n if (input.transitions.length === 0) {\n return undefined\n }\n\n if (input.transitions.some((t) => t.filterSatisfied)) {\n return undefined\n }\n\n if (!input.tasks.every((t) => isResolved(t.status))) {\n return undefined\n }\n\n const undecidable = input.transitions.filter((t) => t.unevaluable)\n if (undecidable.length > 0) {\n return {kind: 'transition-unevaluable', transitions: undecidable.map((t) => t.transition.name)}\n }\n\n return {kind: 'no-transition-fires'}\n}\n\n/**\n * Classify an instance. Terminal states win first; then the genuine stuck\n * causes (nothing advances on its own or via a normal action); then `waiting`\n * (an action is available — healthy); then `blocked` (an active task held by\n * an unmet requirement — healthy, not yet actionable); else `progressing` (a\n * transition is already satisfied and will cascade).\n */\nexport function diagnoseInstance(input: DiagnoseInput): Diagnosis {\n const {instance} = input\n\n if (instance.abortedAt !== undefined) {\n const reason = abortReason(instance)\n\n return {state: 'aborted', at: instance.abortedAt, ...(reason !== undefined ? {reason} : {})}\n }\n\n if (instance.completedAt !== undefined) {\n return {state: 'completed', at: instance.completedAt}\n }\n\n const cause =\n failedEffectCause(input) ??\n failedTaskCause(input) ??\n hungEffectCause(input) ??\n noTransitionFiresCause(input)\n\n if (cause !== undefined) {\n return {state: 'stuck', cause}\n }\n\n return waitingState(input) ?? blockedState(input) ?? {state: 'progressing'}\n}\n\n/** The remediation verbs a consumer can actually run as an engine operation\n * today. Everything else a diagnosis names (`retry-effect`, `reset-task`, the\n * effect drainer) is describable but not yet callable — add a verb here when\n * it ships, and {@link remediationsFor} flips it to `available`. */\nconst RUNNABLE_VERBS = new Set<RemediationVerb>(['set-stage', 'abort'])\n\ntype RemediationSeed = Omit<SuggestedRemediation, 'available'>\n\nfunction remediationsForCause(cause: StuckCause): RemediationSeed[] {\n switch (cause.kind) {\n case 'failed-effect':\n return [\n {\n verb: 'retry-effect',\n rationale: 'Re-run the failed effect once the upstream system is healthy.',\n },\n {verb: 'abort', rationale: 'Abort the instance if it can no longer recover.'},\n ]\n case 'hung-effect':\n return [\n {\n verb: 'drain-effects',\n rationale: 'Re-run the effect drainer to re-pick the claimed effect.',\n },\n {verb: 'abort', rationale: 'Abort the instance if the effect never drains.'},\n ]\n case 'failed-task':\n return [\n {verb: 'reset-task', rationale: 'Reset or skip the failed task.'},\n {\n verb: 'set-stage',\n rationale: 'Move the instance past the failed task to the intended next stage.',\n },\n ]\n case 'no-transition-fires':\n return [\n {\n verb: 'set-stage',\n rationale: 'Move the instance to the intended next stage to force it forward.',\n },\n ]\n case 'transition-unevaluable':\n // Recoverable hold: the filter advances on its own once the operand\n // becomes readable. No engine verb unsticks it — forcing `set-stage`\n // would skip the gate the unevaluable filter exists to hold.\n return []\n }\n}\n\n/**\n * The remediations that would unstick a diagnosis — the *what to do about it*\n * half. Empty unless the instance is `stuck`: a `waiting` instance advances on\n * its own next action (see `availableActions`), and terminal or `progressing`\n * ones need nothing. Each verb is flagged\n * {@link SuggestedRemediation.available} from {@link RUNNABLE_VERBS}.\n */\nexport function remediationsFor(diagnosis: Diagnosis): SuggestedRemediation[] {\n if (diagnosis.state !== 'stuck') {\n return []\n }\n\n return remediationsForCause(diagnosis.cause).map((seed) => ({\n ...seed,\n available: RUNNABLE_VERBS.has(seed.verb),\n }))\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 environment partition stamped on the instance at create\n * time. Reads are scoped to a single tag, so an engine only sees\n * instances whose `tag` equals its own.\n */\n tag: 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 perspective a content read falls back to when the instance has no\n * explicit release perspective: `drafts` overlay published (Sanity\n * draft-precedence), so an unpublished or in-flight subject is what the engine\n * — and the reactive adapters — evaluate, never a published-only read that\n * silently misses the draft. The single home for the draft-precedence default;\n * every content read uses `instance.perspective ?? DEFAULT_CONTENT_PERSPECTIVE`.\n */\nexport const DEFAULT_CONTENT_PERSPECTIVE = 'drafts' satisfies WorkflowPerspective\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 * Pull the single-subject {@link GlobalDocumentReference} values out of\n * state entries — `doc.ref` and `release.ref` — in declaration order.\n * Unlike {@link entryDocRefs} this skips `doc.refs` (a collection has no\n * one \"subject\") and keeps the two kinds interleaved by position, so a\n * caller wanting the subject the author declared first reads index 0.\n * Used to route spawn discovery to the resource its subject lives in.\n */\nexport function entrySubjectRefs(state: unknown): GlobalDocumentReference[] {\n return stateEntries(state).flatMap((entry) =>\n (entry._type === 'doc.ref' || entry._type === 'release.ref') && isGdr(entry.value)\n ? [entry.value]\n : [],\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. With no release perspective they default to\n * `drafts` (drafts overlay published) rather than published-only, so an\n * unpublished or in-flight subject is still what filters evaluate. The\n * instance, ancestors (both instance documents), and `release.ref` system\n * docs are always read RAW — per the engine contract, and because a release\n * perspective doesn't version those. The raw-vs-content split ({@link readsRaw})\n * is shared with the reactive WatchSet contract; the `drafts` default is\n * applied on this fetch side.\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 {\n collectWatchRefs,\n DEFAULT_CONTENT_PERSPECTIVE,\n entryDocRefs,\n readsRaw,\n} 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 (uri: string, perspective: WorkflowPerspective): 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, defaulting to a\n // drafts-preferring read when the instance has no release perspective:\n // drafts overlay published (Sanity draft-precedence), so the version an\n // editor is actively drafting is what filters evaluate — not a stale or\n // entirely absent published doc (a draft-only subject would otherwise read\n // as missing and silently skip every threshold gate). Instance / ancestor /\n // release docs read RAW (see {@link readsRaw} — the one home for that rule,\n // shared with the WatchSet contract the reactive consumer follows).\n for (const ref of collectWatchRefs(instance)) {\n await loadInto(\n ref.id,\n readsRaw(ref) ? 'raw' : (instance.perspective ?? DEFAULT_CONTENT_PERSPECTIVE),\n )\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,\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 under a read perspective. `raw` is a strongly-consistent\n * point read (`getDocument`), used for the engine's own metadata — instance /\n * ancestor / release docs, which are unversioned and live at their bare id.\n * Any other perspective — a drafts-preferring read, or a release stack like\n * `[releaseName]` — goes through `fetch(..., {perspective})` so draft/version\n * content is projected onto the published id and a content doc that exists\n * only as a draft (or only inside a release) is still visible to filters.\n * Mirrors how state-entry query resolution already reads under perspective.\n * The caller decides which reads are raw vs perspective-scoped — see\n * {@link readsRaw}.\n */\nasync function readDoc(\n client: WorkflowClient,\n id: string,\n perspective: WorkflowPerspective,\n): Promise<SanityDocument | null> {\n if (perspective === 'raw') {\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 * 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 perClient = await guardsForDefinitionByClient(args)\n return dedupById(perClient.flatMap((entry) => entry.guards))\n}\n\n/**\n * {@link guardsForDefinition}, but grouped by the resource client each guard\n * doc lives in — for housekeeping that must WRITE against the owning resource\n * (e.g. `deleteDefinition` removing orphaned guard docs per datasource).\n * Resources are deduped by key before querying, so no guard doc appears under\n * two clients.\n */\nexport async function guardsForDefinitionByClient(\n args: GuardsForDefinitionArgs,\n): Promise<Array<{client: WorkflowClient; guards: 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 const query = `*[_type == $t && sourceDefinition == $definition]`\n const params = {t: GUARD_DOC_TYPE, definition}\n return Promise.all(\n [...clients.values()].map(async (resourceClient) => ({\n client: resourceClient,\n guards: await resourceClient.fetch<MutationGuardDoc[]>(query, params),\n })),\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","// Client surface — narrow interface the engine uses.\n\nimport type {SanityDocument} from '@sanity/types'\n\n/**\n * The subset of `@sanity/client` the engine actually needs. The\n * `@sanity-labs/client-fake-for-test` TestClient is\n * structurally assignable to this, as is the real `@sanity/client`\n * SanityClient.\n */\nexport interface WorkflowMutationOptions {\n /**\n * Optimistic concurrency: only proceed if the target document's\n * current `_rev` matches. On mismatch the underlying client throws.\n * Pass the `_rev` loaded alongside the doc you're about to write back.\n */\n ifRevisionId?: string\n}\n\n/**\n * Perspective layering — see Sanity Content Lake docs. The engine\n * threads this into reads that should reflect a release-stacked view\n * of the dataset (state-entry query resolution, spawn forEach discovery).\n * Engine-internal reads of `workflow.instance` / `workflow.definition`\n * stay raw regardless — those docs are unversioned metadata.\n *\n * Either both the real `@sanity/client` and the fake test client\n * support the same shape. `string[]` is an ordered release-name stack;\n * `\"drafts\"` may appear in the array. `\"published\"` is the implicit\n * tail.\n */\nexport type WorkflowPerspective = 'raw' | 'published' | 'drafts' | string[]\n\nexport interface WorkflowFetchOptions {\n /**\n * Override the client's configured perspective for this read. The\n * engine uses this to scope state-entry query and spawn forEach\n * reads to the instance's `perspective` field.\n */\n perspective?: WorkflowPerspective\n}\n\nexport type WorkflowVisibility = 'sync' | 'async' | 'deferred'\n\nexport interface WorkflowCommitOptions {\n /**\n * When the mutation becomes visible to subsequent queries. The engine\n * reads its own writes back through GROQ (`fetch`) — a freshly-spawned\n * child listed by id, a just-deployed definition — so single-document\n * writes (`create`, `patch().commit()`) commit `'sync'`: the change is\n * query-visible before the call resolves and the next read can't miss it.\n * `@sanity/client` already defaults to `'sync'`, but the engine states it\n * rather than depend on a transport default a consumer's client config\n * could change underneath it. (Transactions ride that same default — see\n * {@link WorkflowTransaction.commit}.)\n */\n visibility?: WorkflowVisibility\n}\n\n/** The engine's standing single-write policy — see {@link WorkflowCommitOptions.visibility}. */\nexport const SYNC_COMMIT: WorkflowCommitOptions = {visibility: 'sync'}\n\nexport interface WorkflowClient {\n fetch: <T = unknown>(\n query: string,\n params?: Record<string, unknown>,\n options?: WorkflowFetchOptions,\n ) => Promise<T>\n getDocument: <T = SanityDocument>(id: string) => Promise<T | null | undefined>\n patch: (documentId: string) => WorkflowPatch\n /**\n * Create a brand-new document. Errors loud (HTTP 409 / mutation\n * error) if a document with the same `_id` already exists. The engine\n * uses this whenever it mints a new doc — instances on\n * `startInstance`, child instances on spawn, new definitions on first\n * deploy.\n *\n * The interface deliberately omits `createOrReplace`: for existing\n * docs the engine uses `patch().set(...).ifRevisionId(rev).commit()`,\n * which fails fast if the doc was deleted or concurrently modified\n * (createOrReplace's behaviour on a missing target is ambiguous and\n * its rev-less form silently clobbers). If a consumer truly needs\n * createOrReplace they can extend their own client type.\n */\n create: <T extends {_id: string; _type: string}>(\n doc: T,\n options?: WorkflowCommitOptions,\n ) => Promise<T>\n /**\n * Build a multi-document transaction. All operations succeed or fail\n * together. Used whenever the engine writes multiple documents that\n * are provably in the same workflow resource (spawn fan-out, deploy\n * batches, parent + child propagation that stays in one dataset).\n *\n * Shape matches `@sanity/client.transaction()` and the in-memory test\n * client. `patch()` accepts a `WorkflowPatch` handle built via\n * `client.patch(id).set(...).ifRevisionId(rev)` — pass the handle in\n * without calling `.commit()` on it.\n */\n transaction: () => WorkflowTransaction\n /**\n * Optional — present on the real `@sanity/client` and on the test\n * fake (from `@sanity-labs/client-fake-for-test@0.2.0`+). Effect\n * handlers use it to dispatch Content Releases and version actions\n * (`sanity.action.release.publish`, `sanity.action.document.version.create`,\n * etc.) without depending on the broader client surface.\n *\n * Typed loosely so both the strict real-client `Action` union and\n * the test fake's discriminated shape satisfy the state entry. Callers\n * (effect handlers) pass the concrete action object literal.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n action?: (action: any, options?: {tag?: string}) => Promise<any>\n /**\n * Optional — present on the real `@sanity/client`, absent on the\n * in-memory test client. The engine probes for it when auto-resolving\n * ACL grants from an endpoint; absence is the package's signal for\n * \"dry-run mode, don't try to fetch real grants.\"\n */\n request?: <T>(opts: {\n /** Raw URL (host + path). One of `url` / `uri` required. */\n url?: string\n /**\n * Project-scoped path resolved against the `@sanity/client`'s\n * apiHost (e.g. `/users/me` → `https://api.sanity.io/v1/users/me`).\n * Use this for global endpoints like `/users/me`. Mirrors\n * `SanityClient.request({uri})` in `@sanity/client`.\n */\n uri?: string\n signal?: AbortSignal\n /** Optional `?tag=` query for observability — supported by `@sanity/client`. */\n tag?: string\n }) => Promise<T>\n}\n\nexport interface WorkflowTransaction {\n /**\n * Queue a `create` mutation. Fails the transaction on `_id` collision,\n * same as `client.create`.\n */\n create: <T extends {_id: string; _type: string}>(doc: T) => WorkflowTransaction\n /**\n * Queue a patch. Expected argument is a `WorkflowPatch` handle built\n * via `client.patch(id).set(…).ifRevisionId(rev)` — pass it without\n * calling `.commit()`.\n *\n * Typed `any` so the test-client's `TransactionHandle.patch(string |\n * PatchHandle, …)` and `@sanity/client`'s `Transaction.patch(Patch |\n * string, …)` both satisfy the state entry under `strictFunctionTypes`. The\n * engine call site always passes a `WorkflowPatch`; both underlying\n * clients drain it structurally.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n patch: (patch: any) => WorkflowTransaction\n /**\n * Queue a document delete. Deliberately a transaction-only capability —\n * the top-level client surface stays delete-free so no engine code path\n * can casually remove documents; the sole consumer is `deleteDefinition`\n * housekeeping (definition docs + orphaned guard docs). Both the real\n * `@sanity/client` Transaction and the test fake's TransactionHandle\n * carry this shape.\n */\n delete: (id: string) => WorkflowTransaction\n /**\n * Commit the batch. No options — a transaction rides the client's *default*\n * `visibility`: `'sync'` in `@sanity/client` (so a post-spawn `listInstances`\n * GROQ sees freshly-created children), immediate in the in-memory test fake.\n * This is a standing engine assumption — a consumer that configured an\n * `async` default would make spawn read-backs racy. Single-document writes\n * state `'sync'` explicitly via {@link WorkflowCommitOptions}; transactions\n * can't (yet) — the test fake's commit options don't carry `visibility`, and\n * per repo convention that gap is closed upstream in the fake, not worked\n * around here.\n */\n commit: () => Promise<unknown>\n}\n\nexport interface WorkflowPatch {\n set: (props: Record<string, unknown>) => WorkflowPatch\n setIfMissing: (props: Record<string, unknown>) => WorkflowPatch\n unset: (paths: string[]) => WorkflowPatch\n ifRevisionId: (rev: string) => WorkflowPatch\n commit: (options?: WorkflowCommitOptions) => Promise<SanityDocument>\n}\n","/**\n * Shell-side lake-guard lifecycle: deploy and retract `temp.system.guard`\n * documents as a workflow enters and exits stages, and delete them outright\n * once the owning definition is gone (see {@link deleteOrphanedDefinitionGuards}).\n * 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: a loop-back re-enters the stage and re-deploys the real\n * predicate, so the doc must survive. POC simplification; orphan accumulation\n * + 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, WorkflowResource} 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 {guardsForDefinitionByClient} from './guards-query.ts'\nimport type {MutationGuardDoc} from './types/authorization.ts'\nimport {SYNC_COMMIT, 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, SYNC_COMMIT)\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(SYNC_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(SYNC_COMMIT)\n }\n}\n\nexport interface DeleteOrphanedGuardsArgs {\n client: WorkflowClient\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient\n workflowResource: WorkflowResource\n /** The version-less definition `name` guard docs key on. */\n definition: string\n /** Every deployed version, to span all the datasources its guards named. */\n definitions: WorkflowDefinition[]\n /** Engine-scope tag — only guards minted under this partition are removed. */\n tag: string\n}\n\n/**\n * Remove a definition's guard docs across every datasource its versions\n * statically named — one transaction per resource client. Call once the LAST\n * version is gone: {@link retractStageGuards} already lifted the live\n * predicates as instances left their stages, this clears the now-unreachable\n * docs themselves.\n *\n * Guard docs key on the version-less `sourceDefinition` name and carry no\n * tag, so a same-named workflow in a different-tag partition sharing a\n * datasource surfaces in the same query. Deleting those would drop another\n * partition's live field-locks, so restrict to guards THIS engine registered:\n * their `sourceInstanceId` is an instance id, minted under our tag prefix.\n * The trailing `.` keeps `prod` from matching a `prod-eu` partition.\n */\nexport async function deleteOrphanedDefinitionGuards(\n args: DeleteOrphanedGuardsArgs,\n): Promise<number> {\n const {client, clientForGdr, workflowResource, definition, definitions, tag} = args\n const perClient = await guardsForDefinitionByClient({\n client,\n clientForGdr,\n workflowResource,\n definition,\n definitions,\n })\n const ownPartitionPrefix = `${tag}.`\n let count = 0\n for (const {client: resourceClient, guards} of perClient) {\n const own = guards.filter((guard) => guard.sourceInstanceId.startsWith(ownPartitionPrefix))\n if (own.length === 0) continue\n const tx = resourceClient.transaction()\n for (const guard of own) tx.delete(guard._id)\n await tx.commit()\n count += own.length\n }\n return count\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 * The three-valued result of a condition. GROQ comparisons/arithmetic/derefs\n * against a missing operand yield `null` — a *third* truth value distinct\n * from `false` (\"I can't decide this\", not \"this is false\"). Coercing that\n * `null` to `false` is fail-OPEN for a skip-gate: a missing dependency would\n * silently satisfy \"skip me\". Modeled as one discriminant rather than a\n * `{satisfied, unevaluable}` pair so the illegal \"satisfied AND unevaluable\"\n * state is unrepresentable; callers gate on `'unevaluable'` and fail closed\n * rather than read `'unsatisfied'` as a deliberate `false`.\n */\nexport type ConditionOutcome = 'satisfied' | 'unsatisfied' | 'unevaluable'\n\n/** GROQ's \"can't decide\" — a comparison/arithmetic/deref against a missing or\n * incomparable operand. Distinct from a value that's merely falsy. */\nfunction isUnevaluable(result: unknown): boolean {\n return result === null || result === undefined\n}\n\n/**\n * Evaluate a condition to its three-valued {@link ConditionOutcome}. An\n * absent condition is vacuously `'satisfied'` (e.g. an ungated action). A GROQ\n * `null`/`undefined` result is `'unevaluable'`, never folded into\n * `'unsatisfied'`.\n */\nexport async function evaluateConditionOutcome(\n args: EvaluateConditionArgs,\n): Promise<ConditionOutcome> {\n const {condition, snapshot, params} = args\n if (condition === undefined) return 'satisfied'\n const result = await runGroq(condition, params, snapshot)\n if (isUnevaluable(result)) return 'unevaluable'\n return result ? 'satisfied' : 'unsatisfied'\n}\n\n/**\n * Boolean view of {@link evaluateConditionOutcome} for sites whose\n * unevaluable direction is already the safe one — an undecidable\n * `completeWhen` shouldn't auto-complete, an undecidable `action.filter`\n * shouldn't enable. Both collapse to `false` here. Skip-gates (`task.filter`,\n * transition routing) must use the outcome form and branch on `'unevaluable'`.\n */\nexport async function evaluateCondition(args: EvaluateConditionArgs): Promise<boolean> {\n return (await evaluateConditionOutcome(args)) === 'satisfied'\n}\n\n/**\n * Pre-evaluate the definition's nullary predicates into the params conditions\n * read as `$<name>`. A predicate can't be a plain param (a param is a value,\n * not an expression) and is never macro-spliced — each body is evaluated\n * against the BUILT-IN scope only and its result bound. GROQ is pure, so for\n * boolean predicates this equals inlining; predicates referencing other\n * predicates are rejected at deploy.\n *\n * An unevaluable predicate binds `null` rather than `false`, so GROQ's own\n * three-valued logic carries the undecidability into any condition that reads\n * `$<name>` — a predicate-wrapped gate fails closed exactly like an inline one.\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 | null>> {\n const out: Record<string, boolean | null> = {}\n for (const [name, groq] of Object.entries(args.predicates ?? {})) {\n const result = await runGroq(groq, args.params, args.snapshot)\n out[name] = isUnevaluable(result) ? null : Boolean(result)\n }\n return out\n}\n\n/**\n * Evaluate a task's named requirements over the rendered scope, returning the\n * names whose condition is falsy — the unmet set. All-of by construction (a\n * met requirement contributes nothing); any-of belongs inside a single\n * condition. Declaration order is preserved so a consumer's \"what's\n * outstanding\" list is stable. No requirements means an empty unmet set.\n */\nexport async function evaluateRequirements(args: {\n requirements: Record<string, string> | undefined\n snapshot: HydratedSnapshot\n params: Record<string, unknown>\n}): Promise<string[]> {\n const unmet: string[] = []\n for (const [name, condition] of Object.entries(args.requirements ?? {})) {\n if (!(await evaluateCondition({condition, snapshot: args.snapshot, params: args.params}))) {\n unmet.push(name)\n }\n }\n return unmet\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 * 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 {DEFAULT_CONTENT_PERSPECTIVE} from './subscription-documents.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 tag: 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 tag: ctx.tag,\n })\n try {\n // Same draft-precedence as doc.ref hydration: with no release the query\n // resolves against drafts overlay published, so a query that resolves the\n // subject (or related content) sees an unpublished/in-flight doc instead\n // of reading published-only and feeding a gate stale/missing data.\n const fetchOptions = {perspective: ctx.perspective ?? DEFAULT_CONTENT_PERSPECTIVE}\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 {type ConditionOutcome, evaluateConditionOutcome, 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 to its three-valued {@link ConditionOutcome} against\n * the context's hydrated snapshot with the full rendered scope bound. An\n * undefined condition is vacuously satisfied — short-circuited before the\n * scope (and its predicates) is assembled. */\nexport async function ctxEvaluateConditionOutcome(\n ctx: EngineContext,\n condition: string | undefined,\n opts?: ConditionScopeOptions,\n): Promise<ConditionOutcome> {\n if (condition === undefined) return 'satisfied'\n return evaluateConditionOutcome({\n condition,\n snapshot: ctx.snapshot,\n params: await ctxConditionParams(ctx, opts),\n })\n}\n\n/** Boolean view of {@link ctxEvaluateConditionOutcome} — for gates whose\n * unevaluable direction is already safe (don't auto-complete, don't enable).\n * Skip-gates that fail OPEN on a coerced `null` (`task.filter`, transition\n * routing) read the outcome form and branch on `unevaluable`. */\nexport async function ctxEvaluateCondition(\n ctx: EngineContext,\n condition: string | undefined,\n opts?: ConditionScopeOptions,\n): Promise<boolean> {\n return (await ctxEvaluateConditionOutcome(ctx, condition, opts)) === 'satisfied'\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 tag: instance.tag,\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 tag: instance.tag,\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","import type {Clock} from '../clock.ts'\nimport type {ParsedGdr} from '../core/refs.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {Grant} from '../types/authorization.ts'\nimport type {WorkflowClient} from '../types/client.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 * Cross-resource routing for this operation, derived from the caller's\n * `resourceClients`. Threaded into {@link loadContext} so guard\n * deploy/retract and snapshot hydration route to the SUBJECT's resource —\n * not the engine's own. Defaults to the engine's `client` when absent.\n * A guard written to (or lifted from) the wrong dataset is a silent no-op,\n * so every guard-touching commit path MUST forward this.\n */\n clientForGdr?: (parsed: ParsedGdr) => WorkflowClient\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 {SYNC_COMMIT, 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(SYNC_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","import type {SanityDocument} from '@sanity/types'\n\nimport type {Stage, Task} from '../define/schema.ts'\nimport type {Actor} from '../types/actor.ts'\nimport {SYNC_COMMIT} from '../types/client.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\n .patch(ctx.instance._id)\n .set(set)\n .ifRevisionId(ctx.instance._rev)\n .commit(SYNC_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","/**\n * Engine-scope tag — the environment partition primitive.\n *\n * Every engine operates against exactly one `tag` (\"test\", \"prod\", …).\n * The tag partitions definitions and instances within a single workflow\n * resource: `deploy(def, tag: \"test\")` and `deploy(def, tag: \"prod\")` are\n * separate deployed workflows with independent lifecycles, and every read\n * is scoped to one tag so test runs never surface in prod.\n *\n * The tag must be Sanity-ID-compatible since it's joined into IDs with\n * `.` — ASCII lowercase + digits + dashes, no leading dash, no dots. It\n * is also the ID prefix for every definition/instance the engine writes.\n *\n * There is no default. The tag selects which environment the engine reads\n * and writes, and the engine enforces nothing — so the partition is the\n * only thing keeping test runs out of prod. Every entry point\n * (`createEngine`, the CLI, the MCP server) requires it explicitly and\n * fails when it's absent rather than guessing an environment.\n */\n\nconst TAG_RE = /^[a-z0-9][a-z0-9-]*$/\n\nexport function validateTag(tag: string): void {\n if (!TAG_RE.test(tag)) {\n throw new Error(\n `tag: invalid tag \"${tag}\" — must match ${TAG_RE.source} (ASCII lowercase + digits + dashes, no leading dash, no dots)`,\n )\n }\n}\n\n/**\n * The engine's read-partition invariant as a GROQ predicate: a document is\n * visible when its `tag` equals the caller's `$tag` param. The single\n * definition of \"tag-scoped\" shared by the engine's internal lookups, the\n * `workflow.query` guard, and the CLI/MCP read helpers.\n */\nexport function tagScopeFilter(): string {\n return 'tag == $tag'\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 tag. With {@link explicit} the query pins `$version`; otherwise\n * it returns the highest deployed version.\n *\n * Params: `$definition`, `$tag`, 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 * subject entry (`doc.ref` or `release.ref`), since discovery scans\n * look for items related 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 {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 {WorkflowClient, 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/**\n * Load an instance by id and assert it is visible to this engine's `tag`.\n * The single definition of instance-visibility: a doc whose `tag` differs\n * from the engine's is a different partition and treated as absent, and a\n * missing doc throws. Every read/operation path funnels through here so the\n * partition contract lives in one place rather than re-inlined per call site.\n */\nexport async function reload(\n client: WorkflowClient,\n instanceId: string,\n tag: string,\n): Promise<WorkflowInstance> {\n const doc = await client.getDocument<WorkflowInstance>(instanceId)\n\n if (!doc) {\n throw new Error(`Workflow instance ${instanceId} not found`)\n }\n\n if (doc.tag !== tag) {\n throw new Error(`Workflow instance ${instanceId} not visible to this engine (tag mismatch)`)\n }\n\n return doc\n}\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 tag: 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 tag: args.tag,\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 {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 resourceFromGdrUri,\n sameResource,\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 {DEFAULT_CONTENT_PERSPECTIVE, entrySubjectRefs} from '../subscription-documents.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, 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.tag)\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, discoveryResource} = 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(\n ctx,\n sub,\n definition,\n parentScope,\n row,\n discoveryResource,\n )\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. Returns the rows plus the\n * `discoveryResource` the scan actually ran against — but only when that\n * was a *foreign* resource (a routed client distinct from the engine's\n * own). {@link projectRowState} uses it to reject `with` projections that\n * would silently mint a child subject in the wrong resource.\n */\nasync function resolveSpawnRows(\n ctx: EngineContext,\n sub: Subworkflows,\n): Promise<{rows: unknown[]; discoveryResource: WorkflowResource | undefined}> {\n const params = buildParams({instance: ctx.instance, now: ctx.now, snapshot: ctx.snapshot})\n const groq = sub.forEach\n\n let value: unknown\n let discoveryResource: WorkflowResource | undefined\n if (groq.includes('*')) {\n // Lake discovery — route through resourceClients in case the GROQ\n // targets a different Sanity resource than the parent. Pick the\n // resource by the first declared subject entry (`doc.ref` or\n // `release.ref`): a release-subject workflow carries only a\n // `release.ref`, whose GDR points at the content resource where the\n // release's version docs live, so discovery must follow it there\n // rather than fall back to the engine's own resource. Authors\n // declaring a different routing target should put that entry first.\n const routingUri = entrySubjectRefs(ctx.instance.state)[0]?.id\n const client = clientForDiscovery(ctx.client, ctx.clientForGdr, routingUri)\n // A routed client (`!== ctx.client`) means the rows came from a\n // foreign resource; an unmapped/absent routing URI falls back to the\n // engine's own client, where bare-id rooting is already correct.\n if (client !== ctx.client && routingUri !== undefined) {\n discoveryResource = resourceFromGdrUri(routingUri)\n }\n value = await discoverItems({\n client,\n groq,\n params,\n // Draft-aware by default (drafts overlay published) when there's no\n // release, so a `forEach` discovers in-flight items the same way the\n // engine reads any other content.\n perspective: ctx.instance.perspective ?? DEFAULT_CONTENT_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 {rows: value, discoveryResource}\n if (value === null || value === undefined) return {rows: [], discoveryResource}\n return {rows: [value], discoveryResource}\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 discoveryResource: WorkflowResource | undefined,\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, {\n parentResource: ctx.instance.workflowResource,\n discoveryResource,\n entryName: name,\n childName: childDefinition.name,\n })\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/** Inputs the spawn-ref coercion needs to root bare ids and to refuse a\n * bare id that would silently land in the wrong resource. */\ninterface SpawnRefContext {\n /** The spawning parent's resource — where a bare id roots. */\n parentResource: WorkflowResource\n /** The foreign resource discovery ran against, if any ({@link resolveSpawnRows}). */\n discoveryResource: WorkflowResource | undefined\n /** The `with` entry + child names, for the fail-loud message. */\n entryName: string\n childName: string\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, and {@link coerceSpawnGdr} fails loud\n * rather than silently rooting a foreign-discovered bare id at the\n * parent. Other kinds pass through unchanged.\n *\n * This is the `with` path only (values projected per discovered `$row`).\n * `subworkflows.context` resolves in the parent scope — its ids are\n * already the parent's canonical GDRs, so the foreign-discovery footgun\n * can't arise there; a non-URI `context` GDR is rejected separately when\n * the child is built ({@link resolveContextHandoff}, {@link prepareChildInstance}).\n */\nfunction canonicaliseSpawnValue(kind: StateKind, value: unknown, cx: SpawnRefContext): unknown {\n if (kind === 'doc.ref') {\n return coerceSpawnGdr(value, cx)\n }\n if (kind === 'doc.refs') {\n if (!Array.isArray(value)) return value\n return value.map((v) => coerceSpawnGdr(v, cx)).filter((v) => v !== null)\n }\n return value\n}\n\n/**\n * A bare spawn id roots at the parent resource. When discovery ran against\n * a different (foreign) resource the row's id belongs *there*, so a\n * parent-rooted GDR would point at a document that doesn't exist — a silent\n * mis-route that spawns children whose own reads find nothing. Fail loud\n * and point the author at the explicit-GDR escape hatch instead.\n */\nfunction assertBareIdRootsCorrectly(id: string, cx: SpawnRefContext): void {\n if (cx.discoveryResource === undefined || sameResource(cx.discoveryResource, cx.parentResource)) {\n return\n }\n throw new Error(\n `subworkflows.with[\"${cx.entryName}\"]: subworkflow \"${cx.childName}\" projected the bare id ` +\n `\"${id}\", which roots at the parent resource \"${cx.parentResource.id}\", but spawn discovery ran ` +\n `against \"${cx.discoveryResource.id}\". The child would reference a document that doesn't exist in ` +\n `the parent resource. Project an explicit GDR URI in the with-GROQ ` +\n `(e.g. \"dataset:<projectId>:<dataset>:\" + _id) so the child's subject points at the resource the ` +\n `discovered rows came from.`,\n )\n}\n\nfunction coerceSpawnGdr(raw: unknown, cx: SpawnRefContext): GlobalDocumentReference | null {\n // Canonicalise a bare doc id into a GDR URI rooted at the parent\n // resource; leave already-canonical URIs untouched. A bare id under\n // foreign discovery is a mis-route — refuse it.\n const toUri = (id: string) => {\n if (isGdrUri(id)) return id\n assertBareIdRootsCorrectly(id, cx)\n return gdrFromResource(cx.parentResource, id)\n }\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 the caller's tag. Picks the highest `version` when\n * 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 tag: string,\n): Promise<(WorkflowDefinition & SanityDocument) | null> {\n const wantsExplicit = typeof ref.version === 'number'\n const params: Record<string, unknown> = {definition: ref.name, tag}\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 tag + workflow resource so it stays\n // visible to whichever engine spawned the parent.\n const childTag = parent.tag\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 = `${childTag}.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 tag: childTag,\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 tag: childTag,\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 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 {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 ...(options?.clientForGdr ? {clientForGdr: options.clientForGdr} : {}),\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","/**\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 type {ConditionOutcome} from '../core/eval.ts'\nimport {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 ctxEvaluateConditionOutcome,\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 ...(options?.clientForGdr ? {clientForGdr: options.clientForGdr} : {}),\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 a definite\n * `false` against the stage's entry state is `skipped` (conditional enter —\n * different tasks for different arrivals); the rest start `pending` until\n * activation.\n *\n * An *unevaluable* filter (GROQ `null` — a referenced operand was missing or\n * incomparable) keeps the task in scope rather than skipping it: \"can't\n * decide this gate\" must never collapse to \"skip this gate\", or a missing\n * dependency silently approves whatever the gate was protecting. The\n * undecidability is recorded on {@link TaskEntry.filterEvaluation} so the\n * audit trail tells \"genuinely below threshold\" apart from \"couldn't read it\".\n */\nexport async function buildStageTasks(ctx: EngineContext, stage: Stage): Promise<TaskEntry[]> {\n const entries: TaskEntry[] = []\n for (const task of stage.tasks ?? []) {\n const outcome = await ctxEvaluateConditionOutcome(ctx, task.filter, {taskName: task.name})\n // Skip only on a definite `false`; an unevaluable gate stays in scope.\n const inScope = outcome !== 'unsatisfied'\n entries.push({\n _key: randomKey(),\n name: task.name,\n status: inScope ? 'pending' : 'skipped',\n ...(task.filter !== undefined\n ? {filterEvaluation: buildFilterEvaluation(ctx.now, task.filter, outcome)}\n : {}),\n })\n }\n return entries\n}\n\n/**\n * The audit record for a task's `filter` evaluation. `truthy` reflects the\n * definite boolean; `unevaluable` flags the GROQ-`null` case the engine fails\n * closed on, with a `detail` naming the gate so an operator can see *why* a\n * task that \"should\" have skipped is sitting in scope.\n */\nfunction buildFilterEvaluation(\n at: string,\n filter: string,\n outcome: ConditionOutcome,\n): NonNullable<TaskEntry['filterEvaluation']> {\n if (outcome === 'unevaluable') {\n return {\n at,\n truthy: false,\n unevaluable: true,\n detail: `Filter \"${filter}\" could not be evaluated (GROQ null — a referenced operand was missing or incomparable). Task kept in scope so the gate is not silently skipped.`,\n }\n }\n return {at, truthy: outcome === 'satisfied'}\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 ctxEvaluateConditionOutcome,\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 ...(options?.clientForGdr ? {clientForGdr: options.clientForGdr} : {}),\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 — every transition is evaluated on every commit and\n * cascade; the first transition whose `filter` is satisfied (in declaration\n * order) fires. A transition is purely a condition over the rendered scope —\n * routing differences are written into state by actions and read here.\n *\n * An *unevaluable* filter (GROQ `null` — a referenced operand was missing or\n * incomparable) halts selection without firing anything. The engine can't\n * decide whether this conditional route applies, so it must not fall through\n * to a later catch-all and advance the instance past an undecidable gate; the\n * cascade re-runs once the operand resolves.\n */\nasync function pickTransition(ctx: EngineContext, stage: Stage): Promise<Transition | undefined> {\n for (const candidate of stage.transitions ?? []) {\n const outcome = await ctxEvaluateConditionOutcome(ctx, candidate.filter)\n if (outcome === 'satisfied') return candidate\n if (outcome === 'unevaluable') return undefined\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 {SYNC_COMMIT, 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(SYNC_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","/**\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 * 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 {\n evaluateCondition,\n evaluateConditionOutcome,\n evaluatePredicates,\n evaluateRequirements,\n} 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 {reload} from './instance.ts'\nimport {grantsPermissionOn} from './permissions.ts'\nimport {hydrateSnapshot} from './snapshot.ts'\nimport {validateTag} 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 environment partition — required. */\n tag: 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, tag, 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 validateTag(tag)\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 reload(client, instanceId, tag)\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 // Three-valued, mirroring the engine: an unevaluable filter is a hold, not\n // a `false` — surfaced so a diagnosis can tell it from a routing dead-end.\n const outcome = await evaluateConditionOutcome({\n condition: transition.filter,\n snapshot,\n params: scope,\n })\n transitionEvaluations.push({\n transition,\n filterSatisfied: outcome === 'satisfied',\n unevaluable: outcome === 'unevaluable',\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 // Readiness is a task-level fact (requirements are declared on the task), so\n // it's evaluated once here and fanned out to every action — the same shape\n // as the shared instance-write guard verdict.\n const unmetRequirements = await evaluateRequirements({\n requirements: task.requirements,\n snapshot,\n params: taskScope,\n })\n const requirementsReason: DisabledReason | undefined =\n unmetRequirements.length > 0 ? {kind: 'requirements-unmet', unmetRequirements} : undefined\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 requirementsReason,\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 ...(unmetRequirements.length > 0 ? {unmetRequirements} : {}),\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 /** Shared task-readiness verdict, precomputed once per task. */\n requirementsReason: DisabledReason | undefined\n}\n\nasync function evaluateAction(args: EvaluateActionArgs): Promise<ActionEvaluation> {\n const {\n action,\n status,\n instance,\n snapshot,\n taskScope,\n stageHasExits,\n guardDenial,\n requirementsReason,\n } = args\n\n // First failing gate wins, ordered most- to least-fundamental: lifecycle\n // (task/instance/stage state), then the guard pre-flight (a denied instance\n // write dooms every action), then task readiness (declared requirements),\n // then the ONE per-action 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 (requirementsReason !== undefined) return disabled(action, requirementsReason)\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 {tagScopeFilter} 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 tag: string,\n definition: string,\n version: number,\n): string {\n return `${tag}.${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 tag: string,\n workflowResource: WorkflowResource,\n): Promise<WorkflowDefinition[]> {\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 tag,\n workflowResource,\n findInBatch,\n })\n\n return topoSortDefinitions(definitions, {workflowResource, tag, findInBatch})\n}\n\nexport interface 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 * tag. Throws listing every unresolved ref. No-op when all resolve.\n */\nasync function assertCrossBatchRefsDeployed(\n client: WorkflowClient,\n definitions: WorkflowDefinition[],\n ctx: {\n tag: string\n workflowResource: WorkflowResource\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.tag, 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.tag)\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 `tag`, or a human-readable label\n * for the unresolved ref otherwise. */\nasync function resolveDeployedRefLabel(\n client: WorkflowClient,\n ref: LogicalRef,\n tag: string,\n): Promise<string | undefined> {\n const wantsExplicit = typeof ref.version === 'number'\n const params: Record<string, unknown> = {definition: ref.name, tag}\n if (wantsExplicit) params.version = ref.version\n const doc = await client.fetch<(SanityDocument & {tag?: 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 tag: 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.tag, 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/**\n * Collect every spawn 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;\n * exported so `deleteDefinition` can run the inverse check (who still\n * references the definition being deleted).\n */\nexport function 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 tag: string,\n): Promise<WorkflowDefinition> {\n if (version !== undefined) {\n const doc = await client.fetch<(WorkflowDefinition & {tag?: string}) | null>(\n definitionLookupGroq(true),\n {definition, version, tag},\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 tag,\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 tag: string,\n): Promise<DeployedDefinition[]> {\n return client.fetch<DeployedDefinition[]>(\n `*[_type == \"${WORKFLOW_DEFINITION_TYPE}\" && name == $definition && ${tagScopeFilter()}] | order(version desc)`,\n {definition, tag},\n )\n}\n\n/** A definition as fetched back from the lake — the document always carries `_id`. */\nexport type DeployedDefinition = WorkflowDefinition & {_id: string}\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 ...(options?.clientForGdr ? {clientForGdr: options.clientForGdr} : {}),\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","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 ...(options?.clientForGdr ? {clientForGdr: options.clientForGdr} : {}),\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 | {\n /**\n * The task's declared {@link Task.requirements} aren't all satisfied —\n * the readiness axis. The task is visible and the actor authorized, but\n * its own preconditions don't hold yet. `unmetRequirements` names the\n * failing keys so a consumer can disable the affirmative control and say\n * which precondition is outstanding. Distinct from `filter-failed`\n * (visibility/authorization) and `mutation-guard-denied` (content-write).\n */\n kind: 'requirements-unmet'\n unmetRequirements: 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 /**\n * The task's unmet {@link Task.requirements}, by name — present iff at least\n * one is unmet. The task's own readiness summary: a consumer can explain why\n * the whole task is gated without inspecting each action (every action also\n * carries the matching `requirements-unmet` `disabledReason`).\n */\n unmetRequirements?: string[]\n actions: ActionEvaluation[]\n}\n\nexport interface TransitionEvaluation {\n transition: Transition\n /** Whether the transition's filter is definitively satisfied at read time. */\n filterSatisfied: boolean\n /**\n * The filter evaluated to GROQ `null` — a referenced operand was missing or\n * incomparable, so it couldn't be decided. `filterSatisfied` is `false`, but\n * this is a *recoverable hold*, not a deliberate `false`: the engine halts\n * selection (it won't fall through to a later transition) and the cascade\n * re-fires once the operand resolves. Lets a diagnosis tell an undecidable\n * hold apart from a genuine routing dead-end.\n */\n unevaluable: 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 'requirements-unmet': (r) => `unmet requirement(s): ${r.unmetRequirements.join(', ')}`,\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 {abortInstance as engineAbortInstance} from '../engine/abort.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 {validateTag} 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 the tag, 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 tag: 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 validateTag(args.tag)\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 * The admin abort primitive pair: hard-stop the instance (see\n * {@link engineAbortInstance} for the full contract), then propagate to\n * ancestors so a parent gate waiting on this child re-evaluates. Returns\n * whether the abort fired — `false` means the instance was already\n * terminal, in which case nothing propagates. The single code path for\n * every aborting verb (`workflow.abortInstance`, `deleteDefinition`'s\n * cascade), so the abort contract can't silently diverge between them.\n */\nexport async function abortAndPropagate(args: {\n client: WorkflowClient\n instanceId: string\n reason: string | undefined\n actor: Actor | undefined\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient\n clock: Clock\n}): Promise<boolean> {\n const {client, instanceId, reason, actor, clientForGdr, clock} = args\n const result = await engineAbortInstance({\n client,\n instanceId,\n ...(reason !== undefined ? {reason} : {}),\n options: {...(actor !== undefined ? {actor} : {}), clock, clientForGdr},\n })\n if (result.fired) {\n await propagateToAncestors(client, instanceId, actor, clientForGdr, clock)\n }\n return result.fired\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 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 clientForGdr?: (parsed: ParsedGdr) => WorkflowClient\n}): Promise<Awaited<ReturnType<typeof engineFireAction>>['ranOps']> {\n const {client, instance, task, action, params, actor, grants, clock, clientForGdr} = args\n const options = {\n actor,\n ...(grants !== undefined ? {grants} : {}),\n ...(clock !== undefined ? {clock} : {}),\n ...(clientForGdr !== undefined ? {clientForGdr} : {}),\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 * `deleteDefinition` — remove a deployed workflow definition from the lake.\n *\n * Definitions are the ONLY thing this operation deletes. Workflow instances\n * are never deleted by any engine code path: with `cascade` the non-terminal\n * instances pinned to the targeted versions are hard-stopped via the same\n * abort primitive as `workflow.abortInstance`, and their documents remain in\n * the lake as the audit record. Without `cascade` the delete refuses while\n * such instances exist.\n *\n * Refuses when a surviving deployed definition — another workflow, or a\n * remaining version of this one — still spawn-references a target\n * (`task.subworkflows.definition`). Deploy validates those refs against the\n * lake, and deleting the target would dangle them. Delete or redeploy the\n * referrer first.\n */\n\nimport {type Clock, type Clocked, wallClock} from '../clock.ts'\nimport type {ParsedGdr} from '../core/refs.ts'\nimport {WORKFLOW_DEFINITION_TYPE} from '../define/schema.ts'\nimport {deleteOrphanedDefinitionGuards} from '../guards-lifecycle.ts'\nimport {tagScopeFilter} from '../tags.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport {WORKFLOW_INSTANCE_TYPE} from '../types/instance.ts'\nimport {type DeployedDefinition, loadDefinitionVersions, refsOf} from './deploy.ts'\nimport {abortAndPropagate, resolveOperationContext} from './operations.ts'\nimport type {DeleteDefinitionArgs, DeleteDefinitionResult} from './types.ts'\n\ntype ClientForGdr = (parsed: ParsedGdr) => WorkflowClient\n\n/**\n * Runs three mutating phases in order with NO rollback between them, so a\n * refused write — an ACL denial on one doc type, a lost optimistic-lock\n * race — leaves a partial result the thrown error does not describe:\n *\n * 1. Abort the cascade's in-flight instances (one write each).\n * 2. Delete the targeted definition docs (one transaction).\n * 3. Once the last version is gone, delete the orphaned guard docs.\n *\n * A throw in phase 1 may leave earlier instances already aborted; a throw\n * in phase 2 leaves every cascade instance aborted while the definition\n * survives; a throw in phase 3 leaves the definition gone but some guard\n * docs behind — inert, since their predicates were already lifted as the\n * instances left their stages. Re-running after any partial failure is\n * safe and converges: already-aborted instances are terminal, so they\n * neither re-block the delete nor abort a second time, and the surviving\n * definition / guard docs are re-targeted cleanly.\n *\n * This widens the documented cross-resource non-atomicity seam into a\n * single verb. Surfacing a post-commit failure as a partial\n * {@link DeleteDefinitionResult} rather than a throw is left to a follow-up.\n */\nexport async function deleteDefinition(\n args: Clocked<DeleteDefinitionArgs>,\n): Promise<DeleteDefinitionResult> {\n const {client, tag, definition, version, cascade, reason} = args\n const {actor, clientForGdr} = await resolveOperationContext(args)\n const clock = args.clock ?? wallClock\n\n const versions = await loadDefinitionVersions(client, definition, tag)\n if (versions.length === 0) {\n throw new Error(`No deployed definition for workflow ${definition}`)\n }\n const targets = version === undefined ? versions : versions.filter((d) => d.version === version)\n if (targets.length === 0) {\n throw new Error(`Workflow definition ${definition} v${version} not deployed`)\n }\n const lastVersionGoes = targets.length === versions.length\n\n await assertNoSpawnReferrers(client, tag, definition, targets, lastVersionGoes)\n\n const instanceIds = await nonTerminalInstanceIds(client, tag, definition, version)\n if (instanceIds.length > 0 && cascade !== true) {\n throw new Error(\n `Cannot delete ${definition}: ${instanceIds.length} non-terminal instance(s) exist ` +\n `(${previewIds(instanceIds)}). Pass cascade to abort them first — ` +\n `instances are aborted in place, never deleted.`,\n )\n }\n const abortedInstanceIds = await abortInstances({\n client,\n instanceIds,\n reason,\n actor,\n clientForGdr,\n clock,\n })\n\n const tx = client.transaction()\n for (const target of targets) tx.delete(target._id)\n await tx.commit()\n\n const deletedGuardCount = lastVersionGoes\n ? await deleteOrphanedDefinitionGuards({\n client,\n clientForGdr,\n workflowResource: args.workflowResource,\n definition,\n definitions: versions,\n tag,\n })\n : 0\n\n return {\n name: definition,\n deletedVersions: targets.map((d) => d.version),\n abortedInstanceIds,\n deletedGuardCount,\n }\n}\n\n/**\n * Refuse while any surviving deployed definition spawn-references a target.\n * Survivors are everything deployed in tag scope minus the targets\n * themselves — including remaining versions of the SAME workflow, whose\n * version-pinned self-refs would dangle just like a foreign ref. A\n * version-pinned ref blocks deleting exactly that version; a version-less\n * (or `latest`) ref resolves to the highest deployed version at spawn time,\n * so it only blocks deleting the LAST version.\n */\nasync function assertNoSpawnReferrers(\n client: WorkflowClient,\n tag: string,\n definition: string,\n targets: DeployedDefinition[],\n lastVersionGoes: boolean,\n): Promise<void> {\n const deployed = await client.fetch<DeployedDefinition[]>(\n `*[_type == \"${WORKFLOW_DEFINITION_TYPE}\" && ${tagScopeFilter()}]`,\n {tag},\n )\n const targetIds = new Set(targets.map((d) => d._id))\n const targetVersions = new Set(targets.map((d) => d.version))\n const referrers = deployed\n .filter((d) => !targetIds.has(d._id))\n .filter((d) =>\n refsOf(d).some(\n (ref) =>\n ref.name === definition &&\n (typeof ref.version === 'number' ? targetVersions.has(ref.version) : lastVersionGoes),\n ),\n )\n if (referrers.length > 0) {\n const names = referrers.map((d) => `${d.name} v${d.version}`).join(', ')\n throw new Error(\n `Cannot delete ${definition}: still spawn-referenced by deployed definition(s) ${names}. ` +\n `Delete or redeploy the referrer(s) first.`,\n )\n }\n}\n\n/** Ids of in-flight instances the delete must abort (or refuse over). */\nasync function nonTerminalInstanceIds(\n client: WorkflowClient,\n tag: string,\n definition: string,\n version: number | undefined,\n): Promise<string[]> {\n const versionFilter = version === undefined ? '' : ' && pinnedVersion == $version'\n const docs = await client.fetch<Array<{_id: string}>>(\n `*[_type == \"${WORKFLOW_INSTANCE_TYPE}\" && definition == $definition && ${tagScopeFilter()} ` +\n `&& !defined(completedAt)${versionFilter}] | order(_id asc){_id}`,\n {definition, tag, ...(version !== undefined ? {version} : {})},\n )\n return docs.map((doc) => doc._id)\n}\n\n/**\n * Hard-stop each instance via the shared {@link abortAndPropagate}\n * primitive pair. A concurrent terminal race returns `false` and is\n * skipped silently — the instance is already where the delete needs it.\n */\nasync function abortInstances(args: {\n client: WorkflowClient\n instanceIds: string[]\n reason: string | undefined\n actor: Actor | undefined\n clientForGdr: ClientForGdr\n clock: Clock\n}): Promise<string[]> {\n const {client, instanceIds, reason, actor, clientForGdr, clock} = args\n const aborted: string[] = []\n for (const instanceId of instanceIds) {\n const fired = await abortAndPropagate({client, instanceId, reason, actor, clientForGdr, clock})\n if (fired) aborted.push(instanceId)\n }\n return aborted\n}\n\nfunction previewIds(ids: string[]): string {\n const head = ids.slice(0, 3).join(', ')\n return ids.length > 3 ? `${head}, …` : head\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 {availableActions, type AvailableActionsResult} from '../available-actions.ts'\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 {\n diagnoseInputFromEvaluation,\n diagnoseInstance,\n remediationsFor,\n type DiagnoseResult,\n} from '../diagnostics.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 {\n guardsForDefinition as queryGuardsForDefinition,\n guardsForInstance as queryGuardsForInstance,\n verdictGuardsForInstance,\n} from '../guards-query.ts'\nimport {buildInstanceBase, reload} 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 {tagScopeFilter, validateTag} from '../tags.ts'\nimport type {MutationGuardDoc} from '../types/authorization.ts'\nimport {SYNC_COMMIT, 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 {deleteDefinition as deleteDefinitionInternal} from './delete-definition.ts'\nimport {\n definitionDocId,\n isDefinitionUnchanged,\n loadDefinition,\n loadDefinitionVersions,\n sortByDependencies,\n} from './deploy.ts'\nimport {\n abortAndPropagate,\n applyAction,\n assertActionAllowed,\n bareIdFromSpawnRef,\n buildClientForGdr,\n cascade,\n resolveOperationContext,\n toEffectsContextEntries,\n} from './operations.ts'\nimport type {\n AbortInstanceArgs,\n CompleteEffectArgs,\n DeleteDefinitionArgs,\n DeleteDefinitionResult,\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, tag, workflowResource, definitions} = args\n validateTag(tag)\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, tag, 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 tx = client.transaction()\n let hasWrites = false\n for (const def of ordered) {\n const id = definitionDocId(workflowResource, tag, def.name, def.version)\n const expected = {\n ...def,\n _id: id,\n _type: WORKFLOW_DEFINITION_TYPE,\n tag,\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 (existing && existing.tag === tag && isDefinitionUnchanged(existing, expected)) {\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 * Remove a deployed workflow definition (all versions, or one via\n * `version`). Refuses while non-terminal instances exist unless\n * `cascade` aborts them first — instances are never deleted, only\n * aborted in place; see {@link deleteDefinitionInternal} for the\n * full contract (spawn-referrer check, guard-doc housekeeping).\n */\n deleteDefinition: async (\n args: Clocked<DeleteDefinitionArgs>,\n ): Promise<DeleteDefinitionResult> => {\n return deleteDefinitionInternal(args)\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 tag,\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, tag)\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 ?? `${tag}.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 tag,\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 tag,\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, SYNC_COMMIT)\n\n await primeInitialStage(client, id, actor, clientForGdr, clock)\n await cascade(client, id, actor, clientForGdr, clock)\n\n return reload(client, id, tag)\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 tag,\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, tag)\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 tag,\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 clientForGdr,\n ...(params !== undefined ? {params} : {}),\n })\n\n const cascaded = await cascade(client, instanceId, actor, clientForGdr, clock)\n return {\n instance: await reload(client, instanceId, tag),\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, tag, 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, clientForGdr},\n })\n const cascaded = await cascade(client, instanceId, actor, clientForGdr, clock)\n return {\n instance: await reload(client, instanceId, tag),\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, tag, instanceId} = args\n const {actor, clientForGdr} = await resolveOperationContext(args)\n const clock = args.clock ?? wallClock\n const current = await reload(client, instanceId, tag)\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, tag),\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, tag, instanceId, targetStage, reason} = args\n const {actor, clientForGdr} = await resolveOperationContext(args)\n const clock = args.clock ?? wallClock\n await reload(client, instanceId, tag)\n const result = await engineSetStage({\n client,\n instanceId,\n targetStage,\n ...(reason !== undefined ? {reason} : {}),\n options: {...(actor !== undefined ? {actor} : {}), clock, clientForGdr},\n })\n const cascaded = result.fired\n ? await cascade(client, instanceId, actor, clientForGdr, clock)\n : 0\n return {\n instance: await reload(client, instanceId, tag),\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;\n * see {@link abortAndPropagate} for the abort + ancestor-propagation\n * contract (propagated, not cascaded — the instance is terminal).\n */\n abortInstance: async (args: Clocked<AbortInstanceArgs>): Promise<DispatchResult> => {\n const {client, tag, instanceId, reason} = args\n const {actor, clientForGdr} = await resolveOperationContext(args)\n const clock = args.clock ?? wallClock\n await reload(client, instanceId, tag)\n const fired = await abortAndPropagate({client, instanceId, reason, actor, clientForGdr, clock})\n return {\n instance: await reload(client, instanceId, tag),\n cascaded: 0,\n fired,\n }\n },\n\n /**\n * Fetch a workflow instance by id, scoped to the engine's tag.\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 tag: string\n workflowResource: WorkflowResource\n instanceId: string\n }): Promise<WorkflowInstance> => {\n const {client, tag, instanceId} = args\n validateTag(tag)\n return reload(client, instanceId, tag)\n },\n\n guardsForInstance: async (args: {\n client: WorkflowClient\n tag: string\n workflowResource: WorkflowResource\n instanceId: string\n resourceClients?: ResourceClientResolver\n }): Promise<MutationGuardDoc[]> => {\n const {client, tag, instanceId, resourceClients} = args\n validateTag(tag)\n const instance = await reload(client, instanceId, tag)\n return queryGuardsForInstance({\n client,\n clientForGdr: buildClientForGdr(client, resourceClients),\n instance,\n })\n },\n\n guardsForDefinition: async (args: {\n client: WorkflowClient\n tag: string\n workflowResource: WorkflowResource\n /** The definition's `name`. */\n definition: string\n resourceClients?: ResourceClientResolver\n }): Promise<MutationGuardDoc[]> => {\n const {client, tag, workflowResource, definition, resourceClients} = args\n validateTag(tag)\n const definitions = await loadDefinitionVersions(client, definition, tag)\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 tag bound as\n * `$tag`. 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 `$tag` (e.g. `tag == $tag`). To guard against accidental\n * cross-partition reads, a query that never references `$tag` 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 tag: string\n workflowResource: WorkflowResource\n groq: string\n params?: Record<string, unknown>\n }): Promise<T> => {\n const {client, tag, groq, params} = args\n validateTag(tag)\n // Whole-token match: a substring check would accept unrelated params\n // like $tags / $tagId / $tagName without ever binding the partition,\n // letting an unscoped query slip past the guard it exists to catch.\n if (!/\\$tag\\b/.test(groq)) {\n throw new Error(\n `workflow.query: query must filter on $tag to stay tag-scoped (e.g. \"tag == $tag\"); got: ${groq}`,\n )\n }\n return client.fetch<T>(groq, {...params, tag})\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 tag: 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, tag, instanceId, groq, params, resourceClients} = args\n const clock = args.clock ?? wallClock\n validateTag(tag)\n const instance = await reload(client, instanceId, tag)\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 tag: string\n workflowResource: WorkflowResource\n instanceId: string\n }): Promise<PendingEffect[]> => {\n const inst = await reload(args.client, args.instanceId, args.tag)\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 tag: 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.tag)\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 * Diagnose why an instance is or isn't progressing. Projects the\n * instance (the same read as `evaluate`) and classifies it — terminal,\n * `progressing`, `waiting` (an action is available — healthy), or `stuck`\n * with a structured cause — returning that verdict as a\n * {@link DiagnoseResult} alongside the evaluation it came from, so a\n * consumer can render the supporting evidence without a second projection.\n * Pure read.\n */\n diagnose: async (args: Clocked<EvaluateArgs>): Promise<DiagnoseResult> => {\n const evaluation = await evaluateInstance(args)\n const diagnosis = diagnoseInstance(diagnoseInputFromEvaluation(evaluation))\n return {evaluation, diagnosis, remediations: remediationsFor(diagnosis)}\n },\n\n /**\n * List the actions an actor could fire on an instance's current stage,\n * each flagged `allowed` (with a structured `disabledReason` when not).\n * Projects the instance from the actor's perspective and flattens its\n * tasks' actions. Returns the evaluation alongside the actions so a\n * consumer can read the instance/stage context. Pure read.\n */\n availableActions: async (args: Clocked<EvaluateArgs>): Promise<AvailableActionsResult> => {\n const evaluation = await evaluateInstance(args)\n return {evaluation, actions: availableActions(evaluation.currentStage.tasks)}\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 tag, 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 tag: string\n workflowResource: WorkflowResource\n instanceId: string\n task?: string\n }): Promise<WorkflowInstance[]> => {\n const {client, tag, instanceId, task} = args\n validateTag(tag)\n const parent = await reload(client, instanceId, tag)\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 tag, sorts\n // by startedAt. Beats N `getDocument` roundtrips for fan-outs.\n //\n // Visibility: this read-after-write relies on the spawn transaction\n // committing at the client's default `sync` visibility (see\n // {@link WorkflowTransaction.commit}) — under `async` it could miss a\n // just-spawned child. Every GROQ in the engine shares that assumption;\n // single-document writes now state `sync` explicitly, transactions can't\n // yet (the test fake's commit options lack `visibility`).\n return client.fetch<WorkflowInstance[]>(\n `*[_id in $ids && ${tagScopeFilter()}] | order(startedAt asc)`,\n {ids, tag},\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 {reload} from '../instance.ts'\nimport {tagScopeFilter, validateTag} from '../tags.ts'\nimport type {Actor} from '../types/actor.ts'\nimport {SYNC_COMMIT, type WorkflowClient} from '../types/client.ts'\nimport type {PendingEffect} from '../types/effects.ts'\nimport type {WorkflowInstance} from '../types/instance.ts'\nimport type {DeployedDefinition} from './deploy.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 tag: string\n effectHandlers: Record<string, EffectHandler>\n missingHandler: MissingHandlerPolicy\n logger: LoggerFactory\n}): Promise<VerifyDeployedDefinitionsResult> {\n const {client, tag, effectHandlers, missingHandler, logger} = args\n validateTag(tag)\n const log = logger('verifyDeployedDefinitions')\n const definitions = await client.fetch<DeployedDefinition[]>(\n `*[_type == \"${WORKFLOW_DEFINITION_TYPE}\" && ${tagScopeFilter()}] | order(name asc, version asc)`,\n {tag},\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 tag: 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 tag,\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 validateTag(tag)\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, tag)\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 tag,\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 tag: 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(SYNC_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 {reload} from '../instance.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} 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 tag: 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, tag, 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, tag)\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 clientForGdr,\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, tag)\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 {AvailableActionsResult} from '../available-actions.ts'\nimport type {Clock} from '../clock.ts'\nimport type {WorkflowResource} from '../core/refs.ts'\nimport type {DiagnoseResult} from '../diagnostics.ts'\nimport {type EvaluateArgs, evaluateInstance} from '../evaluate.ts'\nimport {subscriptionDocumentsForInstance, type WatchSet} from '../subscription-documents.ts'\nimport {validateTag} 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 DeleteDefinitionArgs,\n DeleteDefinitionResult,\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`, `tag`, `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 /**\n * Engine-scope environment partition (e.g. `\"test\"`, `\"prod\"`). Every\n * definition/instance the engine writes is stamped with this tag and\n * every read is scoped to it. Required and never defaulted — the engine\n * enforces nothing, so the partition is the only thing keeping reads and\n * writes off the wrong environment.\n */\n tag: 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<Args extends {client: WorkflowClient; tag: string; workflowResource: WorkflowResource}> =\n Omit<Args, 'client' | 'tag' | '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 tag: 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 /** Diagnose why an instance is or isn't progressing — a classified\n * {@link DiagnoseResult} plus the evaluation it was derived from. */\n diagnose: (args: Bound<EvaluateArgs>) => Promise<DiagnoseResult>\n /** The actions firable on the instance's current stage, each flagged\n * allowed/disabled, plus the evaluation they came from. */\n availableActions: (args: Bound<EvaluateArgs>) => Promise<AvailableActionsResult>\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 /** Admin override — remove a deployed definition (instances are only ever aborted, never deleted). */\n deleteDefinition: (args: Bound<DeleteDefinitionArgs>) => Promise<DeleteDefinitionResult>\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. `$tag`\n * is bound for tag-scoped 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 tag 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 + tag. The returned\n * object exposes the same verbs as the `workflow.*` namespace, minus\n * the boilerplate config arguments (client / tag / workflowResource)\n * which are pinned at construction. The `tag` is required — see\n * {@link validateTag} for the accepted shape.\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, resourceClients, clock, tag} = args\n validateTag(tag)\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; tag: string; workflowResource: WorkflowResource},\n >(\n rest: Omit<A, 'client' | 'tag' | 'workflowResource'>,\n ): A =>\n ({\n client,\n tag,\n workflowResource,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n ...(clock !== undefined ? {clock} : {}),\n ...rest,\n }) as A\n\n return {\n client,\n tag,\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 diagnose: (rest) => workflow.diagnose(bind<EvaluateArgs>(rest)),\n availableActions: (rest) => workflow.availableActions(bind<EvaluateArgs>(rest)),\n\n setStage: (rest) => workflow.setStage(bind<SetStageArgs>(rest)),\n abortInstance: (rest) => workflow.abortInstance(bind<AbortInstanceArgs>(rest)),\n deleteDefinition: (rest) => workflow.deleteDefinition(bind<DeleteDefinitionArgs>(rest)),\n getInstance: ({instanceId}) =>\n workflow.getInstance({client, tag, workflowResource, instanceId}),\n subscriptionDocumentsForInstance: ({instanceId}) =>\n workflow\n .getInstance({client, tag, workflowResource, instanceId})\n .then(subscriptionDocumentsForInstance),\n instance: (instanceDoc, opts) =>\n createInstanceSession({\n client,\n tag,\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 tag,\n workflowResource,\n instanceId,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n }),\n guardsForDefinition: ({definition}) =>\n workflow.guardsForDefinition({\n client,\n tag,\n workflowResource,\n definition,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n }),\n children: ({instanceId, task}) =>\n workflow.children({\n client,\n tag,\n workflowResource,\n instanceId,\n ...(task !== undefined ? {task} : {}),\n }),\n query: ({groq, params}) =>\n workflow.query({\n client,\n tag,\n workflowResource,\n groq,\n ...(params !== undefined ? {params} : {}),\n }),\n queryInScope: ({instanceId, groq, params}) =>\n workflow.queryInScope({\n client,\n tag,\n workflowResource,\n instanceId,\n groq,\n ...(params !== undefined ? {params} : {}),\n ...(clock !== undefined ? {clock} : {}),\n }),\n listPendingEffects: ({instanceId}) =>\n workflow.listPendingEffects({client, tag, workflowResource, instanceId}),\n findPendingEffects: ({instanceId, claimed, names}) =>\n workflow.findPendingEffects({\n client,\n tag,\n workflowResource,\n instanceId,\n ...(claimed !== undefined ? {claimed} : {}),\n ...(names !== undefined ? {names} : {}),\n }),\n drainEffects: ({instanceId, access}) =>\n drainEffectsInternal({\n client,\n tag,\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 tag,\n effectHandlers,\n missingHandler,\n logger,\n }),\n }\n}\n","// Definition diff — classify a local definition against its deployed\n// counterpart as create / update / unchanged, using the same doc-id minting\n// and no-op verdict that `deployDefinitions` uses. Pure reasoning: callers\n// own the fetch and render the result. Shared so deploy tooling (CLI today,\n// other consumers later) doesn't re-derive the deployed shape by hand.\n\nimport {definitionDocId, isDefinitionUnchanged, stripSystemFields} from './api/deploy.ts'\nimport type {WorkflowResource} from './core/refs.ts'\nimport {WORKFLOW_DEFINITION_TYPE, type WorkflowDefinition} from './define/schema.ts'\nimport type {WorkflowClient} from './types/client.ts'\n\n/** Where a definition deploys: the engine tag it partitions under, and the\n * workflow resource it belongs to. Structurally what `deployDefinitions`\n * receives, minus the definitions themselves. */\nexport interface DeployTarget {\n tag: string\n workflowResource: WorkflowResource\n}\n\nexport interface DiffEntry {\n name: string\n version: number\n status: 'create' | 'update' | 'unchanged'\n docId: string\n expected: Record<string, unknown>\n existing?: Record<string, unknown>\n}\n\n/** The tag-prefixed document id a definition deploys to — the engine's own\n * {@link definitionDocId}, so a diff lines up with what deploy would write. */\nfunction docIdFor(def: WorkflowDefinition, target: DeployTarget): string {\n return definitionDocId(target.workflowResource, target.tag, def.name, def.version)\n}\n\nfunction diffStatus(\n existing: Record<string, unknown> | undefined,\n expected: Record<string, unknown>,\n): DiffEntry['status'] {\n if (existing === undefined) return 'create'\n if (isDefinitionUnchanged(existing, expected)) return 'unchanged'\n return 'update'\n}\n\n/**\n * Compare one local definition against a deployed document (or its\n * absence), classifying it as create / update / unchanged using the\n * engine's own no-op verdict. Pure — callers own the fetch, so the same\n * comparison serves both deploy's exact-docId lookup and `definition\n * diff`'s latest-version query.\n */\nexport function diffEntry(\n def: WorkflowDefinition,\n existingRaw: Record<string, unknown> | undefined,\n target: DeployTarget,\n): DiffEntry {\n const docId = docIdFor(def, target)\n const expected: Record<string, unknown> = {\n ...def,\n _id: docId,\n _type: WORKFLOW_DEFINITION_TYPE,\n tag: target.tag,\n }\n const status = diffStatus(existingRaw, expected)\n const existing = existingRaw ? stripSystemFields(existingRaw) : undefined\n return {\n name: def.name,\n version: def.version,\n status,\n docId,\n expected,\n ...(existing !== undefined ? {existing} : {}),\n }\n}\n\n/** Compare each definition against the deployed doc at its own docId. */\nexport async function computeDiffEntries(\n client: Pick<WorkflowClient, 'getDocument'>,\n defs: WorkflowDefinition[],\n target: DeployTarget,\n): Promise<DiffEntry[]> {\n const entries: DiffEntry[] = []\n for (const def of defs) {\n const existingRaw =\n (await client.getDocument<Record<string, unknown>>(docIdFor(def, target))) ?? undefined\n entries.push(diffEntry(def, existingRaw, target))\n }\n return entries\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","parse","evaluate","currentTasks","gdrUri","doc","schema","randomKey","isTerminalTaskStatus","WORKFLOW_DEFINITION_TYPE","DOCUMENT_VALUE_PERMISSIONS","engineAbortInstance","engineInvokeTask","engineFireAction","cascade","deleteDefinitionInternal","engineCompleteEffect","engineSetStage","queryGuardsForInstance","queryGuardsForDefinition","evaluateGroq"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/types/instance-state.ts","../src/core/refs.ts","../src/core/params.ts","../src/core/path.ts","../src/guard-bindings.ts","../src/api/validate.ts","../src/available-actions.ts","../src/clock.ts","../src/types/authorization.ts","../src/core/guards.ts","../src/diagnostics.ts","../src/engine/results.ts","../src/core/snapshot.ts","../src/types/instance.ts","../src/subscription-documents.ts","../src/snapshot.ts","../src/guards-query.ts","../src/types/client.ts","../src/guards-lifecycle.ts","../src/keys.ts","../src/core/eval.ts","../src/core/state-validation.ts","../src/state-resolution.ts","../src/engine/context.ts","../src/engine/guard-commit.ts","../src/engine/history-entries.ts","../src/engine/mutation.ts","../src/tags.ts","../src/definition-query.ts","../src/discover.ts","../src/instance.ts","../src/engine/spawn.ts","../src/core/bindings.ts","../src/engine/persist-deploy.ts","../src/engine/effects.ts","../src/core/source.ts","../src/engine/ops.ts","../src/engine/tasks.ts","../src/engine/stages.ts","../src/engine/cascade.ts","../src/permissions.ts","../src/access.ts","../src/core/editability.ts","../src/evaluate.ts","../src/api/deploy.ts","../src/engine/abort.ts","../src/engine/actions.ts","../src/types/evaluation.ts","../src/engine/edit.ts","../src/api/operations.ts","../src/api/delete-definition.ts","../src/api/workflow.ts","../src/api/drain.ts","../src/api/instance-session.ts","../src/api/engine-factory.ts","../src/definition-diff.ts","../src/display.ts"],"sourcesContent":["/**\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 /**\n * The filter evaluated to GROQ `null` — a referenced operand was missing\n * or incomparable, so it couldn't be decided. The engine fails closed\n * (keeps the task in scope) rather than reading this as a deliberate\n * `false`; `truthy` is `false` here but the task is NOT skipped.\n */\n unevaluable?: 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 * 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 {@link WorkflowResource} a GDR URI addresses — the inverse of\n * {@link gdrFromResource}, dropping the document-id tail. Returns\n * `undefined` for a non-GDR string so callers can treat \"unparseable\"\n * as \"no resource\" rather than handling a throw.\n */\nexport function resourceFromGdrUri(uri: string): WorkflowResource | undefined {\n let parsed: ParsedGdr\n try {\n parsed = parseGdr(uri)\n } catch {\n return undefined\n }\n // The `undefined` guards narrow the cross-scheme-optional `ParsedGdr`\n // fields; `parseGdr` already guarantees them per scheme, so they don't\n // fire in practice — they keep the function total without a cast.\n if (parsed.scheme === 'dataset') {\n if (parsed.projectId === undefined || parsed.dataset === undefined) return undefined\n return {type: 'dataset', id: `${parsed.projectId}.${parsed.dataset}`}\n }\n if (parsed.resourceId === undefined) return undefined\n return {type: parsed.scheme, id: parsed.resourceId}\n}\n\n/** Whether two workflow resources address the same place. */\nexport function sameResource(a: WorkflowResource, b: WorkflowResource): boolean {\n return a.type === b.type && a.id === b.id\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 — 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, roleAliases)` — the `$assigned`\n * computation: does the caller match the task's `assignees`-kind state\n * entry (by user id, or by a role the actor holds that fulfills it under\n * the definition's `roleAliases`)? 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 {RoleAliases} from '../define/schema.ts'\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 {actorFulfillsRole} from './roles.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 a role the\n * actor holds that fulfills it (the definition's `roleAliases` widen the\n * accepted set the same way the baked `roles` gate does — see\n * {@link actorFulfillsRole}). No entry (or no actor) means false.\n */\nexport function assignedFor(\n instance: WorkflowInstance,\n taskName: string,\n actor: Actor | undefined,\n roleAliases: RoleAliases | 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 : actorFulfillsRole(actor.roles, a.role, roleAliases),\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 * 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","import {effectsContextMap} from './core/params.ts'\nimport {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// Effect names may be dotted namespaces (`press.notifyDesk`), so the name is\n// bracket-quoted to disambiguate it from the value path — matching the\n// `$effects['<name>'].<output>` spelling used in condition params.\nconst EFFECTS_READ = /^\\$effects\\['([^']+)'\\](?:\\.(.+))?$/\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\"`,\n * `\"$state.<name>[.path]\"`, or `\"$effects['<name>'][.path]\"`. Checked at\n * deploy ({@link validateDefinition}) so a typo fails before the first\n * instance enters the stage, and enforced again at resolve time by\n * {@link resolveGuardRead}.\n */\nexport function isGuardReadExpr(expr: string): boolean {\n return expr === '$self' || expr === '$now' || STATE_READ.test(expr) || EFFECTS_READ.test(expr)\n}\n\n/**\n * Resolve a guard's deploy-time read — the value spelling on `match.idRefs`\n * and `metadata`. The lake contract stores resolved VALUES, so these evaluate\n * here, at deploy (and again on the post-state-op / effect-completion\n * refresh): the engine bakes the value into the guard doc, so the lake never\n * needs to see `$state` or `$effects`. Deliberately a tiny reader, not full\n * GROQ: a guard value is `\"$self\"`, `\"$now\"`, `\"$state.<name>[.path]\"`, or\n * `\"$effects['<name>'][.path]\"` — anything else is an authoring error and\n * 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 const effectsRead = EFFECTS_READ.exec(expr)\n if (effectsRead !== null) {\n const outputs = effectsContextMap(ctx.instance)[effectsRead[1]!]\n return effectsRead[2] !== undefined ? getPath(outputs, effectsRead[2]) : outputs\n }\n throw new Error(\n `Guard read \"${expr}\" is not a supported deploy-time value — use \"$self\", \"$now\", ` +\n `\"$state.<name>[.path]\", or \"$effects['<name>'][.path]\" (guards store resolved values; ` +\n `the lake cannot see $state or $effects)`,\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`/`$effects`) 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\", \"$state.<name>[.path]\", or \"$effects['<name>'][.path]\" (guards store resolved ` +\n `values; the lake cannot see $state or $effects)`,\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 [name, groq] of Object.entries(task.requirements ?? {})) {\n v.checkCondition(groq, `${where}.requirements \"${name}\"`)\n }\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","// Available-actions projection — flatten an instance's current-stage tasks\n// into the actions an actor could fire, each carrying whether it's allowed\n// (and the structured reason when not). Pure reasoning over a\n// `WorkflowEvaluation`; consumers (CLI list mode, MCP, a UI) render it\n// their own way. The `workflow.availableActions` verb composes `evaluate`\n// with this so a consumer can ask \"what can I fire on this instance\" by id.\n\nimport type {ActionParam} from './define/schema.ts'\nimport type {TaskStatus} from './types/enums.ts'\nimport type {\n ActionEvaluation,\n DisabledReason,\n TaskEvaluation,\n WorkflowEvaluation,\n} from './types/evaluation.ts'\n\nexport interface AvailableAction {\n task: string\n taskStatus: TaskStatus\n action: string\n title: string | undefined\n allowed: boolean\n disabledReason: DisabledReason | undefined\n params: ActionParam[]\n}\n\n/** The `workflow.availableActions` result — the projected actions plus the\n * evaluation they came from, so a consumer can read the instance/stage\n * context without a second projection. */\nexport interface AvailableActionsResult {\n evaluation: WorkflowEvaluation\n actions: AvailableAction[]\n}\n\n/** The fireable-action verdict for one action on a task — its `allowed`\n * state, structured `disabledReason`, and declared params, tagged with the\n * owning task. The per-action atom both projections share:\n * {@link availableActions} flattens it across a stage's tasks; a consumer\n * that keeps per-task nesting (e.g. the MCP) maps it over a task's actions\n * directly, so the verdict shape has a single source. */\nexport function actionVerdict(task: TaskEvaluation, action: ActionEvaluation): AvailableAction {\n return {\n task: task.task.name,\n taskStatus: task.status,\n action: action.action.name,\n title: action.action.title,\n allowed: action.allowed,\n disabledReason: action.disabledReason,\n params: action.action.params ?? [],\n }\n}\n\n/** Flatten an evaluation's current-stage tasks into the actions the actor\n * could fire, each carrying whether it's allowed (and why not). */\nexport function availableActions(tasks: TaskEvaluation[]): AvailableAction[] {\n return tasks.flatMap((t) => t.actions.map((a) => actionVerdict(t, a)))\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","// Instance diagnostics — classify *why* an instance is or isn't\n// progressing, from the instance doc + its evaluation, and name the\n// structured remediations that would unstick it. Pure reasoning, no\n// rendering: the CLI and MCP each present a `Diagnosis` their own way.\n// The `workflow.diagnose` verb composes `evaluate` + this classifier so\n// a consumer can diagnose by instance id in one call.\n\nimport type {EffectHistoryEntry, PendingEffect} from './types/effects.ts'\nimport type {TaskStatus} from './types/enums.ts'\nimport type {TaskEvaluation, TransitionEvaluation, WorkflowEvaluation} from './types/evaluation.ts'\nimport type {HistoryEntry} from './types/history.ts'\nimport {findOpenStageEntry, type StageEntry} from './types/instance-state.ts'\nimport type {WorkflowInstance} from './types/instance.ts'\nimport type {Assignee, ResolvedStateEntry} from './types/state-values.ts'\n\n/**\n * Why an in-flight instance is genuinely blocked — nothing advances it on its\n * own OR via a normal action. Ordered most- to least-actionable in\n * {@link diagnoseInstance}: a failed effect is the root cause even when it left\n * its task looking merely \"active\", so it wins over the task- and\n * transition-level symptoms it produces. Note an active task awaiting a human\n * action is NOT here — that's the healthy {@link Diagnosis} `waiting` state.\n */\nexport type StuckCause =\n | {kind: 'failed-effect'; effect: EffectHistoryEntry}\n | {kind: 'hung-effect'; effect: PendingEffect}\n | {kind: 'failed-task'; task: string}\n | {kind: 'no-transition-fires'}\n /**\n * Every task resolved, but an exit transition's filter is *unevaluable*\n * (GROQ `null` — a referenced operand is missing/unreadable), so selection\n * halts. Unlike {@link StuckCause} `no-transition-fires` this is recoverable:\n * the cascade re-fires once the operand resolves (e.g. the subject is\n * published or the field is filled). Carries the undecidable transitions.\n */\n | {kind: 'transition-unevaluable'; transitions: string[]}\n\nexport type Diagnosis =\n | {state: 'progressing'}\n // Healthy in-flight: an active task has an available action; it advances when\n // someone acts. NOT stuck — we deliberately don't judge how long a given\n // workflow is \"allowed\" to wait, since that's workflow- and team-specific.\n | {state: 'waiting'; task: string; assignees: Assignee[]; actions: string[]}\n // Healthy in-flight, but not yet actionable: an active task whose declared\n // requirements aren't all met — the readiness axis. It flips to `waiting`\n // once the preconditions hold (typically when a sibling task completes or\n // content lands). NOT stuck: \"visible but not yet executable\" is an expected,\n // transient state, and only surfaces when nothing else is actionable.\n | {state: 'blocked'; task: string; requirements: string[]; assignees: Assignee[]}\n | {state: 'completed'; at: string}\n | {state: 'aborted'; at: string; reason?: string}\n | {state: 'stuck'; cause: StuckCause}\n\n/**\n * A verb that would unstick a {@link StuckCause} — the *what to do about it*\n * half of a diagnosis. Surface-neutral identifiers; a consumer maps each to\n * its own command or button. `retry-effect`, `drain-effects` and `reset-task`\n * are not yet callable engine operations — see {@link SuggestedRemediation.available}.\n */\nexport type RemediationVerb =\n | 'retry-effect'\n | 'drain-effects'\n | 'reset-task'\n | 'set-stage'\n | 'abort'\n\nexport interface SuggestedRemediation {\n verb: RemediationVerb\n /** True iff a consumer can run this as an engine operation today. `false`\n * marks a remediation we can name but not yet execute — a planned verb, or\n * an operational step (re-running the effect drainer). */\n available: boolean\n /** Surface-neutral one-line rationale — no color or terminal symbols; a\n * consumer decorates it for its own surface. */\n rationale: string\n}\n\n/**\n * The slice of an instance + its {@link WorkflowEvaluation} the classifier\n * reads. Narrowed so callers (and tests) can craft an exact stuck permutation\n * without standing up a full evaluation; {@link diagnoseInputFromEvaluation}\n * builds it from a real {@link WorkflowEvaluation}.\n */\nexport interface DiagnoseInput {\n instance: Pick<\n WorkflowInstance,\n 'currentStage' | 'completedAt' | 'abortedAt' | 'effectHistory' | 'pendingEffects' | 'history'\n >\n tasks: TaskEvaluation[]\n transitions: TransitionEvaluation[]\n assignees: Record<string, Assignee[]>\n}\n\n/** The `workflow.diagnose` result — the verdict, the structured remediations\n * that would unstick it (empty unless `stuck`), and the evaluation it was\n * derived from, so a consumer can render the supporting evidence (current\n * stage tasks + transitions) without a second projection. */\nexport interface DiagnoseResult {\n evaluation: WorkflowEvaluation\n diagnosis: Diagnosis\n remediations: SuggestedRemediation[]\n}\n\n/** The free-text reason recorded on the aborted history entry, if any. */\nexport function abortReason(instance: Pick<WorkflowInstance, 'history'>): string | undefined {\n const entry = instance.history.find(\n (h): h is Extract<HistoryEntry, {_type: 'aborted'}> => h._type === 'aborted',\n )\n return entry?.reason\n}\n\n/** Narrow a full {@link WorkflowEvaluation} to the {@link DiagnoseInput} the\n * classifier reads. */\nexport function diagnoseInputFromEvaluation(evaluation: WorkflowEvaluation): DiagnoseInput {\n const stage = openStage(evaluation.instance)\n\n return {\n instance: evaluation.instance,\n tasks: evaluation.currentStage.tasks,\n transitions: evaluation.currentStage.transitions,\n assignees: Object.fromEntries(\n evaluation.currentStage.tasks.map((t) => [t.task.name, assigneesOf(stage, t.task.name)]),\n ),\n }\n}\n\n/** The instance's current, not-yet-exited {@link StageEntry}, if it has one —\n * the engine's canonical {@link findOpenStageEntry}, over the diagnosis input. */\nfunction openStage(\n instance: Pick<WorkflowInstance, 'currentStage' | 'stages'>,\n): StageEntry | undefined {\n return findOpenStageEntry(instance)\n}\n\n/** The assignees recorded for a task in a stage — the runtime half of the\n * \"who is this waiting on\" answer. Empty when the task is unassigned. */\nfunction assigneesOf(stage: StageEntry | undefined, taskName: string): Assignee[] {\n const entry = stage?.tasks.find((t) => t.name === taskName)\n return (entry?.state ?? [])\n .filter((s): s is Extract<ResolvedStateEntry, {_type: 'assignees'}> => s._type === 'assignees')\n .flatMap((s) => s.value)\n}\n\n/** A task that has resolved one way or another — done or skipped. */\nfunction isResolved(status: TaskStatus): boolean {\n return status === 'done' || status === 'skipped'\n}\n\n/**\n * A failed effect whose origin task is still unresolved in the current\n * stage. The origin link is what makes it the blocker (not just any old\n * failure in history): the task that queued it can't complete until the\n * effect succeeds, so the stage can't advance.\n */\nfunction failedEffectCause(input: DiagnoseInput): StuckCause | undefined {\n const stalled = new Set(input.tasks.filter((t) => !isResolved(t.status)).map((t) => t.task.name))\n const effect = [...input.instance.effectHistory]\n .reverse()\n .find((e) => e.status === 'failed' && e.origin.kind === 'task' && stalled.has(e.origin.name))\n return effect ? {kind: 'failed-effect', effect} : undefined\n}\n\n/** A pending effect a drainer claimed but never reported back on — the\n * drainer died mid-dispatch, so the entry will never drain on its own. */\nfunction hungEffectCause(input: DiagnoseInput): StuckCause | undefined {\n const effect = input.instance.pendingEffects.find((e) => e.claim !== undefined)\n return effect ? {kind: 'hung-effect', effect} : undefined\n}\n\nfunction failedTaskCause(input: DiagnoseInput): StuckCause | undefined {\n const failed = input.tasks.find((t) => t.status === 'failed')\n return failed ? {kind: 'failed-task', task: failed.task.name} : undefined\n}\n\n/** An active task with an available action — the instance advances as soon as\n * someone acts on it. Healthy, not stuck; we don't judge how long that wait\n * is \"allowed\" to be. */\nfunction waitingState(input: DiagnoseInput): Extract<Diagnosis, {state: 'waiting'}> | undefined {\n // A task held by an unmet requirement isn't \"waiting on a human to act\" — no\n // action can fire yet. Skip it here so a genuinely actionable sibling wins;\n // {@link blockedState} reports the readiness hold when nothing is actionable.\n const active = input.tasks.find(\n (t) =>\n t.status === 'active' &&\n (t.task.actions ?? []).length > 0 &&\n (t.unmetRequirements ?? []).length === 0,\n )\n\n if (active === undefined) {\n return undefined\n }\n\n return {\n state: 'waiting',\n task: active.task.name,\n assignees: input.assignees[active.task.name] ?? [],\n actions: (active.task.actions ?? []).map((a) => a.name),\n }\n}\n\n/** An active task held by the readiness axis — its declared requirements\n * aren't all met, so none of its actions can fire yet. Requires the task to\n * HAVE actions (readiness gates executability — a no-action machine step has\n * nothing to block). Reported only after {@link waitingState}, so it never\n * masks an actionable task elsewhere; the hold is not a stuck cause. */\nfunction blockedState(input: DiagnoseInput): Extract<Diagnosis, {state: 'blocked'}> | undefined {\n const blocked = input.tasks.find(\n (t) =>\n t.status === 'active' &&\n (t.task.actions ?? []).length > 0 &&\n (t.unmetRequirements ?? []).length > 0,\n )\n if (blocked === undefined) {\n return undefined\n }\n return {\n state: 'blocked',\n task: blocked.task.name,\n requirements: blocked.unmetRequirements ?? [],\n assignees: input.assignees[blocked.task.name] ?? [],\n }\n}\n\n/**\n * Every task resolved, exits declared, but none fires. Two distinct causes:\n * an *unevaluable* filter (GROQ `null` — a missing/unreadable operand) is a\n * recoverable hold the cascade re-fires once the operand resolves; otherwise\n * every filter is a definite `false` — a routing dead-end (a state value a\n * filter reads never got written).\n */\nfunction noTransitionFiresCause(input: DiagnoseInput): StuckCause | undefined {\n if (input.transitions.length === 0) {\n return undefined\n }\n\n if (input.transitions.some((t) => t.filterSatisfied)) {\n return undefined\n }\n\n if (!input.tasks.every((t) => isResolved(t.status))) {\n return undefined\n }\n\n const undecidable = input.transitions.filter((t) => t.unevaluable)\n if (undecidable.length > 0) {\n return {kind: 'transition-unevaluable', transitions: undecidable.map((t) => t.transition.name)}\n }\n\n return {kind: 'no-transition-fires'}\n}\n\n/**\n * Classify an instance. Terminal states win first; then the genuine stuck\n * causes (nothing advances on its own or via a normal action); then `waiting`\n * (an action is available — healthy); then `blocked` (an active task held by\n * an unmet requirement — healthy, not yet actionable); else `progressing` (a\n * transition is already satisfied and will cascade).\n */\nexport function diagnoseInstance(input: DiagnoseInput): Diagnosis {\n const {instance} = input\n\n if (instance.abortedAt !== undefined) {\n const reason = abortReason(instance)\n\n return {state: 'aborted', at: instance.abortedAt, ...(reason !== undefined ? {reason} : {})}\n }\n\n if (instance.completedAt !== undefined) {\n return {state: 'completed', at: instance.completedAt}\n }\n\n const cause =\n failedEffectCause(input) ??\n failedTaskCause(input) ??\n hungEffectCause(input) ??\n noTransitionFiresCause(input)\n\n if (cause !== undefined) {\n return {state: 'stuck', cause}\n }\n\n return waitingState(input) ?? blockedState(input) ?? {state: 'progressing'}\n}\n\n/** The remediation verbs a consumer can actually run as an engine operation\n * today. Everything else a diagnosis names (`retry-effect`, `reset-task`, the\n * effect drainer) is describable but not yet callable — add a verb here when\n * it ships, and {@link remediationsFor} flips it to `available`. */\nconst RUNNABLE_VERBS = new Set<RemediationVerb>(['set-stage', 'abort'])\n\ntype RemediationSeed = Omit<SuggestedRemediation, 'available'>\n\nfunction remediationsForCause(cause: StuckCause): RemediationSeed[] {\n switch (cause.kind) {\n case 'failed-effect':\n return [\n {\n verb: 'retry-effect',\n rationale: 'Re-run the failed effect once the upstream system is healthy.',\n },\n {verb: 'abort', rationale: 'Abort the instance if it can no longer recover.'},\n ]\n case 'hung-effect':\n return [\n {\n verb: 'drain-effects',\n rationale: 'Re-run the effect drainer to re-pick the claimed effect.',\n },\n {verb: 'abort', rationale: 'Abort the instance if the effect never drains.'},\n ]\n case 'failed-task':\n return [\n {verb: 'reset-task', rationale: 'Reset or skip the failed task.'},\n {\n verb: 'set-stage',\n rationale: 'Move the instance past the failed task to the intended next stage.',\n },\n ]\n case 'no-transition-fires':\n return [\n {\n verb: 'set-stage',\n rationale: 'Move the instance to the intended next stage to force it forward.',\n },\n ]\n case 'transition-unevaluable':\n // Recoverable hold: the filter advances on its own once the operand\n // becomes readable. No engine verb unsticks it — forcing `set-stage`\n // would skip the gate the unevaluable filter exists to hold.\n return []\n }\n}\n\n/**\n * The remediations that would unstick a diagnosis — the *what to do about it*\n * half. Empty unless the instance is `stuck`: a `waiting` instance advances on\n * its own next action (see `availableActions`), and terminal or `progressing`\n * ones need nothing. Each verb is flagged\n * {@link SuggestedRemediation.available} from {@link RUNNABLE_VERBS}.\n */\nexport function remediationsFor(diagnosis: Diagnosis): SuggestedRemediation[] {\n if (diagnosis.state !== 'stuck') {\n return []\n }\n\n return remediationsForCause(diagnosis.cause).map((seed) => ({\n ...seed,\n available: RUNNABLE_VERBS.has(seed.verb),\n }))\n}\n","import type {Clock} from '../clock.ts'\nimport type {ParsedGdr} from '../core/refs.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {Grant} from '../types/authorization.ts'\nimport type {WorkflowClient} from '../types/client.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 * Cross-resource routing for this operation, derived from the caller's\n * `resourceClients`. Threaded into {@link loadContext} so guard\n * deploy/retract and snapshot hydration route to the SUBJECT's resource —\n * not the engine's own. Defaults to the engine's `client` when absent.\n * A guard written to (or lifted from) the wrong dataset is a silent no-op,\n * so every guard-touching commit path MUST forward this.\n */\n clientForGdr?: (parsed: ParsedGdr) => WorkflowClient\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 workflow is started (or a child spawned) without a value for\n * a state entry marked `required`. Mirrors {@link ActionParamsInvalidError}:\n * the engine has NOT created the instance — a missing load-bearing slot\n * (e.g. the subject of a review) screams here rather than silently defaulting\n * to `null`/`[]` and birthing a half-formed instance mid-process.\n */\nexport class RequiredStateNotProvidedError extends Error {\n readonly definition?: string\n readonly missing: {name: string; type: string}[]\n constructor(args: {definition?: string; missing: {name: string; type: string}[]}) {\n const lines = args.missing.map((m) => ` - ${m.name} (${m.type})`).join('\\n')\n const where = args.definition !== undefined ? ` for workflow \"${args.definition}\"` : ''\n super(\n `Required init state${where} was not provided:\\n${lines}\\n` +\n `Provide each via \\`initialState\\` when starting standalone, or via the parent's ` +\n `\\`subworkflows.with\\` when spawned.`,\n )\n this.name = 'RequiredStateNotProvidedError'\n if (args.definition !== undefined) this.definition = args.definition\n this.missing = args.missing\n }\n}\n\n/**\n * Thrown when a guard deploy fails *after* its state move committed and the\n * engine could not cleanly undo the result — any of: the rollback write itself\n * failed; the move created sibling docs (spawn) that a parent-only rollback\n * cannot undo; or a multi-guard deploy partially applied, so even a clean state\n * rollback leaves the earlier guards orphaned ({@link PartialGuardDeployError}).\n * The workflow's persisted state and its deployed guards are now divergent and\n * need manual reconciliation; the engine screams rather than leaving the\n * 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\n/**\n * A stage's multi-guard deploy failed *after* at least one guard already landed.\n * Those partial locks can't be cleanly undone (guard docs have no transactional\n * deploy). Inside the engine {@link deployOrRollback} rolls the state move back\n * and escalates this to a loud {@link WorkflowStateDivergedError}; a caller that\n * invokes {@link deployStageGuards} directly (without that rollback wrapper) can\n * also see it, so it's exported to be catchable by type.\n */\nexport class PartialGuardDeployError extends Error {\n readonly stageName: string\n readonly deployed: number\n constructor(args: {stageName: string; deployed: number; cause: unknown}) {\n super(\n `Partial guard deploy on stage \"${args.stageName}\": ${args.deployed} guard(s) deployed before a later one failed.`,\n {cause: args.cause},\n )\n this.name = 'PartialGuardDeployError'\n this.stageName = args.stageName\n this.deployed = args.deployed\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 * Edit-seam twin of {@link ConcurrentFireActionError}: an `editState` commit\n * lost the optimistic-locking race on every attempt. Same contract — re-read\n * and retry, or investigate a write storm; nothing committed on the final try.\n */\nexport class ConcurrentEditStateError extends Error {\n readonly instanceId: string\n readonly target: {scope: StateScope; state: string; task?: string}\n readonly attempts: number\n constructor(args: {\n instanceId: string\n target: {scope: StateScope; state: string; task?: string}\n attempts: number\n }) {\n const where =\n args.target.task !== undefined\n ? `${args.target.task}.${args.target.state}`\n : args.target.state\n super(\n `Edit of \"${args.target.scope}:${where}\" (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 = 'ConcurrentEditStateError'\n this.instanceId = args.instanceId\n this.target = args.target\n this.attempts = args.attempts\n }\n}\n\nexport interface EditStateResult {\n edited: boolean\n target: {scope: StateScope; state: string; task?: string}\n /** Deterministic engine primitives that ran inline during the commit. */\n ranOps?: OpAppliedSummary[]\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","/**\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 environment partition stamped on the instance at create\n * time. Reads are scoped to a single tag, so an engine only sees\n * instances whose `tag` equals its own.\n */\n tag: 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 perspective a content read falls back to when the instance has no\n * explicit release perspective: `drafts` overlay published (Sanity\n * draft-precedence), so an unpublished or in-flight subject is what the engine\n * — and the reactive adapters — evaluate, never a published-only read that\n * silently misses the draft. The single home for the draft-precedence default;\n * every content read uses `instance.perspective ?? DEFAULT_CONTENT_PERSPECTIVE`.\n */\nexport const DEFAULT_CONTENT_PERSPECTIVE = 'drafts' satisfies WorkflowPerspective\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 * Pull the single-subject {@link GlobalDocumentReference} values out of\n * state entries — `doc.ref` and `release.ref` — in declaration order.\n * Unlike {@link entryDocRefs} this skips `doc.refs` (a collection has no\n * one \"subject\") and keeps the two kinds interleaved by position, so a\n * caller wanting the subject the author declared first reads index 0.\n * Used to route spawn discovery to the resource its subject lives in.\n */\nexport function entrySubjectRefs(state: unknown): GlobalDocumentReference[] {\n return stateEntries(state).flatMap((entry) =>\n (entry._type === 'doc.ref' || entry._type === 'release.ref') && isGdr(entry.value)\n ? [entry.value]\n : [],\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. With no release perspective they default to\n * `drafts` (drafts overlay published) rather than published-only, so an\n * unpublished or in-flight subject is still what filters evaluate. The\n * instance, ancestors (both instance documents), and `release.ref` system\n * docs are always read RAW — per the engine contract, and because a release\n * perspective doesn't version those. The raw-vs-content split ({@link readsRaw})\n * is shared with the reactive WatchSet contract; the `drafts` default is\n * applied on this fetch side.\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 {\n collectWatchRefs,\n DEFAULT_CONTENT_PERSPECTIVE,\n entryDocRefs,\n readsRaw,\n} 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 (uri: string, perspective: WorkflowPerspective): 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, defaulting to a\n // drafts-preferring read when the instance has no release perspective:\n // drafts overlay published (Sanity draft-precedence), so the version an\n // editor is actively drafting is what filters evaluate — not a stale or\n // entirely absent published doc (a draft-only subject would otherwise read\n // as missing and silently skip every threshold gate). Instance / ancestor /\n // release docs read RAW (see {@link readsRaw} — the one home for that rule,\n // shared with the WatchSet contract the reactive consumer follows).\n for (const ref of collectWatchRefs(instance)) {\n await loadInto(\n ref.id,\n readsRaw(ref) ? 'raw' : (instance.perspective ?? DEFAULT_CONTENT_PERSPECTIVE),\n )\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,\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 under a read perspective. `raw` is a strongly-consistent\n * point read (`getDocument`), used for the engine's own metadata — instance /\n * ancestor / release docs, which are unversioned and live at their bare id.\n * Any other perspective — a drafts-preferring read, or a release stack like\n * `[releaseName]` — goes through `fetch(..., {perspective})` so draft/version\n * content is projected onto the published id and a content doc that exists\n * only as a draft (or only inside a release) is still visible to filters.\n * Mirrors how state-entry query resolution already reads under perspective.\n * The caller decides which reads are raw vs perspective-scoped — see\n * {@link readsRaw}.\n */\nasync function readDoc(\n client: WorkflowClient,\n id: string,\n perspective: WorkflowPerspective,\n): Promise<SanityDocument | null> {\n if (perspective === 'raw') {\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 * 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 perClient = await guardsForDefinitionByClient(args)\n return dedupById(perClient.flatMap((entry) => entry.guards))\n}\n\n/**\n * {@link guardsForDefinition}, but grouped by the resource client each guard\n * doc lives in — for housekeeping that must WRITE against the owning resource\n * (e.g. `deleteDefinition` removing orphaned guard docs per datasource).\n * Resources are deduped by key before querying, so no guard doc appears under\n * two clients.\n */\nexport async function guardsForDefinitionByClient(\n args: GuardsForDefinitionArgs,\n): Promise<Array<{client: WorkflowClient; guards: 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 const query = `*[_type == $t && sourceDefinition == $definition]`\n const params = {t: GUARD_DOC_TYPE, definition}\n return Promise.all(\n [...clients.values()].map(async (resourceClient) => ({\n client: resourceClient,\n guards: await resourceClient.fetch<MutationGuardDoc[]>(query, params),\n })),\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","// Client surface — narrow interface the engine uses.\n\nimport type {SanityDocument} from '@sanity/types'\n\n/**\n * The subset of `@sanity/client` the engine actually needs. The\n * `@sanity-labs/client-fake-for-test` TestClient is\n * structurally assignable to this, as is the real `@sanity/client`\n * SanityClient.\n */\nexport interface WorkflowMutationOptions {\n /**\n * Optimistic concurrency: only proceed if the target document's\n * current `_rev` matches. On mismatch the underlying client throws.\n * Pass the `_rev` loaded alongside the doc you're about to write back.\n */\n ifRevisionId?: string\n}\n\n/**\n * Perspective layering — see Sanity Content Lake docs. The engine\n * threads this into reads that should reflect a release-stacked view\n * of the dataset (state-entry query resolution, spawn forEach discovery).\n * Engine-internal reads of `workflow.instance` / `workflow.definition`\n * stay raw regardless — those docs are unversioned metadata.\n *\n * Either both the real `@sanity/client` and the fake test client\n * support the same shape. `string[]` is an ordered release-name stack;\n * `\"drafts\"` may appear in the array. `\"published\"` is the implicit\n * tail.\n */\nexport type WorkflowPerspective = 'raw' | 'published' | 'drafts' | string[]\n\nexport interface WorkflowFetchOptions {\n /**\n * Override the client's configured perspective for this read. The\n * engine uses this to scope state-entry query and spawn forEach\n * reads to the instance's `perspective` field.\n */\n perspective?: WorkflowPerspective\n}\n\nexport type WorkflowVisibility = 'sync' | 'async' | 'deferred'\n\nexport interface WorkflowCommitOptions {\n /**\n * When the mutation becomes visible to subsequent queries. The engine\n * reads its own writes back through GROQ (`fetch`) — a freshly-spawned\n * child listed by id, a just-deployed definition — so single-document\n * writes (`create`, `patch().commit()`) commit `'sync'`: the change is\n * query-visible before the call resolves and the next read can't miss it.\n * `@sanity/client` already defaults to `'sync'`, but the engine states it\n * rather than depend on a transport default a consumer's client config\n * could change underneath it. (Transactions ride that same default — see\n * {@link WorkflowTransaction.commit}.)\n */\n visibility?: WorkflowVisibility\n}\n\n/** The engine's standing single-write policy — see {@link WorkflowCommitOptions.visibility}. */\nexport const SYNC_COMMIT: WorkflowCommitOptions = {visibility: 'sync'}\n\nexport interface WorkflowClient {\n fetch: <T = unknown>(\n query: string,\n params?: Record<string, unknown>,\n options?: WorkflowFetchOptions,\n ) => Promise<T>\n getDocument: <T = SanityDocument>(id: string) => Promise<T | null | undefined>\n patch: (documentId: string) => WorkflowPatch\n /**\n * Create a brand-new document. Errors loud (HTTP 409 / mutation\n * error) if a document with the same `_id` already exists. The engine\n * uses this whenever it mints a new doc — instances on\n * `startInstance`, child instances on spawn, new definitions on first\n * deploy.\n *\n * The interface deliberately omits `createOrReplace`: for existing\n * docs the engine uses `patch().set(...).ifRevisionId(rev).commit()`,\n * which fails fast if the doc was deleted or concurrently modified\n * (createOrReplace's behaviour on a missing target is ambiguous and\n * its rev-less form silently clobbers). If a consumer truly needs\n * createOrReplace they can extend their own client type.\n */\n create: <T extends {_id: string; _type: string}>(\n doc: T,\n options?: WorkflowCommitOptions,\n ) => Promise<T>\n /**\n * Build a multi-document transaction. All operations succeed or fail\n * together. Used whenever the engine writes multiple documents that\n * are provably in the same workflow resource (spawn fan-out, deploy\n * batches, parent + child propagation that stays in one dataset).\n *\n * Shape matches `@sanity/client.transaction()` and the in-memory test\n * client. `patch()` accepts a `WorkflowPatch` handle built via\n * `client.patch(id).set(...).ifRevisionId(rev)` — pass the handle in\n * without calling `.commit()` on it.\n */\n transaction: () => WorkflowTransaction\n /**\n * Optional — present on the real `@sanity/client` and on the test\n * fake (from `@sanity-labs/client-fake-for-test@0.2.0`+). Effect\n * handlers use it to dispatch Content Releases and version actions\n * (`sanity.action.release.publish`, `sanity.action.document.version.create`,\n * etc.) without depending on the broader client surface.\n *\n * Typed loosely so both the strict real-client `Action` union and\n * the test fake's discriminated shape satisfy the state entry. Callers\n * (effect handlers) pass the concrete action object literal.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n action?: (action: any, options?: {tag?: string}) => Promise<any>\n /**\n * Optional — present on the real `@sanity/client`, absent on the\n * in-memory test client. The engine probes for it when auto-resolving\n * ACL grants from an endpoint; absence is the package's signal for\n * \"dry-run mode, don't try to fetch real grants.\"\n */\n request?: <T>(opts: {\n /** Raw URL (host + path). One of `url` / `uri` required. */\n url?: string\n /**\n * Project-scoped path resolved against the `@sanity/client`'s\n * apiHost (e.g. `/users/me` → `https://api.sanity.io/v1/users/me`).\n * Use this for global endpoints like `/users/me`. Mirrors\n * `SanityClient.request({uri})` in `@sanity/client`.\n */\n uri?: string\n signal?: AbortSignal\n /** Optional `?tag=` query for observability — supported by `@sanity/client`. */\n tag?: string\n }) => Promise<T>\n}\n\nexport interface WorkflowTransaction {\n /**\n * Queue a `create` mutation. Fails the transaction on `_id` collision,\n * same as `client.create`.\n */\n create: <T extends {_id: string; _type: string}>(doc: T) => WorkflowTransaction\n /**\n * Queue a patch. Expected argument is a `WorkflowPatch` handle built\n * via `client.patch(id).set(…).ifRevisionId(rev)` — pass it without\n * calling `.commit()`.\n *\n * Typed `any` so the test-client's `TransactionHandle.patch(string |\n * PatchHandle, …)` and `@sanity/client`'s `Transaction.patch(Patch |\n * string, …)` both satisfy the state entry under `strictFunctionTypes`. The\n * engine call site always passes a `WorkflowPatch`; both underlying\n * clients drain it structurally.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n patch: (patch: any) => WorkflowTransaction\n /**\n * Queue a document delete. Deliberately a transaction-only capability —\n * the top-level client surface stays delete-free so no engine code path\n * can casually remove documents; the sole consumer is `deleteDefinition`\n * housekeeping (definition docs + orphaned guard docs). Both the real\n * `@sanity/client` Transaction and the test fake's TransactionHandle\n * carry this shape.\n */\n delete: (id: string) => WorkflowTransaction\n /**\n * Commit the batch. No options — a transaction rides the client's *default*\n * `visibility`: `'sync'` in `@sanity/client` (so a post-spawn `listInstances`\n * GROQ sees freshly-created children), immediate in the in-memory test fake.\n * This is a standing engine assumption — a consumer that configured an\n * `async` default would make spawn read-backs racy. Single-document writes\n * state `'sync'` explicitly via {@link WorkflowCommitOptions}; transactions\n * can't (yet) — the test fake's commit options don't carry `visibility`, and\n * per repo convention that gap is closed upstream in the fake, not worked\n * around here.\n */\n commit: () => Promise<unknown>\n}\n\nexport interface WorkflowPatch {\n set: (props: Record<string, unknown>) => WorkflowPatch\n setIfMissing: (props: Record<string, unknown>) => WorkflowPatch\n unset: (paths: string[]) => WorkflowPatch\n ifRevisionId: (rev: string) => WorkflowPatch\n commit: (options?: WorkflowCommitOptions) => Promise<SanityDocument>\n}\n","/**\n * Shell-side lake-guard lifecycle: deploy and retract `temp.system.guard`\n * documents as a workflow enters and exits stages, and delete them outright\n * once the owning definition is gone (see {@link deleteOrphanedDefinitionGuards}).\n * 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: a loop-back re-enters the stage and re-deploys the real\n * predicate, so the doc must survive. POC simplification; orphan accumulation\n * + 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, WorkflowResource} from './core/refs.ts'\nimport type {Guard, WorkflowDefinition} from './define/schema.ts'\nimport {PartialGuardDeployError} from './engine/results.ts'\nimport {\n assertSingleResource,\n bareIdRefs,\n resolveIdRefTargets,\n resolveMatchTypes,\n resolveMetadata,\n} from './guard-bindings.ts'\nimport {guardsForDefinitionByClient} from './guards-query.ts'\nimport type {MutationGuardDoc} from './types/authorization.ts'\nimport {SYNC_COMMIT, 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, SYNC_COMMIT)\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(SYNC_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 // Guard docs have no transactional multi-write, so track how many landed: if\n // a later guard fails after earlier ones deployed, the partial locks can't be\n // cleanly undone — surface that as {@link PartialGuardDeployError} so the\n // caller escalates to a loud divergence rather than re-throwing a bare error.\n let deployed = 0\n for (const {client, doc} of resolvedStageGuards(args)) {\n try {\n await upsertGuard(client, doc)\n } catch (cause) {\n if (deployed > 0)\n throw new PartialGuardDeployError({stageName: args.stageName, deployed, cause})\n throw cause\n }\n deployed += 1\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(SYNC_COMMIT)\n }\n}\n\nexport interface DeleteOrphanedGuardsArgs {\n client: WorkflowClient\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient\n workflowResource: WorkflowResource\n /** The version-less definition `name` guard docs key on. */\n definition: string\n /** Every deployed version, to span all the datasources its guards named. */\n definitions: WorkflowDefinition[]\n /** Engine-scope tag — only guards minted under this partition are removed. */\n tag: string\n}\n\n/**\n * Remove a definition's guard docs across every datasource its versions\n * statically named — one transaction per resource client. Call once the LAST\n * version is gone: {@link retractStageGuards} already lifted the live\n * predicates as instances left their stages, this clears the now-unreachable\n * docs themselves.\n *\n * Guard docs key on the version-less `sourceDefinition` name and carry no\n * tag, so a same-named workflow in a different-tag partition sharing a\n * datasource surfaces in the same query. Deleting those would drop another\n * partition's live field-locks, so restrict to guards THIS engine registered:\n * their `sourceInstanceId` is an instance id, minted under our tag prefix.\n * The trailing `.` keeps `prod` from matching a `prod-eu` partition.\n */\nexport async function deleteOrphanedDefinitionGuards(\n args: DeleteOrphanedGuardsArgs,\n): Promise<number> {\n const {client, clientForGdr, workflowResource, definition, definitions, tag} = args\n const perClient = await guardsForDefinitionByClient({\n client,\n clientForGdr,\n workflowResource,\n definition,\n definitions,\n })\n const ownPartitionPrefix = `${tag}.`\n let count = 0\n for (const {client: resourceClient, guards} of perClient) {\n const own = guards.filter((guard) => guard.sourceInstanceId.startsWith(ownPartitionPrefix))\n if (own.length === 0) continue\n const tx = resourceClient.transaction()\n for (const guard of own) tx.delete(guard._id)\n await tx.commit()\n count += own.length\n }\n return count\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 * The three-valued result of a condition. GROQ comparisons/arithmetic/derefs\n * against a missing operand yield `null` — a *third* truth value distinct\n * from `false` (\"I can't decide this\", not \"this is false\"). Coercing that\n * `null` to `false` is fail-OPEN for a skip-gate: a missing dependency would\n * silently satisfy \"skip me\". Modeled as one discriminant rather than a\n * `{satisfied, unevaluable}` pair so the illegal \"satisfied AND unevaluable\"\n * state is unrepresentable; callers gate on `'unevaluable'` and fail closed\n * rather than read `'unsatisfied'` as a deliberate `false`.\n */\nexport type ConditionOutcome = 'satisfied' | 'unsatisfied' | 'unevaluable'\n\n/** GROQ's \"can't decide\" — a comparison/arithmetic/deref against a missing or\n * incomparable operand. Distinct from a value that's merely falsy. */\nfunction isUnevaluable(result: unknown): boolean {\n return result === null || result === undefined\n}\n\n/**\n * Evaluate a condition to its three-valued {@link ConditionOutcome}. An\n * absent condition is vacuously `'satisfied'` (e.g. an ungated action). A GROQ\n * `null`/`undefined` result is `'unevaluable'`, never folded into\n * `'unsatisfied'`.\n */\nexport async function evaluateConditionOutcome(\n args: EvaluateConditionArgs,\n): Promise<ConditionOutcome> {\n const {condition, snapshot, params} = args\n if (condition === undefined) return 'satisfied'\n const result = await runGroq(condition, params, snapshot)\n if (isUnevaluable(result)) return 'unevaluable'\n return result ? 'satisfied' : 'unsatisfied'\n}\n\n/**\n * Boolean view of {@link evaluateConditionOutcome} for sites whose\n * unevaluable direction is already the safe one — an undecidable\n * `completeWhen` shouldn't auto-complete, an undecidable `action.filter`\n * shouldn't enable. Both collapse to `false` here. Skip-gates (`task.filter`,\n * transition routing) must use the outcome form and branch on `'unevaluable'`.\n */\nexport async function evaluateCondition(args: EvaluateConditionArgs): Promise<boolean> {\n return (await evaluateConditionOutcome(args)) === 'satisfied'\n}\n\n/**\n * Pre-evaluate the definition's nullary predicates into the params conditions\n * read as `$<name>`. A predicate can't be a plain param (a param is a value,\n * not an expression) and is never macro-spliced — each body is evaluated\n * against the BUILT-IN scope only and its result bound. GROQ is pure, so for\n * boolean predicates this equals inlining; predicates referencing other\n * predicates are rejected at deploy.\n *\n * An unevaluable predicate binds `null` rather than `false`, so GROQ's own\n * three-valued logic carries the undecidability into any condition that reads\n * `$<name>` — a predicate-wrapped gate fails closed exactly like an inline one.\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 | null>> {\n const out: Record<string, boolean | null> = {}\n for (const [name, groq] of Object.entries(args.predicates ?? {})) {\n const result = await runGroq(groq, args.params, args.snapshot)\n out[name] = isUnevaluable(result) ? null : Boolean(result)\n }\n return out\n}\n\n/**\n * Evaluate a task's named requirements over the rendered scope, returning the\n * names whose condition is falsy — the unmet set. All-of by construction (a\n * met requirement contributes nothing); any-of belongs inside a single\n * condition. Declaration order is preserved so a consumer's \"what's\n * outstanding\" list is stable. No requirements means an empty unmet set.\n */\nexport async function evaluateRequirements(args: {\n requirements: Record<string, string> | undefined\n snapshot: HydratedSnapshot\n params: Record<string, unknown>\n}): Promise<string[]> {\n const unmet: string[] = []\n for (const [name, condition] of Object.entries(args.requirements ?? {})) {\n if (!(await evaluateCondition({condition, snapshot: args.snapshot, params: args.params}))) {\n unmet.push(name)\n }\n }\n return unmet\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 * 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 {RequiredStateNotProvidedError} from './engine/results.ts'\nimport {DEFAULT_CONTENT_PERSPECTIVE} from './subscription-documents.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 tag: string\n /**\n * Definition name, for the {@link RequiredStateNotProvidedError} message when\n * a `required` init entry is unfilled. Workflow-scope callers (start/spawn)\n * pass it; stage/task-scope resolution may omit it (the deploy invariant\n * keeps `required` off those scopes, so the check never fires there).\n */\n definitionName?: 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 assertRequiredInitProvided(entryDefs, initialState, ctx.definitionName)\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\n/**\n * Fail fast when a `required` init entry has no caller value — the start/spawn\n * counterpart to action-param validation. Collects every miss so one throw\n * names them all (like {@link RequiredStateNotProvidedError}'s param sibling),\n * rather than failing on the first. Keys on the same name+type as the init read\n * in {@link resolveInitValue}, but is stricter: a present-but-null/undefined\n * value counts as absent here (a required slot needs a real value), whereas\n * {@link resolveInitValue} passes a null fill straight through. The deploy\n * invariant guarantees only workflow-scope `init` entries reach here marked\n * required, so stage/task resolution no-ops.\n */\nfunction assertRequiredInitProvided(\n entryDefs: StateEntry[],\n initialState: InitialStateValue[],\n definitionName: string | undefined,\n): void {\n const missing = entryDefs\n .filter((entry) => entry.required === true && entry.source.type === 'init')\n .filter((entry) => {\n const match = initialState.find((s) => s.name === entry.name && s.type === entry.type)\n return match === undefined || match.value === undefined || match.value === null\n })\n .map((entry) => ({name: entry.name, type: entry.type}))\n if (missing.length === 0) return\n throw new RequiredStateNotProvidedError({\n ...(definitionName !== undefined ? {definition: definitionName} : {}),\n missing,\n })\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 tag: ctx.tag,\n })\n try {\n // Same draft-precedence as doc.ref hydration: with no release the query\n // resolves against drafts overlay published, so a query that resolves the\n // subject (or related content) sees an unpublished/in-flight doc instead\n // of reading published-only and feeding a gate stale/missing data.\n const fetchOptions = {perspective: ctx.perspective ?? DEFAULT_CONTENT_PERSPECTIVE}\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 {type ConditionOutcome, evaluateConditionOutcome, 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\n/**\n * Reload an {@link EngineContext} for a verb commit, threading the optional\n * clock + cross-resource routing carried on {@link EngineCallOptions}. The\n * shared entry the `fireAction` and `editState` retry loops reload through, so\n * the two can't drift in how they wire the clock/router.\n */\nexport function loadCallContext(\n client: WorkflowClient,\n instanceId: string,\n options: {clock?: Clock; clientForGdr?: (parsed: ParsedGdr) => WorkflowClient} | undefined,\n): Promise<EngineContext> {\n return loadContext(client, instanceId, {\n ...(options?.clock ? {clock: options.clock} : {}),\n ...(options?.clientForGdr ? {clientForGdr: options.clientForGdr} : {}),\n })\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\n ? assignedFor(ctx.instance, opts.taskName, opts?.actor, ctx.definition.roleAliases)\n : 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 to its three-valued {@link ConditionOutcome} against\n * the context's hydrated snapshot with the full rendered scope bound. An\n * undefined condition is vacuously satisfied — short-circuited before the\n * scope (and its predicates) is assembled. */\nexport async function ctxEvaluateConditionOutcome(\n ctx: EngineContext,\n condition: string | undefined,\n opts?: ConditionScopeOptions,\n): Promise<ConditionOutcome> {\n if (condition === undefined) return 'satisfied'\n return evaluateConditionOutcome({\n condition,\n snapshot: ctx.snapshot,\n params: await ctxConditionParams(ctx, opts),\n })\n}\n\n/** Boolean view of {@link ctxEvaluateConditionOutcome} — for gates whose\n * unevaluable direction is already safe (don't auto-complete, don't enable).\n * Skip-gates that fail OPEN on a coerced `null` (`task.filter`, transition\n * routing) read the outcome form and branch on `unevaluable`. */\nexport async function ctxEvaluateCondition(\n ctx: EngineContext,\n condition: string | undefined,\n opts?: ConditionScopeOptions,\n): Promise<boolean> {\n return (await ctxEvaluateConditionOutcome(ctx, condition, opts)) === 'satisfied'\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 tag: instance.tag,\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 tag: instance.tag,\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","import {SYNC_COMMIT, type WorkflowClient} from '../types/client.ts'\nimport {PartialGuardDeployError, 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(SYNC_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 // The state move rolled back cleanly, but a partial multi-guard deploy left\n // orphaned locks on the stage we rolled away from — still divergence, so\n // scream rather than re-throwing the bare write error.\n if (guardError instanceof PartialGuardDeployError) {\n throw new WorkflowStateDivergedError({\n instanceId: args.instanceId,\n guardError,\n reason:\n 'a multi-guard deploy partially applied; the rolled-back move left orphaned guard locks',\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","import type {SanityDocument} from '@sanity/types'\n\nimport type {Stage, Task} from '../define/schema.ts'\nimport type {Actor} from '../types/actor.ts'\nimport {SYNC_COMMIT} from '../types/client.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'\nimport {WorkflowStateDivergedError} from './results.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` / `effectsContext` layered on. Guard (re)deployment resolves\n * Sources against this so it sees post-move state — including `effectOutput`\n * values from a just-completed effect — 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 effectsContext: mutation.effectsContext,\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\n .patch(ctx.instance._id)\n .set(set)\n .ifRevisionId(ctx.instance._rev)\n .commit(SYNC_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 // The spawn transaction already committed the parent move + children, so a\n // failure settling a child (prime/cascade/propagate — e.g. its initial-stage\n // guard can't deploy) can't be cleanly undone. Scream divergence at the\n // parent boundary rather than letting a raw child error unwind past the\n // parent's rollback scope — which would leave the parent move committed with\n // the intended scream never raised. A child that already diverged loudly\n // propagates as-is, keeping the most specific instanceId and a single layer.\n try {\n await primeInitialStage(ctx.client, body._id, actorForPriming, ctx.clientForGdr, ctx.clock)\n await cascadeAutoTransitions(\n ctx.client,\n body._id,\n actorForPriming,\n ctx.clientForGdr,\n ctx.clock,\n )\n await propagateToAncestors(ctx.client, body._id, actorForPriming, ctx.clientForGdr, ctx.clock)\n } catch (cause) {\n if (cause instanceof WorkflowStateDivergedError) throw cause\n throw new WorkflowStateDivergedError({\n instanceId: ctx.instance._id,\n guardError: cause,\n reason: `spawned child \"${body._id}\" failed to settle after the spawn transaction committed`,\n })\n }\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","/**\n * Engine-scope tag — the environment partition primitive.\n *\n * Every engine operates against exactly one `tag` (\"test\", \"prod\", …).\n * The tag partitions definitions and instances within a single workflow\n * resource: `deploy(def, tag: \"test\")` and `deploy(def, tag: \"prod\")` are\n * separate deployed workflows with independent lifecycles, and every read\n * is scoped to one tag so test runs never surface in prod.\n *\n * The tag must be Sanity-ID-compatible since it's joined into IDs with\n * `.` — ASCII lowercase + digits + dashes, no leading dash, no dots. It\n * is also the ID prefix for every definition/instance the engine writes.\n *\n * There is no default. The tag selects which environment the engine reads\n * and writes, and the engine enforces nothing — so the partition is the\n * only thing keeping test runs out of prod. Every entry point\n * (`createEngine`, the CLI, the MCP server) requires it explicitly and\n * fails when it's absent rather than guessing an environment.\n */\n\nconst TAG_RE = /^[a-z0-9][a-z0-9-]*$/\n\nexport function validateTag(tag: string): void {\n if (!TAG_RE.test(tag)) {\n throw new Error(\n `tag: invalid tag \"${tag}\" — must match ${TAG_RE.source} (ASCII lowercase + digits + dashes, no leading dash, no dots)`,\n )\n }\n}\n\n/**\n * The engine's read-partition invariant as a GROQ predicate: a document is\n * visible when its `tag` equals the caller's `$tag` param. The single\n * definition of \"tag-scoped\" shared by the engine's internal lookups, the\n * `workflow.query` guard, and the CLI/MCP read helpers.\n */\nexport function tagScopeFilter(): string {\n return 'tag == $tag'\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 tag. With {@link explicit} the query pins `$version`; otherwise\n * it returns the highest deployed version.\n *\n * Params: `$definition`, `$tag`, 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 * subject entry (`doc.ref` or `release.ref`), since discovery scans\n * look for items related 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 {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 {WorkflowClient, 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/**\n * Load an instance by id and assert it is visible to this engine's `tag`.\n * The single definition of instance-visibility: a doc whose `tag` differs\n * from the engine's is a different partition and treated as absent, and a\n * missing doc throws. Every read/operation path funnels through here so the\n * partition contract lives in one place rather than re-inlined per call site.\n */\nexport async function reload(\n client: WorkflowClient,\n instanceId: string,\n tag: string,\n): Promise<WorkflowInstance> {\n const doc = await client.getDocument<WorkflowInstance>(instanceId)\n\n if (!doc) {\n throw new Error(`Workflow instance ${instanceId} not found`)\n }\n\n if (doc.tag !== tag) {\n throw new Error(`Workflow instance ${instanceId} not visible to this engine (tag mismatch)`)\n }\n\n return doc\n}\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 tag: 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 tag: args.tag,\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 {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 resourceFromGdrUri,\n sameResource,\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 {DEFAULT_CONTENT_PERSPECTIVE, entrySubjectRefs} from '../subscription-documents.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, 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.tag)\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, discoveryResource} = 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(\n ctx,\n sub,\n definition,\n parentScope,\n row,\n discoveryResource,\n )\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. Returns the rows plus the\n * `discoveryResource` the scan actually ran against — but only when that\n * was a *foreign* resource (a routed client distinct from the engine's\n * own). {@link projectRowState} uses it to reject `with` projections that\n * would silently mint a child subject in the wrong resource.\n */\nasync function resolveSpawnRows(\n ctx: EngineContext,\n sub: Subworkflows,\n): Promise<{rows: unknown[]; discoveryResource: WorkflowResource | undefined}> {\n const params = buildParams({instance: ctx.instance, now: ctx.now, snapshot: ctx.snapshot})\n const groq = sub.forEach\n\n let value: unknown\n let discoveryResource: WorkflowResource | undefined\n if (groq.includes('*')) {\n // Lake discovery — route through resourceClients in case the GROQ\n // targets a different Sanity resource than the parent. Pick the\n // resource by the first declared subject entry (`doc.ref` or\n // `release.ref`): a release-subject workflow carries only a\n // `release.ref`, whose GDR points at the content resource where the\n // release's version docs live, so discovery must follow it there\n // rather than fall back to the engine's own resource. Authors\n // declaring a different routing target should put that entry first.\n const routingUri = entrySubjectRefs(ctx.instance.state)[0]?.id\n const client = clientForDiscovery(ctx.client, ctx.clientForGdr, routingUri)\n // A routed client (`!== ctx.client`) means the rows came from a\n // foreign resource; an unmapped/absent routing URI falls back to the\n // engine's own client, where bare-id rooting is already correct.\n if (client !== ctx.client && routingUri !== undefined) {\n discoveryResource = resourceFromGdrUri(routingUri)\n }\n value = await discoverItems({\n client,\n groq,\n params,\n // Draft-aware by default (drafts overlay published) when there's no\n // release, so a `forEach` discovers in-flight items the same way the\n // engine reads any other content.\n perspective: ctx.instance.perspective ?? DEFAULT_CONTENT_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 {rows: value, discoveryResource}\n if (value === null || value === undefined) return {rows: [], discoveryResource}\n return {rows: [value], discoveryResource}\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 discoveryResource: WorkflowResource | undefined,\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, {\n parentResource: ctx.instance.workflowResource,\n discoveryResource,\n entryName: name,\n childName: childDefinition.name,\n })\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/** Inputs the spawn-ref coercion needs to root bare ids and to refuse a\n * bare id that would silently land in the wrong resource. */\ninterface SpawnRefContext {\n /** The spawning parent's resource — where a bare id roots. */\n parentResource: WorkflowResource\n /** The foreign resource discovery ran against, if any ({@link resolveSpawnRows}). */\n discoveryResource: WorkflowResource | undefined\n /** The `with` entry + child names, for the fail-loud message. */\n entryName: string\n childName: string\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, and {@link coerceSpawnGdr} fails loud\n * rather than silently rooting a foreign-discovered bare id at the\n * parent. Other kinds pass through unchanged.\n *\n * This is the `with` path only (values projected per discovered `$row`).\n * `subworkflows.context` resolves in the parent scope — its ids are\n * already the parent's canonical GDRs, so the foreign-discovery footgun\n * can't arise there; a non-URI `context` GDR is rejected separately when\n * the child is built ({@link resolveContextHandoff}, {@link prepareChildInstance}).\n */\nfunction canonicaliseSpawnValue(kind: StateKind, value: unknown, cx: SpawnRefContext): unknown {\n if (kind === 'doc.ref') {\n return coerceSpawnGdr(value, cx)\n }\n if (kind === 'doc.refs') {\n if (!Array.isArray(value)) return value\n return value.map((v) => coerceSpawnGdr(v, cx)).filter((v) => v !== null)\n }\n return value\n}\n\n/**\n * A bare spawn id roots at the parent resource. When discovery ran against\n * a different (foreign) resource the row's id belongs *there*, so a\n * parent-rooted GDR would point at a document that doesn't exist — a silent\n * mis-route that spawns children whose own reads find nothing. Fail loud\n * and point the author at the explicit-GDR escape hatch instead.\n */\nfunction assertBareIdRootsCorrectly(id: string, cx: SpawnRefContext): void {\n if (cx.discoveryResource === undefined || sameResource(cx.discoveryResource, cx.parentResource)) {\n return\n }\n throw new Error(\n `subworkflows.with[\"${cx.entryName}\"]: subworkflow \"${cx.childName}\" projected the bare id ` +\n `\"${id}\", which roots at the parent resource \"${cx.parentResource.id}\", but spawn discovery ran ` +\n `against \"${cx.discoveryResource.id}\". The child would reference a document that doesn't exist in ` +\n `the parent resource. Project an explicit GDR URI in the with-GROQ ` +\n `(e.g. \"dataset:<projectId>:<dataset>:\" + _id) so the child's subject points at the resource the ` +\n `discovered rows came from.`,\n )\n}\n\nfunction coerceSpawnGdr(raw: unknown, cx: SpawnRefContext): GlobalDocumentReference | null {\n // Canonicalise a bare doc id into a GDR URI rooted at the parent\n // resource; leave already-canonical URIs untouched. A bare id under\n // foreign discovery is a mis-route — refuse it.\n const toUri = (id: string) => {\n if (isGdrUri(id)) return id\n assertBareIdRootsCorrectly(id, cx)\n return gdrFromResource(cx.parentResource, id)\n }\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 the caller's tag. Picks the highest `version` when\n * 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 tag: string,\n): Promise<(WorkflowDefinition & SanityDocument) | null> {\n const wantsExplicit = typeof ref.version === 'number'\n const params: Record<string, unknown> = {definition: ref.name, tag}\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 tag + workflow resource so it stays\n // visible to whichever engine spawned the parent.\n const childTag = parent.tag\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 = `${childTag}.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 tag: childTag,\n workflowResource,\n definitionName: definition.name,\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 tag: childTag,\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 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","/**\n * The commit-then-(re)deploy chokepoints shared by the transition, action, and\n * effect-completion paths. Kept separate from `stages.ts` so the effect path\n * (`effects.ts`, which `stages.ts` already imports for `queueEffects`) can reuse\n * them without a cyclic import.\n */\n\nimport {deployStageGuards} from '../guards-lifecycle.ts'\nimport type {StageName} from '../types/ids.ts'\nimport type {EngineContext} from './context.ts'\nimport {deployOrRollback} from './guard-commit.ts'\nimport {\n instanceStateFields,\n materializeInstance,\n type MutableInstance,\n persist,\n} from './mutation.ts'\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, action, and\n * effect-completion 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 or an effect's output change that state\n * without a stage move, the engine must refresh the guard so it stays coherent\n * (the \"use the engine, stay consistent\" contract). Idempotent upsert —\n * re-resolves each guard's Sources against the new state via\n * {@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 callers run this through {@link persistThenDeploy}, so a failed re-deploy\n * rolls the state change back rather than leaving it stale. One coherence\n * relaxation: {@link deployStageGuards} no-ops if a concurrent transition moved\n * the instance off `stageName` between the persist and the deploy. The refresh is\n * then correctly skipped (refreshing a left stage would itself be wrong) and the\n * state change stands — `deployOrRollback` sees success, so this is not a\n * 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","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, startMutation} from './mutation.ts'\nimport {persistThenDeploy, refreshStageGuards} from './persist-deploy.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 ...(options?.clientForGdr ? {clientForGdr: options.clientForGdr} : {}),\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 // An effect completing with outputs writes them into `effectsContext`; a guard\n // whose `match`/`metadata` reads one (`$effects['<name>'][.path]`) would\n // otherwise stay stale until a transition re-deploys. One predicate drives both\n // the write and the completion-path refresh so they can never disagree (an\n // empty `outputs: {}` still writes the entry, so it must still refresh).\n const wroteEffectsContext = status === 'done' && outputs !== undefined\n if (wroteEffectsContext) {\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 // Refresh the current stage's guards on the completion path — same fail-loud\n // policy as the action-ops refresh, so a failed refresh rolls the completion back.\n await persistThenDeploy(ctx, mutation, () =>\n wroteEffectsContext\n ? refreshStageGuards(ctx, mutation, ctx.instance.currentStage)\n : Promise.resolve(),\n )\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","/**\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 {HistoryEntry} from '../types/history.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 /** A direct edit through the edit seam (`editState`) rather than an\n * action/transition/activation. */\n edit?: true\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(opAppliedEntry({origin, summary, stage, actor, now}))\n }\n return summaries\n}\n\n/** Build the `opApplied` audit row for one applied op — the boundary origin\n * (action / transition / activation / edit), the op's type + resolved target,\n * and the actor. Kept out of {@link runOps} so its conditional-field\n * assembly doesn't inflate the loop's complexity. */\nfunction opAppliedEntry(args: {\n origin: OpOrigin\n summary: OpAppliedSummary\n stage: StageName\n actor: Actor | undefined\n now: string\n}): Extract<HistoryEntry, {_type: 'opApplied'}> {\n const {origin, summary, stage, actor, now} = args\n return {\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 ...(origin.edit === true ? {edit: true} : {}),\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\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 type {ConditionOutcome} from '../core/eval.ts'\nimport {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 ctxEvaluateConditionOutcome,\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 ...(options?.clientForGdr ? {clientForGdr: options.clientForGdr} : {}),\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 a definite\n * `false` against the stage's entry state is `skipped` (conditional enter —\n * different tasks for different arrivals); the rest start `pending` until\n * activation.\n *\n * An *unevaluable* filter (GROQ `null` — a referenced operand was missing or\n * incomparable) keeps the task in scope rather than skipping it: \"can't\n * decide this gate\" must never collapse to \"skip this gate\", or a missing\n * dependency silently approves whatever the gate was protecting. The\n * undecidability is recorded on {@link TaskEntry.filterEvaluation} so the\n * audit trail tells \"genuinely below threshold\" apart from \"couldn't read it\".\n */\nexport async function buildStageTasks(ctx: EngineContext, stage: Stage): Promise<TaskEntry[]> {\n const entries: TaskEntry[] = []\n for (const task of stage.tasks ?? []) {\n const outcome = await ctxEvaluateConditionOutcome(ctx, task.filter, {taskName: task.name})\n // Skip only on a definite `false`; an unevaluable gate stays in scope.\n const inScope = outcome !== 'unsatisfied'\n entries.push({\n _key: randomKey(),\n name: task.name,\n status: inScope ? 'pending' : 'skipped',\n ...(task.filter !== undefined\n ? {filterEvaluation: buildFilterEvaluation(ctx.now, task.filter, outcome)}\n : {}),\n })\n }\n return entries\n}\n\n/**\n * The audit record for a task's `filter` evaluation. `truthy` reflects the\n * definite boolean; `unevaluable` flags the GROQ-`null` case the engine fails\n * closed on, with a `detail` naming the gate so an operator can see *why* a\n * task that \"should\" have skipped is sitting in scope.\n */\nfunction buildFilterEvaluation(\n at: string,\n filter: string,\n outcome: ConditionOutcome,\n): NonNullable<TaskEntry['filterEvaluation']> {\n if (outcome === 'unevaluable') {\n return {\n at,\n truthy: false,\n unevaluable: true,\n detail: `Filter \"${filter}\" could not be evaluated (GROQ null — a referenced operand was missing or incomparable). Task kept in scope so the gate is not silently skipped.`,\n }\n }\n return {at, truthy: outcome === 'satisfied'}\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 ctxEvaluateConditionOutcome,\n type EngineContext,\n findStage,\n loadContext,\n resolveStageStateEntries,\n} from './context.ts'\nimport {queueEffects} from './effects.ts'\nimport {stageTransitionHistory} from './history-entries.ts'\nimport {materializeInstance, type MutableInstance, startMutation} from './mutation.ts'\nimport {runOps} from './ops.ts'\nimport {persistThenDeploy} from './persist-deploy.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 ...(options?.clientForGdr ? {clientForGdr: options.clientForGdr} : {}),\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\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 — every transition is evaluated on every commit and\n * cascade; the first transition whose `filter` is satisfied (in declaration\n * order) fires. A transition is purely a condition over the rendered scope —\n * routing differences are written into state by actions and read here.\n *\n * An *unevaluable* filter (GROQ `null` — a referenced operand was missing or\n * incomparable) halts selection without firing anything. The engine can't\n * decide whether this conditional route applies, so it must not fall through\n * to a later catch-all and advance the instance past an undecidable gate; the\n * cascade re-runs once the operand resolves.\n */\nasync function pickTransition(ctx: EngineContext, stage: Stage): Promise<Transition | undefined> {\n for (const candidate of stage.transitions ?? []) {\n const outcome = await ctxEvaluateConditionOutcome(ctx, candidate.filter)\n if (outcome === 'satisfied') return candidate\n if (outcome === 'unevaluable') return undefined\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 {SYNC_COMMIT, 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(SYNC_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","/**\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 * Editable state — the shared resolution behind the generic edit seam. The one\n * place that answers \"which declared slots are editable, by whom, right now,\n * and where did the current value come from.\" Both the projection\n * (`evaluateFromSnapshot`, for the reactive UI) and the engine's `editState`\n * commit gate read from here so the soft-gate the UI rendered and the commit\n * re-check can't diverge.\n *\n * The model (EDEX-1319): editability is DECLARED per slot (default off);\n * `scope` is the editable *window* (where the slot is declared — workflow /\n * stage / task); a stage may only TIGHTEN a slot via conjunction; everything\n * here is ADVISORY (the lake guard is the only real lock); and provenance is\n * read straight off the `opApplied` history the op path already stamps.\n */\n\nimport type {\n Editable,\n Stage,\n StateEntry,\n StoredStateRef,\n WorkflowDefinition,\n} from '../define/schema.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {StateScope} from '../types/enums.ts'\nimport type {EditDisabledReason} from '../types/evaluation.ts'\nimport type {TaskName} from '../types/ids.ts'\nimport {findOpenStageEntry} from '../types/instance-state.ts'\nimport type {WorkflowInstance} from '../types/instance.ts'\nimport type {ResolvedStateEntry, StateKind} from '../types/state-values.ts'\nimport {andConditions} from './conditions.ts'\n\n/**\n * Effective editability of a slot in a stage: the slot's own `editable`\n * (the ceiling) ANDed with the stage's tighten-override, if any. Conjunction is\n * what makes the override tighten-only — `false && x` stays closed and adding a\n * predicate can only remove permission, never grant it. `undefined` baseline\n * (slot not declared editable) is closed regardless of any override.\n */\nfunction effectiveEditable(\n baseline: Editable | undefined,\n override: Editable | undefined,\n): Editable | undefined {\n if (baseline === undefined) return undefined\n if (override === undefined) return baseline\n if (baseline === true && override === true) return true\n // At least one side is a predicate; `true` contributes no constraint.\n const parts = [baseline, override].map((e) => (e === true ? undefined : e))\n return andConditions(parts) ?? true\n}\n\n/** A declared slot located in a stage's scope, with its effective editability. */\nexport interface ResolvedSlot {\n scope: StateScope\n /** Present iff `scope === \"task\"` — the task whose state[] holds the slot. */\n task?: TaskName\n name: string\n type: StateKind\n title?: string\n /** The stored reference the op path targets. */\n ref: StoredStateRef\n /** Baseline AND the stage override — `undefined` means not editable here. */\n effective: Editable | undefined\n}\n\ninterface SlotSite {\n scope: StateScope\n task?: TaskName\n entry: StateEntry\n}\n\n/** Every declared state slot reachable for editing in `stage`: workflow-scope,\n * this stage's scope, and this stage's tasks' scope. */\nfunction slotSites(definition: WorkflowDefinition, stage: Stage): SlotSite[] {\n const sites: SlotSite[] = []\n for (const entry of definition.state ?? []) sites.push({scope: 'workflow', entry})\n for (const entry of stage.state ?? []) sites.push({scope: 'stage', entry})\n for (const task of stage.tasks ?? []) {\n for (const entry of task.state ?? []) sites.push({scope: 'task', task: task.name, entry})\n }\n return sites\n}\n\nfunction toResolvedSlot(site: SlotSite, stage: Stage): ResolvedSlot {\n return {\n scope: site.scope,\n ...(site.task !== undefined ? {task: site.task} : {}),\n name: site.entry.name,\n type: site.entry.type,\n ...(site.entry.title !== undefined ? {title: site.entry.title} : {}),\n ref: {scope: site.scope, state: site.entry.name},\n effective: effectiveEditable(site.entry.editable, stage.editable?.[site.entry.name]),\n }\n}\n\n/** The slots a stage declares as editable (baseline `editable` set), each with\n * its effective editability after the stage's tighten-override. */\nexport function editableSlotsInStage(definition: WorkflowDefinition, stage: Stage): ResolvedSlot[] {\n return slotSites(definition, stage)\n .filter((site) => site.entry.editable !== undefined)\n .map((site) => toResolvedSlot(site, stage))\n}\n\n/** An edit-target descriptor (`{scope?, state, task?}`) addressing this slot.\n * An explicit `task` requires a task-scope match; an explicit `scope` must\n * match; a bare name matches any scope (the caller disambiguates lexically). */\nexport function editTargetMatches(\n slot: {scope: StateScope; name: string; task?: string},\n target: {scope?: StateScope; state: string; task?: string},\n): boolean {\n if (slot.name !== target.state) return false\n if (target.task !== undefined) return slot.scope === 'task' && slot.task === target.task\n if (target.scope !== undefined) return slot.scope === target.scope\n return true\n}\n\n/** Lexical precedence for an ambiguous bare-name match: nearest scope wins,\n * task before stage before workflow (mirrors `$state` shadowing). */\nexport const SCOPE_PRECEDENCE: Record<StateScope, number> = {task: 0, stage: 1, workflow: 2}\n\n/** Resolve a single edit target by name (+ optional explicit scope / task).\n * Scope inference, when omitted: an explicit `task` ⇒ task scope; otherwise\n * the nearest declaring scope, stage before workflow (mirrors `$state` reads).\n * Returns `undefined` when no declared slot matches. */\nexport function resolveEditTarget(args: {\n definition: WorkflowDefinition\n stage: Stage\n target: {scope?: StateScope; state: string; task?: string}\n}): ResolvedSlot | undefined {\n const {definition, stage, target} = args\n const found = slotSites(definition, stage)\n .filter((site) =>\n editTargetMatches(\n {\n scope: site.scope,\n name: site.entry.name,\n ...(site.task !== undefined ? {task: site.task} : {}),\n },\n target,\n ),\n )\n .sort((a, b) => SCOPE_PRECEDENCE[a.scope] - SCOPE_PRECEDENCE[b.scope])[0]\n return found ? toResolvedSlot(found, stage) : undefined\n}\n\n/** Whether a slot's scope window is currently open for editing, and a reason\n * string when it isn't. Workflow/stage slots are open while the instance is\n * live; a task-scope slot is open only while its task is `active`. */\nexport function slotWindowOpen(\n instance: WorkflowInstance,\n slot: {scope: StateScope; task?: TaskName},\n): {open: boolean; detail?: string} {\n if (instance.completedAt !== undefined) return {open: false, detail: 'instance completed'}\n if (instance.abortedAt !== undefined) return {open: false, detail: 'instance aborted'}\n if (slot.scope !== 'task') return {open: true}\n const status = findOpenStageEntry(instance)?.tasks.find((t) => t.name === slot.task)?.status\n if (status === 'active') return {open: true}\n return {open: false, detail: `task \"${slot.task}\" is ${status ?? 'not active'}`}\n}\n\n/** The current resolved value of a slot, read from the instance's runtime\n * state[] at the slot's scope. `undefined` when the slot hasn't been resolved\n * yet (e.g. a task-scope slot before its task activated). */\nexport function readSlotValue(\n instance: WorkflowInstance,\n slot: {scope: StateScope; task?: TaskName; name: string},\n): unknown {\n return slotStateHost(instance, slot)?.find((e) => e.name === slot.name)?.value\n}\n\nfunction slotStateHost(\n instance: WorkflowInstance,\n slot: {scope: StateScope; task?: TaskName},\n): ResolvedStateEntry[] | undefined {\n if (slot.scope === 'workflow') return instance.state\n const stageEntry = findOpenStageEntry(instance)\n if (slot.scope === 'stage') return stageEntry?.state\n return stageEntry?.tasks.find((t) => t.name === slot.task)?.state\n}\n\n/**\n * Per-slot provenance, read off the audit trail: the actor and time of the\n * latest `opApplied` history entry that targeted this slot. The op path stamps\n * every state write, so this is the single source of truth — no denormalised\n * copy on the slot. Returns empty when the slot was never written.\n */\nexport function slotProvenance(\n instance: WorkflowInstance,\n ref: StoredStateRef,\n): {setBy?: Actor; setAt?: string} {\n let latest: {actor?: Actor; at: string} | undefined\n for (const entry of instance.history) {\n if (entry._type !== 'opApplied') continue\n if (entry.target?.scope !== ref.scope || entry.target.state !== ref.state) continue\n latest = {at: entry.at, ...(entry.actor !== undefined ? {actor: entry.actor} : {})}\n }\n if (latest === undefined) return {}\n return {\n ...(latest.actor !== undefined ? {setBy: latest.actor} : {}),\n setAt: latest.at,\n }\n}\n\n/**\n * Combine the editability facts into a verdict, first failing gate winning:\n * declared-editable → window open → no denying lake guard → who-may-edit\n * predicate holds. `predicateSatisfied` is the already-evaluated result of the\n * effective predicate for this actor (always `true` when `effective === true`).\n * Returns `undefined` when the actor may edit the slot now.\n */\nexport function editDisabledReason(args: {\n effective: Editable | undefined\n instance: WorkflowInstance\n window: {open: boolean; detail?: string}\n guardDenial: EditDisabledReason | undefined\n predicateSatisfied: boolean\n}): EditDisabledReason | undefined {\n const {effective, instance, window, guardDenial, predicateSatisfied} = args\n if (effective === undefined) return {kind: 'not-editable'}\n if (!window.open) {\n if (instance.completedAt !== undefined) {\n return {kind: 'instance-completed', completedAt: instance.completedAt}\n }\n return {kind: 'edit-window-closed', detail: window.detail ?? 'closed'}\n }\n if (guardDenial !== undefined) return guardDenial\n if (!predicateSatisfied) {\n return {kind: 'editor-not-permitted', predicate: effective === true ? 'true' : effective}\n }\n return undefined\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 {\n editableSlotsInStage,\n editDisabledReason,\n readSlotValue,\n type ResolvedSlot,\n slotProvenance,\n slotWindowOpen,\n} from './core/editability.ts'\nimport {\n evaluateCondition,\n evaluateConditionOutcome,\n evaluatePredicates,\n evaluateRequirements,\n} 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, RoleAliases, Stage, Task, WorkflowDefinition} from './define/schema.ts'\nimport {isTerminalStage} from './engine/stages.ts'\nimport {verdictGuardsForInstance} from './guards-query.ts'\nimport {reload} from './instance.ts'\nimport {grantsPermissionOn} from './permissions.ts'\nimport {hydrateSnapshot} from './snapshot.ts'\nimport {validateTag} 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 EditableSlotEvaluation,\n EditDisabledReason,\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 environment partition — required. */\n tag: 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, tag, 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 validateTag(tag)\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 reload(client, instanceId, tag)\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 roleAliases: definition.roleAliases,\n stageHasExits: !isTerminalStage(stage),\n guardDenial,\n }),\n )\n }\n\n const transitionEvaluations: TransitionEvaluation[] = []\n for (const transition of stage.transitions ?? []) {\n // Three-valued, mirroring the engine: an unevaluable filter is a hold, not\n // a `false` — surfaced so a diagnosis can tell it from a routing dead-end.\n const outcome = await evaluateConditionOutcome({\n condition: transition.filter,\n snapshot,\n params: scope,\n })\n transitionEvaluations.push({\n transition,\n filterSatisfied: outcome === 'satisfied',\n unevaluable: outcome === 'unevaluable',\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 // Edits are the same instance-doc `update` an action commit performs, so the\n // shared guard verdict gates them too; narrow it to the edit-reason shape.\n const editGuardDenial = guardDenial?.kind === 'mutation-guard-denied' ? guardDenial : undefined\n const editableSlots = await evaluateEditableSlots({\n instance,\n definition,\n stage,\n actor,\n snapshot,\n scope,\n guardDenial: editGuardDenial,\n })\n\n return {\n instance,\n definition,\n actor,\n currentStage,\n pendingOnYou,\n canInteract,\n editableSlots,\n }\n}\n\ninterface EvaluateEditableSlotsArgs {\n instance: WorkflowInstance\n definition: WorkflowDefinition\n stage: Stage\n actor: Actor\n snapshot: HydratedSnapshot\n /** The projection's base rendered scope (workflow/stage slots evaluate here). */\n scope: Record<string, unknown>\n /** Shared instance-write guard verdict, precomputed once per evaluation. */\n guardDenial: EditDisabledReason | undefined\n}\n\n/**\n * Project every declared-editable slot in the current scope: its value, this\n * actor's edit verdict (window + who-may-edit predicate + guard pre-flight),\n * and the current value's provenance read off `opApplied` history. The\n * who-may-edit predicate evaluates in the slot's own scope — a task-scope slot\n * sees its task's `$assigned` and lexical `$state` overlay, exactly as that\n * task's actions do.\n */\nasync function evaluateEditableSlots(\n args: EvaluateEditableSlotsArgs,\n): Promise<EditableSlotEvaluation[]> {\n const {instance, definition, stage, actor, snapshot, scope, guardDenial} = args\n const slots: EditableSlotEvaluation[] = []\n for (const slot of editableSlotsInStage(definition, stage)) {\n const window = slotWindowOpen(instance, slot)\n const predicateSatisfied = await editPredicateSatisfied({\n slot,\n window,\n guardDenial,\n instance,\n snapshot,\n scope,\n actor,\n roleAliases: definition.roleAliases,\n })\n const reason = editDisabledReason({\n effective: slot.effective,\n instance,\n window,\n guardDenial,\n predicateSatisfied,\n })\n const value = readSlotValue(instance, slot)\n slots.push({\n scope: slot.scope,\n ...(slot.task !== undefined ? {task: slot.task} : {}),\n name: slot.name,\n type: slot.type,\n ...(slot.title !== undefined ? {title: slot.title} : {}),\n value,\n editable: reason === undefined,\n ...(reason !== undefined ? {disabledReason: reason} : {}),\n ...slotProvenance(instance, slot.ref),\n })\n }\n return slots\n}\n\n/**\n * Whether the slot's effective who-may-edit predicate holds for the actor.\n * Short-circuits the groq-js eval when the verdict can't turn on it — the\n * window is closed or a guard already denies — and when `effective === true`\n * (no predicate to check).\n */\nasync function editPredicateSatisfied(args: {\n slot: ResolvedSlot\n window: {open: boolean}\n guardDenial: EditDisabledReason | undefined\n instance: WorkflowInstance\n snapshot: HydratedSnapshot\n scope: Record<string, unknown>\n actor: Actor\n roleAliases: RoleAliases | undefined\n}): Promise<boolean> {\n const {slot, window, guardDenial, instance, snapshot, scope, actor, roleAliases} = args\n if (!window.open || guardDenial !== undefined) return false\n if (slot.effective === true) return true\n const params =\n slot.scope === 'task' && slot.task !== undefined\n ? taskScopeFor({scope, instance, snapshot, actor, taskName: slot.task, roleAliases})\n : scope\n return evaluateCondition({condition: slot.effective, snapshot, params})\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 /** The definition's role aliasing, for the `$assigned` role match. */\n roleAliases: RoleAliases | undefined\n stageHasExits: boolean\n /** Shared instance-write guard verdict, precomputed once per evaluation. */\n guardDenial: DisabledReason | undefined\n}\n\n/**\n * The rendered scope for a task: the projection's base scope with the task's\n * lexical `$state` overlay layered on and `$assigned` set for this actor.\n * Shared by task-action evaluation and editable task-slot evaluation so both\n * read identically.\n */\nfunction taskScopeFor(args: {\n scope: Record<string, unknown>\n instance: WorkflowInstance\n snapshot: HydratedSnapshot\n actor: Actor\n taskName: string\n roleAliases: RoleAliases | undefined\n}): Record<string, unknown> {\n const {scope, instance, snapshot, actor, taskName, roleAliases} = args\n return {\n ...scope,\n state: {\n ...(scope.state as Record<string, unknown>),\n ...scopedStateOverlay(instance, snapshot, taskName),\n },\n assigned: assignedFor(instance, taskName, actor, roleAliases),\n }\n}\n\nasync function evaluateTask(args: EvaluateTaskArgs): Promise<TaskEvaluation> {\n const {\n task,\n statusEntry,\n instance,\n actor,\n snapshot,\n scope,\n roleAliases,\n stageHasExits,\n guardDenial,\n } = args\n const status: TaskStatus = statusEntry?.status ?? 'pending'\n const taskScope = taskScopeFor({\n scope,\n instance,\n snapshot,\n actor,\n taskName: task.name,\n roleAliases,\n })\n const assigned = taskScope.assigned === true\n\n // Readiness is a task-level fact (requirements are declared on the task), so\n // it's evaluated once here and fanned out to every action — the same shape\n // as the shared instance-write guard verdict.\n const unmetRequirements = await evaluateRequirements({\n requirements: task.requirements,\n snapshot,\n params: taskScope,\n })\n const requirementsReason: DisabledReason | undefined =\n unmetRequirements.length > 0 ? {kind: 'requirements-unmet', unmetRequirements} : undefined\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 requirementsReason,\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 ...(unmetRequirements.length > 0 ? {unmetRequirements} : {}),\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 /** Shared task-readiness verdict, precomputed once per task. */\n requirementsReason: DisabledReason | undefined\n}\n\nasync function evaluateAction(args: EvaluateActionArgs): Promise<ActionEvaluation> {\n const {\n action,\n status,\n instance,\n snapshot,\n taskScope,\n stageHasExits,\n guardDenial,\n requirementsReason,\n } = args\n\n // First failing gate wins, ordered most- to least-fundamental: lifecycle\n // (task/instance/stage state), then the guard pre-flight (a denied instance\n // write dooms every action), then task readiness (declared requirements),\n // then the ONE per-action 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 (requirementsReason !== undefined) return disabled(action, requirementsReason)\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 {tagScopeFilter} 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 tag: string,\n definition: string,\n version: number,\n): string {\n return `${tag}.${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 tag: string,\n workflowResource: WorkflowResource,\n): Promise<WorkflowDefinition[]> {\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 tag,\n workflowResource,\n findInBatch,\n })\n\n return topoSortDefinitions(definitions, {workflowResource, tag, findInBatch})\n}\n\nexport interface 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 * tag. Throws listing every unresolved ref. No-op when all resolve.\n */\nasync function assertCrossBatchRefsDeployed(\n client: WorkflowClient,\n definitions: WorkflowDefinition[],\n ctx: {\n tag: string\n workflowResource: WorkflowResource\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.tag, 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.tag)\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 `tag`, or a human-readable label\n * for the unresolved ref otherwise. */\nasync function resolveDeployedRefLabel(\n client: WorkflowClient,\n ref: LogicalRef,\n tag: string,\n): Promise<string | undefined> {\n const wantsExplicit = typeof ref.version === 'number'\n const params: Record<string, unknown> = {definition: ref.name, tag}\n if (wantsExplicit) params.version = ref.version\n const doc = await client.fetch<(SanityDocument & {tag?: 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 tag: 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.tag, 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/**\n * Collect every spawn 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;\n * exported so `deleteDefinition` can run the inverse check (who still\n * references the definition being deleted).\n */\nexport function 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 tag: string,\n): Promise<WorkflowDefinition> {\n if (version !== undefined) {\n const doc = await client.fetch<(WorkflowDefinition & {tag?: string}) | null>(\n definitionLookupGroq(true),\n {definition, version, tag},\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 tag,\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 tag: string,\n): Promise<DeployedDefinition[]> {\n return client.fetch<DeployedDefinition[]>(\n `*[_type == \"${WORKFLOW_DEFINITION_TYPE}\" && name == $definition && ${tagScopeFilter()}] | order(version desc)`,\n {definition, tag},\n )\n}\n\n/** A definition as fetched back from the lake — the document always carries `_id`. */\nexport type DeployedDefinition = WorkflowDefinition & {_id: string}\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 ...(options?.clientForGdr ? {clientForGdr: options.clientForGdr} : {}),\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","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, loadCallContext} 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 {persistThenDeploy, refreshStageGuards} from './persist-deploy.ts'\nimport {\n type ActionResult,\n CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS,\n ConcurrentFireActionError,\n type EngineCallOptions,\n isRevisionConflict,\n} from './results.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 loadCallContext(client, instanceId, options)\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 {StateScope, TaskStatus, TerminalTaskStatus} from './enums.ts'\nimport type {ActionName, StageName, TaskName} from './ids.ts'\nimport type {WorkflowInstance} from './instance.ts'\nimport type {StateKind} from './state-values.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 | {\n /**\n * The task's declared {@link Task.requirements} aren't all satisfied —\n * the readiness axis. The task is visible and the actor authorized, but\n * its own preconditions don't hold yet. `unmetRequirements` names the\n * failing keys so a consumer can disable the affirmative control and say\n * which precondition is outstanding. Distinct from `filter-failed`\n * (visibility/authorization) and `mutation-guard-denied` (content-write).\n */\n kind: 'requirements-unmet'\n unmetRequirements: 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\n/**\n * Why an editable slot can't be edited by this actor right now — the edit-seam\n * twin of {@link DisabledReason}. First failing gate wins: the slot must be\n * declared editable, its scope window open, no lake guard denying the instance\n * write, and the who-may-edit predicate satisfied. Reuses the shared\n * `mutation-guard-denied` shape — an edit is the same instance-doc `update` an\n * action commit performs, so the same guard pre-flight applies.\n */\nexport type EditDisabledReason =\n | {kind: 'not-editable'}\n | {kind: 'instance-completed'; completedAt: string}\n | {\n /** The slot's scope window is closed: a task-scope slot whose task isn't\n * active, or otherwise out of its editable window. */\n kind: 'edit-window-closed'\n detail: string\n }\n | {\n /** The slot's effective `editable` predicate evaluated falsy for this\n * actor (a role/predicate miss; the stage tighten-override is folded in). */\n kind: 'editor-not-permitted'\n predicate: string\n }\n | Extract<DisabledReason, {kind: 'mutation-guard-denied'}>\n\n/**\n * One declared-editable slot in the current scope, projected for an actor: its\n * resolved value, whether this actor may edit it now (advisory), and the\n * provenance of the current value read off `opApplied` history. The reactive\n * surface a consumer renders as an inline field (the field widget itself is\n * out of scope here — see the slot-component work).\n */\nexport interface EditableSlotEvaluation {\n scope: StateScope\n /** Present iff `scope === \"task\"`. */\n task?: TaskName\n name: string\n type: StateKind\n title?: string\n /** Current resolved value; `undefined` until the slot is first resolved. */\n value: unknown\n /** Whether THIS actor may edit the slot right now (window + predicate + guard). */\n editable: boolean\n /** Present iff `editable === false`. */\n disabledReason?: EditDisabledReason\n /** Actor who last wrote the slot (latest `opApplied`); absent if never written. */\n setBy?: Actor\n /** When the slot was last written (ISO); absent if never written. */\n setAt?: string\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 /**\n * The task's unmet {@link Task.requirements}, by name — present iff at least\n * one is unmet. The task's own readiness summary: a consumer can explain why\n * the whole task is gated without inspecting each action (every action also\n * carries the matching `requirements-unmet` `disabledReason`).\n */\n unmetRequirements?: string[]\n actions: ActionEvaluation[]\n}\n\nexport interface TransitionEvaluation {\n transition: Transition\n /** Whether the transition's filter is definitively satisfied at read time. */\n filterSatisfied: boolean\n /**\n * The filter evaluated to GROQ `null` — a referenced operand was missing or\n * incomparable, so it couldn't be decided. `filterSatisfied` is `false`, but\n * this is a *recoverable hold*, not a deliberate `false`: the engine halts\n * selection (it won't fall through to a later transition) and the cascade\n * re-fires once the operand resolves. Lets a diagnosis tell an undecidable\n * hold apart from a genuine routing dead-end.\n */\n unevaluable: 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 * Declared-editable slots in the current scope (workflow + current stage +\n * its tasks), each with this actor's edit verdict and the current value's\n * provenance. The reactive edit-seam surface; empty when the workflow\n * declares no editable slots.\n */\n editableSlots: EditableSlotEvaluation[]\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 'requirements-unmet': (r) => `unmet requirement(s): ${r.unmetRequirements.join(', ')}`,\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\n/** Edit-seam twin of {@link ActionDisabledError}: thrown by `editState` when\n * the slot can't be edited by the caller. Carries the structured reason. */\nexport class EditStateDeniedError extends Error {\n readonly reason: EditDisabledReason\n readonly target: {scope: StateScope; state: string; task?: string}\n\n constructor(args: {\n target: {scope: StateScope; state: string; task?: string}\n reason: EditDisabledReason\n }) {\n super(formatEditDisabledReason(args.target, args.reason))\n this.name = 'EditStateDeniedError'\n this.reason = args.reason\n this.target = args.target\n }\n}\n\ntype EditDisabledReasonDetail = {\n [K in EditDisabledReason['kind']]: (reason: Extract<EditDisabledReason, {kind: K}>) => string\n}\n\nconst editDisabledReasonDetail: EditDisabledReasonDetail = {\n 'not-editable': () => 'slot is not declared editable',\n 'instance-completed': (r) => `instance completed at ${r.completedAt}`,\n 'edit-window-closed': (r) => `edit window closed (${r.detail})`,\n 'editor-not-permitted': (r) => `editor not permitted (${r.predicate})`,\n 'mutation-guard-denied': (r) =>\n `blocked by mutation guard(s) [${r.guardIds.join(', ')}]${r.detail ? ` (${r.detail})` : ''}`,\n}\n\nfunction formatEditDisabledReason(\n target: {scope: StateScope; state: string; task?: string},\n reason: EditDisabledReason,\n): string {\n const detail = (editDisabledReasonDetail[reason.kind] as (r: EditDisabledReason) => string)(\n reason,\n )\n const where = target.task !== undefined ? `${target.task}.${target.state}` : target.state\n return `State \"${target.scope}:${where}\" is not editable: ${detail}`\n}\n","import {\n editDisabledReason,\n resolveEditTarget,\n type ResolvedSlot,\n slotWindowOpen,\n} from '../core/editability.ts'\nimport {selfGdr} from '../core/refs.ts'\nimport type {Op} from '../define/schema.ts'\nimport {advisoryCan} from '../evaluate.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {StateScope} from '../types/enums.ts'\nimport {EditStateDeniedError} from '../types/evaluation.ts'\nimport {ctxEvaluateCondition, type EngineContext, findStage, loadCallContext} from './context.ts'\nimport {startMutation} from './mutation.ts'\nimport {isStateOp, runOps} from './ops.ts'\nimport {persistThenDeploy, refreshStageGuards} from './persist-deploy.ts'\nimport {\n CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS,\n ConcurrentEditStateError,\n type EditStateResult,\n type EngineCallOptions,\n isRevisionConflict,\n} from './results.ts'\n\n/**\n * The generic edit seam (EDEX-1319). `editState` writes a declared-editable\n * slot directly — reassign, reschedule, claim-by-hand, append to a log —\n * without a bespoke action per field. It is NOT a raw patch: the edit applies\n * as a `state.*` op through the shared op path (so it stamps `opApplied`\n * provenance + history), gates on the slot's declared editability the same way\n * an action gates on its filter, then refreshes the stage's guards and lets the\n * caller cascade. Editing a value a transition reads can and should move the\n * instance — that rippling is intended.\n *\n * Gating is ONE mechanism (advisory, like every engine check): the slot's\n * effective `editable` predicate over the rendered scope. The lake ACL + guards\n * are the only hard locks.\n */\nexport type EditMode = 'set' | 'append' | 'unset'\n\nexport interface EditStateTarget {\n /** Omit to resolve lexically (task slot if `task` set, else stage then workflow). */\n scope?: StateScope\n state: string\n /** Required to address a task-scope slot. */\n task?: string\n}\n\n/**\n * Reload + commit under `ifRevisionId`, reloading and re-gating on a lost race\n * (mirrors `fireAction`). A non-conflict failure — not editable, denied,\n * unknown slot — throws immediately, before any mutation.\n */\nexport async function editState(args: {\n client: WorkflowClient\n instanceId: string\n target: EditStateTarget\n mode?: EditMode\n value?: unknown\n options?: EngineCallOptions\n}): Promise<EditStateResult> {\n const {client, instanceId, target, mode = 'set', value, options} = args\n for (let attempt = 1; attempt <= CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS; attempt++) {\n const ctx = await loadCallContext(client, instanceId, options)\n try {\n return await commitEdit(ctx, target, mode, value, options)\n } catch (error) {\n if (!isRevisionConflict(error)) throw error\n // Lost the optimistic-locking race — reload and retry.\n }\n }\n throw new ConcurrentEditStateError({\n instanceId,\n target: labelTarget(target),\n attempts: CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS,\n })\n}\n\nasync function commitEdit(\n ctx: EngineContext,\n target: EditStateTarget,\n mode: EditMode,\n value: unknown,\n options: EngineCallOptions | undefined,\n): Promise<EditStateResult> {\n const actor = options?.actor\n const stage = findStage(ctx.definition, ctx.instance.currentStage)\n const slot = resolveEditTarget({definition: ctx.definition, stage, target})\n if (slot === undefined) {\n throw new Error(\n `No state slot \"${describeTarget(target)}\" resolves in current stage \"${stage.name}\" of ${ctx.definition.name}`,\n )\n }\n await assertSlotEditable(ctx, slot, options)\n\n const op = buildEditOp(slot, mode, value)\n const mutation = startMutation(ctx.instance)\n const ranOps = runOps({\n ops: [op],\n mutation,\n stage: stage.name,\n origin: {\n edit: true,\n ...(slot.scope === 'task' && slot.task !== undefined ? {task: slot.task} : {}),\n },\n params: {},\n actor,\n self: selfGdr(ctx.instance),\n now: ctx.now,\n })\n\n // An edit can change state a stage guard reads, so refresh the stage's guards\n // (rolling the commit back if the refresh fails), exactly like an action op.\n await persistThenDeploy(ctx, mutation, () =>\n ranOps.some(isStateOp) ? refreshStageGuards(ctx, mutation, stage.name) : Promise.resolve(),\n )\n\n return {\n edited: true,\n target: slotTarget(slot),\n ...(ranOps.length > 0 ? {ranOps} : {}),\n }\n}\n\n/**\n * Re-gate the edit against fresh state (the reload loop may have moved it):\n * declared editable, scope window open, who-may-edit predicate holds. Throws a\n * structured {@link EditStateDeniedError} if not — no mutation begins. The lake\n * guard pre-flight rides the API soft-gate + the commit's own guard refresh, so\n * it isn't re-evaluated here (mirrors `fireAction`, which re-checks only its\n * filter at commit).\n */\nasync function assertSlotEditable(\n ctx: EngineContext,\n slot: ResolvedSlot,\n options: EngineCallOptions | undefined,\n): Promise<void> {\n const actor = options?.actor\n const window = slotWindowOpen(ctx.instance, slot)\n const can =\n options?.grants !== undefined && actor !== undefined\n ? await advisoryCan(ctx.instance, actor, options.grants)\n : undefined\n const predicateSatisfied =\n window.open && slot.effective !== true && slot.effective !== undefined\n ? await ctxEvaluateCondition(ctx, slot.effective, {\n ...(slot.task !== undefined ? {taskName: slot.task} : {}),\n ...(actor !== undefined ? {actor} : {}),\n ...(can !== undefined ? {vars: {can}} : {}),\n })\n : slot.effective === true\n const reason = editDisabledReason({\n effective: slot.effective,\n instance: ctx.instance,\n window,\n guardDenial: undefined,\n predicateSatisfied,\n })\n if (reason !== undefined) throw new EditStateDeniedError({target: slotTarget(slot), reason})\n}\n\nfunction buildEditOp(slot: ResolvedSlot, mode: EditMode, value: unknown): Op {\n if (mode === 'unset') return {type: 'state.unset', target: slot.ref}\n if (value === undefined) {\n throw new Error(`editState mode \"${mode}\" requires a value for slot \"${slot.name}\"`)\n }\n return {\n type: mode === 'append' ? 'state.append' : 'state.set',\n target: slot.ref,\n value: {type: 'literal', value},\n }\n}\n\nfunction slotTarget(slot: ResolvedSlot): {scope: StateScope; state: string; task?: string} {\n return {\n scope: slot.scope,\n state: slot.name,\n ...(slot.task !== undefined ? {task: slot.task} : {}),\n }\n}\n\nfunction labelTarget(target: EditStateTarget): {scope: StateScope; state: string; task?: string} {\n return {\n scope: target.scope ?? (target.task !== undefined ? 'task' : 'workflow'),\n state: target.state,\n ...(target.task !== undefined ? {task: target.task} : {}),\n }\n}\n\nfunction describeTarget(target: EditStateTarget): string {\n const where = target.task !== undefined ? `${target.task}.${target.state}` : target.state\n return target.scope !== undefined ? `${target.scope}:${where}` : where\n}\n","import {resolveAccess, type WorkflowAccessOverride} from '../access.ts'\nimport type {Clock} from '../clock.ts'\nimport {editTargetMatches, SCOPE_PRECEDENCE} from '../core/editability.ts'\nimport {\n extractDocumentId,\n type GlobalDocumentReference,\n type ParsedGdr,\n type WorkflowResource,\n} from '../core/refs.ts'\nimport type {LoadedDoc} from '../core/snapshot.ts'\nimport {abortInstance as engineAbortInstance} from '../engine/abort.ts'\nimport {fireAction as engineFireAction} from '../engine/actions.ts'\nimport {cascadeAutoTransitions, propagateToAncestors} from '../engine/cascade.ts'\nimport {editState as engineEditState, type EditMode, type EditStateTarget} from '../engine/edit.ts'\nimport type {EngineCallOptions, OpAppliedSummary} from '../engine/results.ts'\nimport {invokeTask as engineInvokeTask} from '../engine/tasks.ts'\nimport {evaluateInstance} from '../evaluate.ts'\nimport {effectsContextEntry, reload} from '../instance.ts'\nimport {validateTag} 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 {\n ActionDisabledError,\n EditStateDeniedError,\n type WorkflowEvaluation,\n} from '../types/evaluation.ts'\nimport {findOpenStageEntry} from '../types/instance-state.ts'\nimport type {WorkflowInstance} from '../types/instance.ts'\nimport type {DispatchResult, 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 the tag, 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 tag: 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 validateTag(args.tag)\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 * The admin abort primitive pair: hard-stop the instance (see\n * {@link engineAbortInstance} for the full contract), then propagate to\n * ancestors so a parent gate waiting on this child re-evaluates. Returns\n * whether the abort fired — `false` means the instance was already\n * terminal, in which case nothing propagates. The single code path for\n * every aborting verb (`workflow.abortInstance`, `deleteDefinition`'s\n * cascade), so the abort contract can't silently diverge between them.\n */\nexport async function abortAndPropagate(args: {\n client: WorkflowClient\n instanceId: string\n reason: string | undefined\n actor: Actor | undefined\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient\n clock: Clock\n}): Promise<boolean> {\n const {client, instanceId, reason, actor, clientForGdr, clock} = args\n const result = await engineAbortInstance({\n client,\n instanceId,\n ...(reason !== undefined ? {reason} : {}),\n options: {...(actor !== undefined ? {actor} : {}), clock, clientForGdr},\n })\n if (result.fired) {\n await propagateToAncestors(client, instanceId, actor, clientForGdr, clock)\n }\n return result.fired\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 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 * The shared body of the soft-gated write verbs (`fireAction`, `editState`):\n * project the instance once from the caller's perspective, run the verb's gate\n * + apply against that projection and the already-loaded `before`, then\n * cascade, reload, and shape the {@link DispatchResult}. The differing middle —\n * which verdict to assert and which engine primitive to apply — is the `apply`\n * callback; the reload → evaluate → cascade → reload → return spine lives here\n * once.\n */\nexport async function dispatchGatedWrite(args: {\n client: WorkflowClient\n tag: string\n workflowResource: WorkflowResource\n instanceId: string\n resourceClients?: ResourceClientResolver\n access: WorkflowAccessOverride\n actor: Actor\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient\n clock: Clock\n before: WorkflowInstance\n apply: (\n before: WorkflowInstance,\n evaluation: WorkflowEvaluation,\n ) => Promise<OpAppliedSummary[] | undefined>\n}): Promise<DispatchResult> {\n const {client, tag, workflowResource, instanceId, resourceClients, access, apply} = args\n // Soft-gate via the same projection a UI renders, reusing the resolved access\n // (no second token/grant round-trip).\n const evaluation = await evaluateInstance({\n client,\n tag,\n workflowResource,\n instanceId,\n access,\n clock: args.clock,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n })\n const ranOps = await apply(args.before, evaluation)\n const cascaded = await cascade(client, instanceId, args.actor, args.clientForGdr, args.clock)\n return {\n instance: await reload(client, instanceId, tag),\n cascaded,\n fired: true,\n ...(ranOps !== undefined ? {ranOps} : {}),\n }\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 * Soft-gate before an edit write: throw {@link EditStateDeniedError} if the\n * projection says the targeted slot can't be edited by the caller. Mirrors\n * {@link assertActionAllowed} — the lake is the real boundary; this surfaces a\n * structured reason first. Silent when no projected slot matches (the slot is\n * undeclared / not editable): the engine commit raises the precise error.\n */\nexport function assertEditAllowed(evaluation: WorkflowEvaluation, target: EditStateTarget): void {\n const slot = evaluation.editableSlots\n .filter((s) => editTargetMatches(s, target))\n .sort((a, b) => SCOPE_PRECEDENCE[a.scope] - SCOPE_PRECEDENCE[b.scope])[0]\n if (slot !== undefined && !slot.editable && slot.disabledReason !== undefined) {\n throw new EditStateDeniedError({\n target: {\n scope: slot.scope,\n state: slot.name,\n ...(slot.task !== undefined ? {task: slot.task} : {}),\n },\n reason: slot.disabledReason,\n })\n }\n}\n\n/**\n * Edit a declared-editable slot against the supplied instance (the edit-seam\n * twin of {@link applyAction}); returns the edit's `ranOps` (if any).\n */\nexport async function applyEdit(args: {\n client: WorkflowClient\n instance: WorkflowInstance\n target: EditStateTarget\n mode?: EditMode\n value?: unknown\n actor: Actor\n grants?: Grant[]\n clock?: Clock\n clientForGdr?: (parsed: ParsedGdr) => WorkflowClient\n}): Promise<Awaited<ReturnType<typeof engineEditState>>['ranOps']> {\n const {client, instance, target, mode, value, actor, grants, clock, clientForGdr} = args\n const result = await engineEditState({\n client,\n instanceId: instance._id,\n target,\n ...(mode !== undefined ? {mode} : {}),\n ...(value !== undefined ? {value} : {}),\n options: buildEngineCallOptions({actor, grants, clock, clientForGdr}),\n })\n return result.ranOps\n}\n\n/** The {@link EngineCallOptions} shape the apply helpers thread into the engine,\n * assembled from a verb's resolved call context. One spot so the action and\n * edit paths can't drift in how they forward actor / grants / clock / router. */\nfunction buildEngineCallOptions(args: {\n actor: Actor\n grants: Grant[] | undefined\n clock: Clock | undefined\n clientForGdr: ((parsed: ParsedGdr) => WorkflowClient) | undefined\n}): EngineCallOptions {\n return {\n actor: args.actor,\n ...(args.grants !== undefined ? {grants: args.grants} : {}),\n ...(args.clock !== undefined ? {clock: args.clock} : {}),\n ...(args.clientForGdr !== undefined ? {clientForGdr: args.clientForGdr} : {}),\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 clientForGdr?: (parsed: ParsedGdr) => WorkflowClient\n}): Promise<Awaited<ReturnType<typeof engineFireAction>>['ranOps']> {\n const {client, instance, task, action, params, actor, grants, clock, clientForGdr} = args\n const options = buildEngineCallOptions({actor, grants, clock, clientForGdr})\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 * `deleteDefinition` — remove a deployed workflow definition from the lake.\n *\n * Definitions are the ONLY thing this operation deletes. Workflow instances\n * are never deleted by any engine code path: with `cascade` the non-terminal\n * instances pinned to the targeted versions are hard-stopped via the same\n * abort primitive as `workflow.abortInstance`, and their documents remain in\n * the lake as the audit record. Without `cascade` the delete refuses while\n * such instances exist.\n *\n * Refuses when a surviving deployed definition — another workflow, or a\n * remaining version of this one — still spawn-references a target\n * (`task.subworkflows.definition`). Deploy validates those refs against the\n * lake, and deleting the target would dangle them. Delete or redeploy the\n * referrer first.\n */\n\nimport {type Clock, type Clocked, wallClock} from '../clock.ts'\nimport type {ParsedGdr} from '../core/refs.ts'\nimport {WORKFLOW_DEFINITION_TYPE} from '../define/schema.ts'\nimport {deleteOrphanedDefinitionGuards} from '../guards-lifecycle.ts'\nimport {tagScopeFilter} from '../tags.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport {WORKFLOW_INSTANCE_TYPE} from '../types/instance.ts'\nimport {type DeployedDefinition, loadDefinitionVersions, refsOf} from './deploy.ts'\nimport {abortAndPropagate, resolveOperationContext} from './operations.ts'\nimport type {DeleteDefinitionArgs, DeleteDefinitionResult} from './types.ts'\n\ntype ClientForGdr = (parsed: ParsedGdr) => WorkflowClient\n\n/**\n * Runs three mutating phases in order with NO rollback between them, so a\n * refused write — an ACL denial on one doc type, a lost optimistic-lock\n * race — leaves a partial result the thrown error does not describe:\n *\n * 1. Abort the cascade's in-flight instances (one write each).\n * 2. Delete the targeted definition docs (one transaction).\n * 3. Once the last version is gone, delete the orphaned guard docs.\n *\n * A throw in phase 1 may leave earlier instances already aborted; a throw\n * in phase 2 leaves every cascade instance aborted while the definition\n * survives; a throw in phase 3 leaves the definition gone but some guard\n * docs behind — inert, since their predicates were already lifted as the\n * instances left their stages. Re-running after any partial failure is\n * safe and converges: already-aborted instances are terminal, so they\n * neither re-block the delete nor abort a second time, and the surviving\n * definition / guard docs are re-targeted cleanly.\n *\n * This widens the documented cross-resource non-atomicity seam into a\n * single verb. Surfacing a post-commit failure as a partial\n * {@link DeleteDefinitionResult} rather than a throw is left to a follow-up.\n */\nexport async function deleteDefinition(\n args: Clocked<DeleteDefinitionArgs>,\n): Promise<DeleteDefinitionResult> {\n const {client, tag, definition, version, cascade, reason} = args\n const {actor, clientForGdr} = await resolveOperationContext(args)\n const clock = args.clock ?? wallClock\n\n const versions = await loadDefinitionVersions(client, definition, tag)\n if (versions.length === 0) {\n throw new Error(`No deployed definition for workflow ${definition}`)\n }\n const targets = version === undefined ? versions : versions.filter((d) => d.version === version)\n if (targets.length === 0) {\n throw new Error(`Workflow definition ${definition} v${version} not deployed`)\n }\n const lastVersionGoes = targets.length === versions.length\n\n await assertNoSpawnReferrers(client, tag, definition, targets, lastVersionGoes)\n\n const instanceIds = await nonTerminalInstanceIds(client, tag, definition, version)\n if (instanceIds.length > 0 && cascade !== true) {\n throw new Error(\n `Cannot delete ${definition}: ${instanceIds.length} non-terminal instance(s) exist ` +\n `(${previewIds(instanceIds)}). Pass cascade to abort them first — ` +\n `instances are aborted in place, never deleted.`,\n )\n }\n const abortedInstanceIds = await abortInstances({\n client,\n instanceIds,\n reason,\n actor,\n clientForGdr,\n clock,\n })\n\n const tx = client.transaction()\n for (const target of targets) tx.delete(target._id)\n await tx.commit()\n\n const deletedGuardCount = lastVersionGoes\n ? await deleteOrphanedDefinitionGuards({\n client,\n clientForGdr,\n workflowResource: args.workflowResource,\n definition,\n definitions: versions,\n tag,\n })\n : 0\n\n return {\n name: definition,\n deletedVersions: targets.map((d) => d.version),\n abortedInstanceIds,\n deletedGuardCount,\n }\n}\n\n/**\n * Refuse while any surviving deployed definition spawn-references a target.\n * Survivors are everything deployed in tag scope minus the targets\n * themselves — including remaining versions of the SAME workflow, whose\n * version-pinned self-refs would dangle just like a foreign ref. A\n * version-pinned ref blocks deleting exactly that version; a version-less\n * (or `latest`) ref resolves to the highest deployed version at spawn time,\n * so it only blocks deleting the LAST version.\n */\nasync function assertNoSpawnReferrers(\n client: WorkflowClient,\n tag: string,\n definition: string,\n targets: DeployedDefinition[],\n lastVersionGoes: boolean,\n): Promise<void> {\n const deployed = await client.fetch<DeployedDefinition[]>(\n `*[_type == \"${WORKFLOW_DEFINITION_TYPE}\" && ${tagScopeFilter()}]`,\n {tag},\n )\n const targetIds = new Set(targets.map((d) => d._id))\n const targetVersions = new Set(targets.map((d) => d.version))\n const referrers = deployed\n .filter((d) => !targetIds.has(d._id))\n .filter((d) =>\n refsOf(d).some(\n (ref) =>\n ref.name === definition &&\n (typeof ref.version === 'number' ? targetVersions.has(ref.version) : lastVersionGoes),\n ),\n )\n if (referrers.length > 0) {\n const names = referrers.map((d) => `${d.name} v${d.version}`).join(', ')\n throw new Error(\n `Cannot delete ${definition}: still spawn-referenced by deployed definition(s) ${names}. ` +\n `Delete or redeploy the referrer(s) first.`,\n )\n }\n}\n\n/** Ids of in-flight instances the delete must abort (or refuse over). */\nasync function nonTerminalInstanceIds(\n client: WorkflowClient,\n tag: string,\n definition: string,\n version: number | undefined,\n): Promise<string[]> {\n const versionFilter = version === undefined ? '' : ' && pinnedVersion == $version'\n const docs = await client.fetch<Array<{_id: string}>>(\n `*[_type == \"${WORKFLOW_INSTANCE_TYPE}\" && definition == $definition && ${tagScopeFilter()} ` +\n `&& !defined(completedAt)${versionFilter}] | order(_id asc){_id}`,\n {definition, tag, ...(version !== undefined ? {version} : {})},\n )\n return docs.map((doc) => doc._id)\n}\n\n/**\n * Hard-stop each instance via the shared {@link abortAndPropagate}\n * primitive pair. A concurrent terminal race returns `false` and is\n * skipped silently — the instance is already where the delete needs it.\n */\nasync function abortInstances(args: {\n client: WorkflowClient\n instanceIds: string[]\n reason: string | undefined\n actor: Actor | undefined\n clientForGdr: ClientForGdr\n clock: Clock\n}): Promise<string[]> {\n const {client, instanceIds, reason, actor, clientForGdr, clock} = args\n const aborted: string[] = []\n for (const instanceId of instanceIds) {\n const fired = await abortAndPropagate({client, instanceId, reason, actor, clientForGdr, clock})\n if (fired) aborted.push(instanceId)\n }\n return aborted\n}\n\nfunction previewIds(ids: string[]): string {\n const head = ids.slice(0, 3).join(', ')\n return ids.length > 3 ? `${head}, …` : head\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 {availableActions, type AvailableActionsResult} from '../available-actions.ts'\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 {\n diagnoseInputFromEvaluation,\n diagnoseInstance,\n remediationsFor,\n type DiagnoseResult,\n} from '../diagnostics.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 {\n guardsForDefinition as queryGuardsForDefinition,\n guardsForInstance as queryGuardsForInstance,\n verdictGuardsForInstance,\n} from '../guards-query.ts'\nimport {buildInstanceBase, reload} 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 {tagScopeFilter, validateTag} from '../tags.ts'\nimport type {MutationGuardDoc} from '../types/authorization.ts'\nimport {SYNC_COMMIT, 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 {deleteDefinition as deleteDefinitionInternal} from './delete-definition.ts'\nimport {\n definitionDocId,\n isDefinitionUnchanged,\n loadDefinition,\n loadDefinitionVersions,\n sortByDependencies,\n} from './deploy.ts'\nimport {\n abortAndPropagate,\n applyAction,\n applyEdit,\n assertActionAllowed,\n assertEditAllowed,\n bareIdFromSpawnRef,\n buildClientForGdr,\n cascade,\n dispatchGatedWrite,\n resolveOperationContext,\n toEffectsContextEntries,\n} from './operations.ts'\nimport type {\n AbortInstanceArgs,\n CompleteEffectArgs,\n DeleteDefinitionArgs,\n DeleteDefinitionResult,\n DeployDefinitionResult,\n DeployDefinitionsArgs,\n DeployDefinitionsResult,\n DispatchResult,\n EditStateArgs,\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, tag, workflowResource, definitions} = args\n validateTag(tag)\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, tag, 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 tx = client.transaction()\n let hasWrites = false\n for (const def of ordered) {\n const id = definitionDocId(workflowResource, tag, def.name, def.version)\n const expected = {\n ...def,\n _id: id,\n _type: WORKFLOW_DEFINITION_TYPE,\n tag,\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 (existing && existing.tag === tag && isDefinitionUnchanged(existing, expected)) {\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 * Remove a deployed workflow definition (all versions, or one via\n * `version`). Refuses while non-terminal instances exist unless\n * `cascade` aborts them first — instances are never deleted, only\n * aborted in place; see {@link deleteDefinitionInternal} for the\n * full contract (spawn-referrer check, guard-doc housekeeping).\n */\n deleteDefinition: async (\n args: Clocked<DeleteDefinitionArgs>,\n ): Promise<DeleteDefinitionResult> => {\n return deleteDefinitionInternal(args)\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 tag,\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, tag)\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 ?? `${tag}.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 tag,\n workflowResource,\n definitionName: definition.name,\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 tag,\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, SYNC_COMMIT)\n\n await primeInitialStage(client, id, actor, clientForGdr, clock)\n await cascade(client, id, actor, clientForGdr, clock)\n\n return reload(client, id, tag)\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 tag,\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, tag)\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 return dispatchGatedWrite({\n client,\n tag,\n workflowResource,\n instanceId,\n access,\n actor,\n clientForGdr,\n clock,\n before,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n apply: (instance, evaluation) => {\n assertActionAllowed(evaluation, task, action)\n return applyAction({\n client,\n instance,\n task,\n action,\n actor,\n ...(access.grants !== undefined ? {grants: access.grants} : {}),\n clock,\n clientForGdr,\n ...(params !== undefined ? {params} : {}),\n })\n },\n })\n },\n\n /**\n * Edit a declared-editable state slot directly — reassign, reschedule,\n * claim-by-hand, append to a running log — through the generic edit seam,\n * instead of a bespoke action per field. Soft-gates on the slot's declared\n * editability (the same projection a UI renders), applies the edit as a\n * `state.*` op (so provenance + history are stamped by the op path),\n * refreshes the stage's guards, then cascades — an edit to a value a\n * transition reads can and should move the instance. Advisory like every\n * engine gate; the lake ACL + guards are the only hard locks.\n *\n * Each call is a discrete COMMIT (a history entry, a guard refresh, a\n * cascade, an `ifRevisionId` write), not a draft patch — so an inline-field\n * UI must bind it to a deliberate boundary (blur / Enter / Save / debounce),\n * never an `onChange` per keystroke.\n */\n editState: async (args: Clocked<EditStateArgs>): Promise<DispatchResult> => {\n const {client, tag, workflowResource, instanceId, target, mode, value, resourceClients} = args\n const {access, actor, clientForGdr} = await resolveOperationContext(args)\n const clock = args.clock ?? wallClock\n const before = await reload(client, instanceId, tag)\n\n return dispatchGatedWrite({\n client,\n tag,\n workflowResource,\n instanceId,\n access,\n actor,\n clientForGdr,\n clock,\n before,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n apply: (instance, evaluation) => {\n assertEditAllowed(evaluation, target)\n return applyEdit({\n client,\n instance,\n target,\n ...(mode !== undefined ? {mode} : {}),\n ...(value !== undefined ? {value} : {}),\n actor,\n ...(access.grants !== undefined ? {grants: access.grants} : {}),\n clock,\n clientForGdr,\n })\n },\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, tag, 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, clientForGdr},\n })\n const cascaded = await cascade(client, instanceId, actor, clientForGdr, clock)\n return {\n instance: await reload(client, instanceId, tag),\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, tag, instanceId} = args\n const {actor, clientForGdr} = await resolveOperationContext(args)\n const clock = args.clock ?? wallClock\n const current = await reload(client, instanceId, tag)\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, tag),\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, tag, instanceId, targetStage, reason} = args\n const {actor, clientForGdr} = await resolveOperationContext(args)\n const clock = args.clock ?? wallClock\n await reload(client, instanceId, tag)\n const result = await engineSetStage({\n client,\n instanceId,\n targetStage,\n ...(reason !== undefined ? {reason} : {}),\n options: {...(actor !== undefined ? {actor} : {}), clock, clientForGdr},\n })\n const cascaded = result.fired\n ? await cascade(client, instanceId, actor, clientForGdr, clock)\n : 0\n return {\n instance: await reload(client, instanceId, tag),\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;\n * see {@link abortAndPropagate} for the abort + ancestor-propagation\n * contract (propagated, not cascaded — the instance is terminal).\n */\n abortInstance: async (args: Clocked<AbortInstanceArgs>): Promise<DispatchResult> => {\n const {client, tag, instanceId, reason} = args\n const {actor, clientForGdr} = await resolveOperationContext(args)\n const clock = args.clock ?? wallClock\n await reload(client, instanceId, tag)\n const fired = await abortAndPropagate({client, instanceId, reason, actor, clientForGdr, clock})\n return {\n instance: await reload(client, instanceId, tag),\n cascaded: 0,\n fired,\n }\n },\n\n /**\n * Fetch a workflow instance by id, scoped to the engine's tag.\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 tag: string\n workflowResource: WorkflowResource\n instanceId: string\n }): Promise<WorkflowInstance> => {\n const {client, tag, instanceId} = args\n validateTag(tag)\n return reload(client, instanceId, tag)\n },\n\n guardsForInstance: async (args: {\n client: WorkflowClient\n tag: string\n workflowResource: WorkflowResource\n instanceId: string\n resourceClients?: ResourceClientResolver\n }): Promise<MutationGuardDoc[]> => {\n const {client, tag, instanceId, resourceClients} = args\n validateTag(tag)\n const instance = await reload(client, instanceId, tag)\n return queryGuardsForInstance({\n client,\n clientForGdr: buildClientForGdr(client, resourceClients),\n instance,\n })\n },\n\n guardsForDefinition: async (args: {\n client: WorkflowClient\n tag: string\n workflowResource: WorkflowResource\n /** The definition's `name`. */\n definition: string\n resourceClients?: ResourceClientResolver\n }): Promise<MutationGuardDoc[]> => {\n const {client, tag, workflowResource, definition, resourceClients} = args\n validateTag(tag)\n const definitions = await loadDefinitionVersions(client, definition, tag)\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 tag bound as\n * `$tag`. 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 `$tag` (e.g. `tag == $tag`). To guard against accidental\n * cross-partition reads, a query that never references `$tag` 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 tag: string\n workflowResource: WorkflowResource\n groq: string\n params?: Record<string, unknown>\n }): Promise<T> => {\n const {client, tag, groq, params} = args\n validateTag(tag)\n // Whole-token match: a substring check would accept unrelated params\n // like $tags / $tagId / $tagName without ever binding the partition,\n // letting an unscoped query slip past the guard it exists to catch.\n if (!/\\$tag\\b/.test(groq)) {\n throw new Error(\n `workflow.query: query must filter on $tag to stay tag-scoped (e.g. \"tag == $tag\"); got: ${groq}`,\n )\n }\n return client.fetch<T>(groq, {...params, tag})\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 tag: 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, tag, instanceId, groq, params, resourceClients} = args\n const clock = args.clock ?? wallClock\n validateTag(tag)\n const instance = await reload(client, instanceId, tag)\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 tag: string\n workflowResource: WorkflowResource\n instanceId: string\n }): Promise<PendingEffect[]> => {\n const inst = await reload(args.client, args.instanceId, args.tag)\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 tag: 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.tag)\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 * Diagnose why an instance is or isn't progressing. Projects the\n * instance (the same read as `evaluate`) and classifies it — terminal,\n * `progressing`, `waiting` (an action is available — healthy), or `stuck`\n * with a structured cause — returning that verdict as a\n * {@link DiagnoseResult} alongside the evaluation it came from, so a\n * consumer can render the supporting evidence without a second projection.\n * Pure read.\n */\n diagnose: async (args: Clocked<EvaluateArgs>): Promise<DiagnoseResult> => {\n const evaluation = await evaluateInstance(args)\n const diagnosis = diagnoseInstance(diagnoseInputFromEvaluation(evaluation))\n return {evaluation, diagnosis, remediations: remediationsFor(diagnosis)}\n },\n\n /**\n * List the actions an actor could fire on an instance's current stage,\n * each flagged `allowed` (with a structured `disabledReason` when not).\n * Projects the instance from the actor's perspective and flattens its\n * tasks' actions. Returns the evaluation alongside the actions so a\n * consumer can read the instance/stage context. Pure read.\n */\n availableActions: async (args: Clocked<EvaluateArgs>): Promise<AvailableActionsResult> => {\n const evaluation = await evaluateInstance(args)\n return {evaluation, actions: availableActions(evaluation.currentStage.tasks)}\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 tag, 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 tag: string\n workflowResource: WorkflowResource\n instanceId: string\n task?: string\n }): Promise<WorkflowInstance[]> => {\n const {client, tag, instanceId, task} = args\n validateTag(tag)\n const parent = await reload(client, instanceId, tag)\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 tag, sorts\n // by startedAt. Beats N `getDocument` roundtrips for fan-outs.\n //\n // Visibility: this read-after-write relies on the spawn transaction\n // committing at the client's default `sync` visibility (see\n // {@link WorkflowTransaction.commit}) — under `async` it could miss a\n // just-spawned child. Every GROQ in the engine shares that assumption;\n // single-document writes now state `sync` explicitly, transactions can't\n // yet (the test fake's commit options lack `visibility`).\n return client.fetch<WorkflowInstance[]>(\n `*[_id in $ids && ${tagScopeFilter()}] | order(startedAt asc)`,\n {ids, tag},\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 {reload} from '../instance.ts'\nimport {tagScopeFilter, validateTag} from '../tags.ts'\nimport type {Actor} from '../types/actor.ts'\nimport {SYNC_COMMIT, type WorkflowClient} from '../types/client.ts'\nimport type {PendingEffect} from '../types/effects.ts'\nimport type {WorkflowInstance} from '../types/instance.ts'\nimport type {DeployedDefinition} from './deploy.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 tag: string\n effectHandlers: Record<string, EffectHandler>\n missingHandler: MissingHandlerPolicy\n logger: LoggerFactory\n}): Promise<VerifyDeployedDefinitionsResult> {\n const {client, tag, effectHandlers, missingHandler, logger} = args\n validateTag(tag)\n const log = logger('verifyDeployedDefinitions')\n const definitions = await client.fetch<DeployedDefinition[]>(\n `*[_type == \"${WORKFLOW_DEFINITION_TYPE}\" && ${tagScopeFilter()}] | order(name asc, version asc)`,\n {tag},\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 tag: 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 tag,\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 validateTag(tag)\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, tag)\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 tag,\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 tag: 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(SYNC_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 type {EditMode, EditStateTarget} from '../engine/edit.ts'\nimport {evaluateFromSnapshot} from '../evaluate.ts'\nimport {reload} from '../instance.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 {\n applyAction,\n applyEdit,\n assertActionAllowed,\n assertEditAllowed,\n buildClientForGdr,\n cascade,\n} 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 /** Edit a declared-editable slot against the held content (the generic edit\n * seam), gated on the held projection, then cascade. */\n editState(args: {\n target: EditStateTarget\n mode?: EditMode\n value?: unknown\n }): Promise<DispatchResult>\n}\n\nexport interface CreateInstanceSessionArgs {\n client: WorkflowClient\n tag: 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, tag, 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 // Cascade after an applied write (content stays overlaid), reload the\n // instance's own changes, and shape the dispatch result. Shared by the\n // intent verbs that always fire (`fireAction` / `editState`); `tick` reports\n // `fired` from the cascade count, so it builds its own result.\n const settleAfterApply = async (\n actor: Actor,\n held: ReadonlyMap<string, LoadedDoc>,\n ranOps: DispatchResult['ranOps'],\n ): Promise<DispatchResult> => {\n const cascaded = await cascade(client, instance._id, actor, clientForGdr, clock, held)\n instance = await reload(client, instance._id, tag)\n return {instance, cascaded, fired: true, ...(ranOps !== undefined ? {ranOps} : {})}\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, tag)\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 clientForGdr,\n ...(grants !== undefined ? {grants} : {}),\n ...(clock !== undefined ? {clock} : {}),\n ...(params !== undefined ? {params} : {}),\n })\n return settleAfterApply(actor, held, ranOps)\n })\n },\n\n editState({target, mode, value}) {\n return commit(async (actor, held) => {\n // Soft-gate on the held projection — the same editable-slot verdict the\n // UI rendered (a non-editable slot throws before any write).\n assertEditAllowed(await evaluateWith(held, heldGuards), target)\n const {grants} = await access()\n const ranOps = await applyEdit({\n client,\n instance,\n target,\n ...(mode !== undefined ? {mode} : {}),\n ...(value !== undefined ? {value} : {}),\n actor,\n clientForGdr,\n ...(grants !== undefined ? {grants} : {}),\n ...(clock !== undefined ? {clock} : {}),\n })\n return settleAfterApply(actor, held, 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 {AvailableActionsResult} from '../available-actions.ts'\nimport type {Clock} from '../clock.ts'\nimport type {WorkflowResource} from '../core/refs.ts'\nimport type {DiagnoseResult} from '../diagnostics.ts'\nimport {type EvaluateArgs, evaluateInstance} from '../evaluate.ts'\nimport {subscriptionDocumentsForInstance, type WatchSet} from '../subscription-documents.ts'\nimport {validateTag} 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 EditStateArgs,\n EffectHandler,\n AbortInstanceArgs,\n DeleteDefinitionArgs,\n DeleteDefinitionResult,\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`, `tag`, `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 /**\n * Engine-scope environment partition (e.g. `\"test\"`, `\"prod\"`). Every\n * definition/instance the engine writes is stamped with this tag and\n * every read is scoped to it. Required and never defaulted — the engine\n * enforces nothing, so the partition is the only thing keeping reads and\n * writes off the wrong environment.\n */\n tag: 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<Args extends {client: WorkflowClient; tag: string; workflowResource: WorkflowResource}> =\n Omit<Args, 'client' | 'tag' | '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 tag: 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 /** Edit a declared-editable state slot directly (the generic edit seam):\n * reassign / reschedule / claim-by-hand / append-to-log, then cascade. */\n editState: (args: Bound<EditStateArgs>) => 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 /** Diagnose why an instance is or isn't progressing — a classified\n * {@link DiagnoseResult} plus the evaluation it was derived from. */\n diagnose: (args: Bound<EvaluateArgs>) => Promise<DiagnoseResult>\n /** The actions firable on the instance's current stage, each flagged\n * allowed/disabled, plus the evaluation they came from. */\n availableActions: (args: Bound<EvaluateArgs>) => Promise<AvailableActionsResult>\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 /** Admin override — remove a deployed definition (instances are only ever aborted, never deleted). */\n deleteDefinition: (args: Bound<DeleteDefinitionArgs>) => Promise<DeleteDefinitionResult>\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. `$tag`\n * is bound for tag-scoped 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 tag 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 + tag. The returned\n * object exposes the same verbs as the `workflow.*` namespace, minus\n * the boilerplate config arguments (client / tag / workflowResource)\n * which are pinned at construction. The `tag` is required — see\n * {@link validateTag} for the accepted shape.\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, resourceClients, clock, tag} = args\n validateTag(tag)\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; tag: string; workflowResource: WorkflowResource},\n >(\n rest: Omit<A, 'client' | 'tag' | 'workflowResource'>,\n ): A =>\n ({\n client,\n tag,\n workflowResource,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n ...(clock !== undefined ? {clock} : {}),\n ...rest,\n }) as A\n\n return {\n client,\n tag,\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 editState: (rest) => workflow.editState(bind<EditStateArgs>(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 diagnose: (rest) => workflow.diagnose(bind<EvaluateArgs>(rest)),\n availableActions: (rest) => workflow.availableActions(bind<EvaluateArgs>(rest)),\n\n setStage: (rest) => workflow.setStage(bind<SetStageArgs>(rest)),\n abortInstance: (rest) => workflow.abortInstance(bind<AbortInstanceArgs>(rest)),\n deleteDefinition: (rest) => workflow.deleteDefinition(bind<DeleteDefinitionArgs>(rest)),\n getInstance: ({instanceId}) =>\n workflow.getInstance({client, tag, workflowResource, instanceId}),\n subscriptionDocumentsForInstance: ({instanceId}) =>\n workflow\n .getInstance({client, tag, workflowResource, instanceId})\n .then(subscriptionDocumentsForInstance),\n instance: (instanceDoc, opts) =>\n createInstanceSession({\n client,\n tag,\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 tag,\n workflowResource,\n instanceId,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n }),\n guardsForDefinition: ({definition}) =>\n workflow.guardsForDefinition({\n client,\n tag,\n workflowResource,\n definition,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n }),\n children: ({instanceId, task}) =>\n workflow.children({\n client,\n tag,\n workflowResource,\n instanceId,\n ...(task !== undefined ? {task} : {}),\n }),\n query: ({groq, params}) =>\n workflow.query({\n client,\n tag,\n workflowResource,\n groq,\n ...(params !== undefined ? {params} : {}),\n }),\n queryInScope: ({instanceId, groq, params}) =>\n workflow.queryInScope({\n client,\n tag,\n workflowResource,\n instanceId,\n groq,\n ...(params !== undefined ? {params} : {}),\n ...(clock !== undefined ? {clock} : {}),\n }),\n listPendingEffects: ({instanceId}) =>\n workflow.listPendingEffects({client, tag, workflowResource, instanceId}),\n findPendingEffects: ({instanceId, claimed, names}) =>\n workflow.findPendingEffects({\n client,\n tag,\n workflowResource,\n instanceId,\n ...(claimed !== undefined ? {claimed} : {}),\n ...(names !== undefined ? {names} : {}),\n }),\n drainEffects: ({instanceId, access}) =>\n drainEffectsInternal({\n client,\n tag,\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 tag,\n effectHandlers,\n missingHandler,\n logger,\n }),\n }\n}\n","// Definition diff — classify a local definition against its deployed\n// counterpart as create / update / unchanged, using the same doc-id minting\n// and no-op verdict that `deployDefinitions` uses. Pure reasoning: callers\n// own the fetch and render the result. Shared so deploy tooling (CLI today,\n// other consumers later) doesn't re-derive the deployed shape by hand.\n\nimport {definitionDocId, isDefinitionUnchanged, stripSystemFields} from './api/deploy.ts'\nimport type {WorkflowResource} from './core/refs.ts'\nimport {WORKFLOW_DEFINITION_TYPE, type WorkflowDefinition} from './define/schema.ts'\nimport type {WorkflowClient} from './types/client.ts'\n\n/** Where a definition deploys: the engine tag it partitions under, and the\n * workflow resource it belongs to. Structurally what `deployDefinitions`\n * receives, minus the definitions themselves. */\nexport interface DeployTarget {\n tag: string\n workflowResource: WorkflowResource\n}\n\nexport interface DiffEntry {\n name: string\n version: number\n status: 'create' | 'update' | 'unchanged'\n docId: string\n expected: Record<string, unknown>\n existing?: Record<string, unknown>\n}\n\n/** The tag-prefixed document id a definition deploys to — the engine's own\n * {@link definitionDocId}, so a diff lines up with what deploy would write. */\nfunction docIdFor(def: WorkflowDefinition, target: DeployTarget): string {\n return definitionDocId(target.workflowResource, target.tag, def.name, def.version)\n}\n\nfunction diffStatus(\n existing: Record<string, unknown> | undefined,\n expected: Record<string, unknown>,\n): DiffEntry['status'] {\n if (existing === undefined) return 'create'\n if (isDefinitionUnchanged(existing, expected)) return 'unchanged'\n return 'update'\n}\n\n/**\n * Compare one local definition against a deployed document (or its\n * absence), classifying it as create / update / unchanged using the\n * engine's own no-op verdict. Pure — callers own the fetch, so the same\n * comparison serves both deploy's exact-docId lookup and `definition\n * diff`'s latest-version query.\n */\nexport function diffEntry(\n def: WorkflowDefinition,\n existingRaw: Record<string, unknown> | undefined,\n target: DeployTarget,\n): DiffEntry {\n const docId = docIdFor(def, target)\n const expected: Record<string, unknown> = {\n ...def,\n _id: docId,\n _type: WORKFLOW_DEFINITION_TYPE,\n tag: target.tag,\n }\n const status = diffStatus(existingRaw, expected)\n const existing = existingRaw ? stripSystemFields(existingRaw) : undefined\n return {\n name: def.name,\n version: def.version,\n status,\n docId,\n expected,\n ...(existing !== undefined ? {existing} : {}),\n }\n}\n\n/** Compare each definition against the deployed doc at its own docId. */\nexport async function computeDiffEntries(\n client: Pick<WorkflowClient, 'getDocument'>,\n defs: WorkflowDefinition[],\n target: DeployTarget,\n): Promise<DiffEntry[]> {\n const entries: DiffEntry[] = []\n for (const def of defs) {\n const existingRaw =\n (await client.getDocument<Record<string, unknown>>(docIdFor(def, target))) ?? undefined\n entries.push(diffEntry(def, existingRaw, target))\n }\n return entries\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":["currentTasks","actorFulfillsRole","v","parseGroq","parse","evaluate","gdrUri","doc","schema","randomKey","isTerminalTaskStatus","WORKFLOW_DEFINITION_TYPE","andConditions","DOCUMENT_VALUE_PERMISSIONS","engineAbortInstance","engineEditState","engineInvokeTask","engineFireAction","cascade","deleteDefinitionInternal","engineCompleteEffect","engineSetStage","queryGuardsForInstance","queryGuardsForDefinition","evaluateGroq"],"mappings":"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"}