@sanity/workflow-engine 0.12.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -0
- package/dist/_chunks-cjs/schema.cjs +809 -119
- package/dist/_chunks-cjs/schema.cjs.map +1 -1
- package/dist/_chunks-es/schema.js +810 -120
- package/dist/_chunks-es/schema.js.map +1 -1
- package/dist/define.cjs +384 -140
- package/dist/define.cjs.map +1 -1
- package/dist/define.d.cts +1996 -11940
- package/dist/define.d.ts +1996 -11940
- package/dist/define.js +385 -140
- package/dist/define.js.map +1 -1
- package/dist/index.cjs +2724 -2064
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +4759 -18067
- package/dist/index.d.ts +4759 -18067
- package/dist/index.js +2766 -2106
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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/field-validation.ts","../src/field-resolution.ts","../src/engine/context.ts","../src/core/bindings.ts","../src/instance.ts","../src/engine/mutation.ts","../src/engine/guard-commit.ts","../src/engine/persist-deploy.ts","../src/engine/effects.ts","../src/engine/history-entries.ts","../src/core/source.ts","../src/engine/ops.ts","../src/tags.ts","../src/definition-query.ts","../src/discover.ts","../src/engine/system-actor.ts","../src/engine/spawn.ts","../src/engine/activities.ts","../src/engine/stages.ts","../src/engine/cascade.ts","../src/permissions.ts","../src/access.ts","../src/activity-kind.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 activities. ActivityEntry is the activity's runtime state\n * (status, who/when, spawned subworkflows). Its `name` matches the\n * authoring `Activity.name`.\n */\n\nimport type {GlobalDocumentReference} from '../core/refs.ts'\nimport type {ActivityStatus} from './enums.ts'\nimport type {ResolvedFieldEntry} from './field-values.ts'\nimport type {StageName, ActivityName} from './ids.ts'\n\nexport interface ActivityEntry {\n _key: string\n /** Matches the authoring `Activity.name`. */\n name: ActivityName\n status: ActivityStatus\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 activity in scope) rather than reading this as a deliberate\n * `false`; `truthy` is `false` here but the activity is NOT skipped.\n */\n unevaluable?: boolean\n detail?: string\n }\n /**\n * Subworkflows started by this activity (via `activity.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 activity's\n * `completeWhen` / `failWhen`.\n */\n spawnedInstances?: GlobalDocumentReference[]\n /** Activity-scoped resolved field entries. Absent until the engine writes to it. */\n fields?: ResolvedFieldEntry[]\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 field entries. */\n fields: ResolvedFieldEntry[]\n activities: ActivityEntry[]\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, field 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 `ValueExpr.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`, `$fields`, `$parent`,\n * `$ancestors`, `$stage`, `$now`, `$effects`, `$activities`, `$allActivitiesDone`,\n * `$anyActivityFailed`. 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, activityName, actor, roleAliases)` — the `$assigned`\n * computation: does the caller match the activity's `assignees`-kind field\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 type {Assignee, ResolvedFieldEntry} from '../types/field-values.ts'\nimport {findOpenStageEntry} from '../types/instance-state.ts'\nimport type {WorkflowInstance} from '../types/instance.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, `$fields` doc-ref reads render the HYDRATED document\n * (`$fields.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 currentActivities = findOpenStageEntry(instance)?.activities ?? []\n return {\n self: selfGdr(instance),\n fields: renderedFields(instance.fields ?? [], 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 /** `$activities` — the current stage's activity rows, statuses included. */\n activities: currentActivities,\n allActivitiesDone: currentActivities.every(\n (activity) => activity.status === 'done' || activity.status === 'skipped',\n ),\n anyActivityFailed: currentActivities.some((activity) => activity.status === 'failed'),\n ...extra,\n }\n}\n\n/**\n * `$fields.<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). Activity- and stage-scope entries ride in via the evaluation\n * context's `extra` ({@link scopedFieldOverlay}) and shadow lexically.\n */\nfunction renderedFields(\n entries: readonly ResolvedFieldEntry[],\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: ResolvedFieldEntry, 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-/activity-scope fields in the current evaluation context —\n * merged over the workflow-scope `$fields` map so inner declarations shadow\n * outer ones, exactly like the deploy-time lexical resolution of writes.\n */\nexport function scopedFieldOverlay(\n instance: WorkflowInstance,\n snapshot: HydratedSnapshot | undefined,\n activityName?: string,\n): Record<string, unknown> {\n const stageEntry = findOpenStageEntry(instance)\n if (stageEntry === undefined) return {}\n const stageFields = renderedFields(stageEntry.fields ?? [], snapshot)\n const activity = activityName\n ? stageEntry.activities.find((t) => t.name === activityName)\n : undefined\n return {...stageFields, ...renderedFields(activity?.fields ?? [], snapshot)}\n}\n\n/**\n * The `$assigned` computation: true iff the caller matches the activity's\n * `assignees`-kind field 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 activityName: string,\n actor: Actor | undefined,\n roleAliases: RoleAliases | undefined,\n): boolean {\n if (actor === undefined) return false\n const activity = findOpenStageEntry(instance)?.activities.find((t) => t.name === activityName)\n const entry = activity?.fields?.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 == $fields.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 `$fields` 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 fields: stripFieldsForLake(params.fields),\n }\n}\n\nfunction stripFieldsForLake(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(stripFieldsForLake)\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] = stripFieldsForLake(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, field-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// Field 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 FIELD_READ = /^\\$fields\\.(\\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 * `\"$fields.<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' || FIELD_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-field-op / effect-completion\n * refresh): the engine bakes the value into the guard doc, so the lake never\n * needs to see `$fields` or `$effects`. Deliberately a tiny reader, not full\n * GROQ: a guard value is `\"$self\"`, `\"$now\"`, `\"$fields.<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 fieldRead = FIELD_READ.exec(expr)\n if (fieldRead !== null) {\n const entry = (ctx.instance.fields ?? []).find((s) => s.name === fieldRead[1])\n const value = entry?.value\n return fieldRead[2] !== undefined ? getPath(value, fieldRead[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 `\"$fields.<name>[.path]\", or \"$effects['<name>'][.path]\" (guards store resolved values; ` +\n `the lake cannot see $fields 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 `$fields`/`$effects`) to workflow fields. */\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, FieldEntry, Activity, 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 * `activity.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.fields ?? []) {\n v.checkEntry(entry, `workflow.fields \"${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}\"): ` +\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 field entry's GROQ. */\n checkEntry: (entry: FieldEntry, 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 + field-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 `field-declared docs). To bring extra docs in scope, declare a \\`doc.ref\\` ` +\n `(or \\`doc.refs\\`) field 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: FieldEntry, label: string) => {\n if (entry.initialValue?.type === 'query') tryParse(entry.initialValue.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\", \"$fields.<name>[.path]\", or \"$effects['<name>'][.path]\" (guards store resolved ` +\n `values; the lake cannot see $fields 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.fields ?? []) {\n v.checkEntry(entry, `stage \"${stage.name}\".fields \"${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 activity of stage.activities ?? []) {\n validateActivity(v, stage.name, activity)\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 validateActivity(v: DefinitionValidator, stageName: string, activity: Activity): void {\n const where = `stage \"${stageName}\" activity \"${activity.name}\"`\n for (const entry of activity.fields ?? []) {\n v.checkEntry(entry, `${where}.fields \"${entry.name}\"`)\n }\n if (activity.filter !== undefined) v.checkCondition(activity.filter, `${where}.filter`)\n if (activity.completeWhen !== undefined)\n v.checkCondition(activity.completeWhen, `${where}.completeWhen`)\n if (activity.failWhen !== undefined) v.checkCondition(activity.failWhen, `${where}.failWhen`)\n for (const [name, groq] of Object.entries(activity.requirements ?? {})) {\n v.checkCondition(groq, `${where}.requirements \"${name}\"`)\n }\n for (const [key, groq] of effectBindings(activity.effects)) {\n v.tryParse(groq, `${where} effect binding \"${key}\"`)\n }\n validateActivityActions(v, activity)\n if (activity.subworkflows !== undefined) validateSubworkflows(v, where, activity.subworkflows)\n}\n\nfunction validateActivityActions(v: DefinitionValidator, activity: Activity): void {\n for (const a of activity.actions ?? []) {\n if (a.filter !== undefined) {\n v.checkCondition(a.filter, `activity \"${activity.name}\" action \"${a.name}\".filter`)\n }\n for (const [key, groq] of effectBindings(a.effects)) {\n v.tryParse(groq, `activity \"${activity.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<Activity['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 activities\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 {ActivityStatus} from './types/enums.ts'\nimport type {\n ActionEvaluation,\n DisabledReason,\n ActivityEvaluation,\n WorkflowEvaluation,\n} from './types/evaluation.ts'\n\nexport interface AvailableAction {\n activity: string\n activityStatus: ActivityStatus\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 an activity — its `allowed`\n * state, structured `disabledReason`, and declared params, tagged with the\n * owning activity. The per-action atom both projections share:\n * {@link availableActions} flattens it across a stage's activities; a consumer\n * that keeps per-activity nesting (e.g. the MCP) maps it over an activity's actions\n * directly, so the verdict shape has a single source. */\nexport function actionVerdict(\n activity: ActivityEvaluation,\n action: ActionEvaluation,\n): AvailableAction {\n return {\n activity: activity.activity.name,\n activityStatus: activity.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 activities into the actions the actor\n * could fire, each carrying whether it's allowed (and why not). */\nexport function availableActions(activities: ActivityEvaluation[]): AvailableAction[] {\n return activities.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 {ActivityStatus} from './types/enums.ts'\nimport type {\n ActivityEvaluation,\n TransitionEvaluation,\n WorkflowEvaluation,\n} from './types/evaluation.ts'\nimport type {Assignee, ResolvedFieldEntry} from './types/field-values.ts'\nimport type {HistoryEntry} from './types/history.ts'\nimport {findOpenStageEntry, type StageEntry} from './types/instance-state.ts'\nimport type {WorkflowInstance} from './types/instance.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 activity looking merely \"active\", so it wins over the activity- and\n * transition-level symptoms it produces. Note an active activity 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-activity'; activity: string}\n | {kind: 'no-transition-fires'}\n /**\n * Every activity 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 activity 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'; activity: string; assignees: Assignee[]; actions: string[]}\n // Healthy in-flight, but not yet actionable: an active activity whose declared\n // requirements aren't all met — the readiness axis. It flips to `waiting`\n // once the preconditions hold (typically when a sibling activity 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'; activity: 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-activity`\n * are not yet callable engine operations — see {@link SuggestedRemediation.available}.\n */\nexport type RemediationVerb =\n | 'retry-effect'\n | 'drain-effects'\n | 'reset-activity'\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 activities: ActivityEvaluation[]\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 activities + 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 activities: evaluation.currentStage.activities,\n transitions: evaluation.currentStage.transitions,\n assignees: Object.fromEntries(\n evaluation.currentStage.activities.map((t) => [\n t.activity.name,\n assigneesOf(stage, t.activity.name),\n ]),\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 an activity in a stage — the runtime half of the\n * \"who is this waiting on\" answer. Empty when the activity is unassigned. */\nfunction assigneesOf(stage: StageEntry | undefined, activityName: string): Assignee[] {\n const entry = stage?.activities.find((t) => t.name === activityName)\n return (entry?.fields ?? [])\n .filter((s): s is Extract<ResolvedFieldEntry, {_type: 'assignees'}> => s._type === 'assignees')\n .flatMap((s) => s.value)\n}\n\n/** An activity that has resolved one way or another — done or skipped. */\nfunction isResolved(status: ActivityStatus): boolean {\n return status === 'done' || status === 'skipped'\n}\n\n/**\n * A failed effect whose origin activity 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 activity 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(\n input.activities.filter((t) => !isResolved(t.status)).map((t) => t.activity.name),\n )\n const effect = [...input.instance.effectHistory]\n .reverse()\n .find(\n (e) => e.status === 'failed' && e.origin.kind === 'activity' && stalled.has(e.origin.name),\n )\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 failedActivityCause(input: DiagnoseInput): StuckCause | undefined {\n const failed = input.activities.find((t) => t.status === 'failed')\n return failed ? {kind: 'failed-activity', activity: failed.activity.name} : undefined\n}\n\n/** An active activity 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 // An activity 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.activities.find(\n (t) =>\n t.status === 'active' &&\n (t.activity.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 activity: active.activity.name,\n assignees: input.assignees[active.activity.name] ?? [],\n actions: (active.activity.actions ?? []).map((a) => a.name),\n }\n}\n\n/** An active activity held by the readiness axis — its declared requirements\n * aren't all met, so none of its actions can fire yet. Requires the activity 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 activity elsewhere; the hold is not a stuck cause. */\nfunction blockedState(input: DiagnoseInput): Extract<Diagnosis, {state: 'blocked'}> | undefined {\n const blocked = input.activities.find(\n (t) =>\n t.status === 'active' &&\n (t.activity.actions ?? []).length > 0 &&\n (t.unmetRequirements ?? []).length > 0,\n )\n if (blocked === undefined) {\n return undefined\n }\n return {\n state: 'blocked',\n activity: blocked.activity.name,\n requirements: blocked.unmetRequirements ?? [],\n assignees: input.assignees[blocked.activity.name] ?? [],\n }\n}\n\n/**\n * Every activity 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.activities.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 activity 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 failedActivityCause(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-activity`, 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-activity':\n return [\n {verb: 'reset-activity', rationale: 'Reset or skip the failed activity.'},\n {\n verb: 'set-stage',\n rationale: 'Move the instance past the failed activity 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 {FieldScope, ActivityStatus} from '../types/enums.ts'\nimport type {StageName, ActivityName} 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 activity: ActivityName\n}\n\nexport interface OpAppliedSummary {\n opType: string\n target?: {scope: FieldScope; field: string}\n resolved?: Record<string, unknown>\n}\n\nexport interface ActionResult {\n fired: boolean\n activity: ActivityName\n action: string\n newStatus?: ActivityStatus\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 activity: ActivityName\n readonly issues: {param: string; reason: string}[]\n constructor(args: {\n action: string\n activity: ActivityName\n issues: {param: string; reason: string}[]\n }) {\n const lines = args.issues.map((i) => ` - ${i.param}: ${i.reason}`).join('\\n')\n super(\n `Action \"${args.action}\" on activity \"${args.activity}\" rejected: invalid params\\n${lines}`,\n )\n this.name = 'ActionParamsInvalidError'\n this.action = args.action\n this.activity = args.activity\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 field 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 RequiredFieldNotProvidedError 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 input fields${where} were not provided:\\n${lines}\\n` +\n `Provide each via \\`initialFields\\` when starting standalone, or via the parent's ` +\n `\\`subworkflows.with\\` when spawned.`,\n )\n this.name = 'RequiredFieldNotProvidedError'\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 activity: ActivityName\n readonly action: string\n readonly attempts: number\n constructor(args: {\n instanceId: string\n activity: ActivityName\n action: string\n attempts: number\n }) {\n super(\n `Action \"${args.action}\" on activity \"${args.activity}\" (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.activity = args.activity\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 activity) 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 `editField` 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 ConcurrentEditFieldError extends Error {\n readonly instanceId: string\n readonly target: {scope: FieldScope; field: string; activity?: string}\n readonly attempts: number\n constructor(args: {\n instanceId: string\n target: {scope: FieldScope; field: string; activity?: string}\n attempts: number\n }) {\n const where =\n args.target.activity !== undefined\n ? `${args.target.activity}.${args.target.field}`\n : args.target.field\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 = 'ConcurrentEditFieldError'\n this.instanceId = args.instanceId\n this.target = args.target\n this.attempts = args.attempts\n }\n}\n\nexport interface EditFieldResult {\n edited: boolean\n target: {scope: FieldScope; field: string; activity?: 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.field.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 {ResolvedFieldEntry} from './field-values.ts'\nimport type {HistoryEntry} from './history.ts'\nimport type {StageName} from './ids.ts'\nimport type {StageEntry} from './instance-state.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 /**\n * Content fingerprint of the pinned definition version (see\n * {@link hashDefinitionContent}). Pinned alongside the version so a consumer\n * can detect a deployed definition that drifted from what this instance\n * started on. Advisory — the engine enforces nothing; this enables detection,\n * not prevention. Absent when the instance was started against a definition\n * deployed before content-addressing (it carried no hash to pin).\n */\n pinnedContentHash?: string\n /** Frozen JSON snapshot of the definition at the moment the instance started. */\n definitionSnapshot: string\n /**\n * Workflow-level resolved field entries.\n * Populated from the workflow definition's `fields[]` declarations plus\n * the caller-supplied `initialFields` 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\", initialValue: { type: \"input\" } }`\n * entry to the workflow definition. Conditions then read it as\n * `$fields.subject`. There is no other subject mechanism.\n */\n fields: ResolvedFieldEntry[]\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 field-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 activities.\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` field 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` field entries, and the **release** docs named by\n * `release.ref` field entries — on the workflow scope and the current stage.\n * Order: self, ancestors, content field entries, release field 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.fields),\n ...entryDocRefs(stage?.fields),\n ...entryReleaseRefs(instance.fields),\n ...entryReleaseRefs(stage?.fields),\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` field 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 * Whether {@link document} is in {@link instance}'s reactive watch-set — the\n * reverse of {@link subscriptionDocumentsForInstance}. Both derive from\n * {@link collectWatchRefs}, the single source of truth, so \"which docs does\n * this instance watch\" and \"which instances watch this doc\" stay in lockstep\n * — the same way {@link hydrateSnapshot}'s load-set does. Matching is on the\n * resource-qualified GDR URI, so a cross-dataset subject (`dataset:A:ds:doc`)\n * never matches a same-id doc in another resource (`dataset:B:ds:doc`).\n *\n * A non-reactive, content-change-driven runtime uses this to decide whether a\n * changed document should re-`tick` an instance it does not hold in memory.\n */\nexport function instanceWatchesDocument(instance: WorkflowInstance, document: GdrUri): boolean {\n return collectWatchRefs(instance).some((ref) => ref.id === document)\n}\n\n/**\n * Pull the {@link GlobalDocumentReference} values out of `doc.ref` /\n * `doc.refs` (content) field entries. Content only — release field entries come\n * from {@link entryReleaseRefs}, so guard discovery (which reads this via\n * `collectEntryDocUris`) stays scoped to content docs.\n */\nexport function entryDocRefs(entries: unknown): GlobalDocumentReference[] {\n return fieldEntries(entries).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 * field 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(entries: unknown): GlobalDocumentReference[] {\n return fieldEntries(entries).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 * field 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(entries: unknown): GlobalDocumentReference[] {\n return fieldEntries(entries).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-field entry array to the `{_type, value}` shape\n * the ref extractors read. Tolerates `unknown` (resolved field entry arrays are\n * polymorphic) and drops non-object entries.\n */\nfunction fieldEntries(entries: unknown): {_type?: string; value?: unknown}[] {\n if (!Array.isArray(entries)) return []\n return entries.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` field entry on\n * the workflow OR the current stage,\n * - or the `system.release` doc named by a `release.ref` field 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/field 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 field-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 field entries and collect every GDR URI mentioned by a\n * `doc.ref` or `doc.refs` field entry's value. The GDR-keyed id list lake\n * guard discovery needs; {@link entryDocRefs} is the typed source.\n */\nexport function collectEntryDocUris(resolvedFieldEntries: unknown): string[] {\n return entryDocRefs(resolvedFieldEntries).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, FieldEntry, 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.fields),\n ...instance.stages.flatMap((stage) => collectEntryDocUris(stage.fields)),\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 `fieldRead` of a field entry whose\n * `initialValue` is a literal GDR — or to the workflow resource (`self`, or a\n * `query`-sourced field entry, which restamps into it). Guards whose resource is\n * only known once an instance exists — reading a `subject` / `input` / otherwise\n * runtime-sourced field 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 * `$fields` read string; the only static non-workflow case is an entry whose\n * declared `initialValue` is a literal GDR. Everything else (`input`,\n * `query`, or working memory) resolves at runtime — the documented\n * per-instance boundary.\n */\nfunction staticIdRefGdr(\n idRef: string,\n stage: Stage,\n definition: WorkflowDefinition,\n): ParsedGdr | undefined {\n const read = /^\\$fields\\.([\\w-]+)/.exec(idRef)\n if (read === null) return undefined\n const seed = entriesInScope(stage, definition).find((e) => e.name === read[1])?.initialValue\n return seed?.type === 'literal' ? gdrFromValue(seed.value) : undefined\n}\n\n/** The statically-declared entries reachable from a stage's guards. */\nfunction entriesInScope(stage: Stage, definition: WorkflowDefinition): readonly FieldEntry[] {\n return [\n ...(definition.fields ?? []),\n ...(stage.fields ?? []),\n ...(stage.activities ?? []).flatMap((activity) => activity.fields ?? []),\n ]\n}\n\n/** Parse a GDR from a literal `initialValue` — 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 (field-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 field-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 field 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 field 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 (`activity.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 an activity'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-field entry-type value validation.\n *\n * Every write into a typed field entry must match the field entry's declared shape.\n * The validator is called at three boundaries:\n *\n * 1. `workflow.op.field.set` — full-value replace on any field entry\n * 2. `workflow.op.field.append` — one-item push on array field entries\n * 3. `resolveDeclaredFields` — init / literal / fieldRead / query\n *\n * `validateFieldValue` checks a complete field entry value against the field entry\n * type's shape. The fixed kinds (scalars, refs, actor/assignee) have static\n * schemas; the compositional kinds (`object` / `array`) build their schema from\n * the entry's declared `fields` / `of` sub-field shapes, recursively.\n *\n * `validateFieldAppendItem` checks a single item against the field entry's\n * row shape (only array field entries support append).\n *\n * Both throw `FieldValueShapeError` with the field entry id, field 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\nimport * as v from 'valibot'\n\nimport type {FieldShape} from '../define/schema.ts'\nimport {isGdrUri} from './refs.ts'\n\nclass FieldValueShapeError 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 `Field entry ${args.mode} shape invalid for \"${args.entryName}\" (${args.entryType}): ${issueText}`,\n )\n this.name = 'FieldValueShapeError'\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\n// Scalars that allow null (write-sourced field 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// date: date-only `YYYY-MM-DD`, no time component (Sanity's `date` shape).\nconst NullableDate = v.union([\n v.null(),\n v.pipe(v.string(), v.regex(/^\\d{4}-\\d{2}-\\d{2}$/, 'must be a `YYYY-MM-DD` date')),\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 for the fixed (non-compositional) kinds, keyed by\n// field entry type. `object` / `array` are absent — they are built from the\n// entry's declared sub-field shapes (see {@link wholeValueSchema}).\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 string: NullableString,\n text: NullableString,\n number: NullableNumber,\n boolean: NullableBoolean,\n date: NullableDate,\n datetime: NullableDateTime,\n url: NullableUrl,\n actor: v.union([v.null(), ActorShape]),\n assignee: v.union([v.null(), AssigneeShape]),\n assignees: v.array(AssigneeShape),\n} as const\n\n/**\n * Schema for one sub-field's VALUE. Leaf kinds reuse the fixed schemas above\n * (a sub-field value may be null — unfilled); compositional kinds recurse into\n * their own `fields` / `of`. An unknown kind can't occur (the schema parse\n * constrains it) but degrades to `v.any()` rather than throwing here.\n */\nfunction shapeValueSchema(shape: FieldShape): v.GenericSchema {\n if (shape.type === 'object') return objectSchema(shape.fields ?? [])\n if (shape.type === 'array') return v.array(objectSchema(shape.of ?? []))\n return (valueSchemas as Record<string, v.GenericSchema>)[shape.type] ?? v.any()\n}\n\n/**\n * A row/object schema from declared sub-field shapes. `looseObject` so each\n * declared sub-field is validated when present but unknown keys pass — `_key`\n * (engine-stamped on append), `_type`, and `audit`-op stamps live alongside\n * the declared fields without a per-row schema rewrite.\n */\nfunction objectSchema(fields: readonly FieldShape[]): v.GenericSchema {\n // Null-prototype map so a sub-field literally named `__proto__` (or\n // `constructor`) registers as an own key instead of hitting the prototype\n // setter and silently dropping its schema — those names pass GROQ_IDENTIFIER.\n const entries: Record<string, v.GenericSchema> = Object.create(null)\n for (const f of fields) entries[f.name] = v.optional(shapeValueSchema(f))\n return v.looseObject(entries)\n}\n\ninterface CompositeShape {\n fields?: readonly FieldShape[] | undefined\n of?: readonly FieldShape[] | undefined\n}\n\nfunction wholeValueSchema(entryType: string, shape: CompositeShape): v.GenericSchema | undefined {\n if (entryType === 'object') return v.union([v.null(), objectSchema(shape.fields ?? [])])\n if (entryType === 'array') return v.array(objectSchema(shape.of ?? []))\n return (valueSchemas as Record<string, v.GenericSchema>)[entryType]\n}\n\n// Per-item schemas for `workflow.op.field.append`. Only array-kind entries\n// support append; `array` items follow the entry's declared `of`.\nfunction appendItemSchema(entryType: string, shape: CompositeShape): v.GenericSchema | undefined {\n if (entryType === 'array') return objectSchema(shape.of ?? [])\n if (entryType === 'doc.refs') return GdrShape\n if (entryType === 'assignees') return AssigneeShape\n return undefined\n}\n\n// Public API.\n\n/**\n * Check a whole-value against its field entry kind WITHOUT throwing — returns\n * the shape issues, or `undefined` when valid. The non-throwing core of\n * {@link validateFieldValue}, used by query-result resolution to *discard*\n * (rather than abort) a lake result that doesn't fit the declared kind.\n */\nexport function checkFieldValue(args: {\n entryType: string\n value: unknown\n fields?: readonly FieldShape[] | undefined\n of?: readonly FieldShape[] | undefined\n}): string[] | undefined {\n const schema = wholeValueSchema(args.entryType, args)\n if (schema === undefined) return [`unknown field entry type ${args.entryType}`]\n const result = v.safeParse(schema, args.value)\n return result.success ? undefined : formatIssues(result.issues)\n}\n\nexport function validateFieldValue(args: {\n entryType: string\n entryName: string\n value: unknown\n fields?: readonly FieldShape[] | undefined\n of?: readonly FieldShape[] | undefined\n}): void {\n const issues = checkFieldValue(args)\n if (issues !== undefined) {\n throw new FieldValueShapeError({\n entryType: args.entryType,\n entryName: args.entryName,\n issues,\n mode: 'value',\n })\n }\n}\n\nexport function validateFieldAppendItem(args: {\n entryType: string\n entryName: string\n item: unknown\n of?: readonly FieldShape[] | undefined\n}): void {\n const schema = appendItemSchema(args.entryType, args)\n if (schema === undefined) {\n throw new FieldValueShapeError({\n entryType: args.entryType,\n entryName: args.entryName,\n issues: [`field entry type ${args.entryType} does not support append`],\n mode: 'item',\n })\n }\n const result = v.safeParse(schema, args.item)\n if (!result.success) {\n throw new FieldValueShapeError({\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 `fields[]` declarations into `ResolvedFieldEntry`s.\n *\n * Shared by:\n * - `workflow.startInstance` (workflow-scope fields)\n * - engine stage entry (stage-scope fields on StageEntry)\n * - engine activity activation (activity-scope fields on ActivityEntry)\n *\n * `initialValue` (FieldSource) semantics:\n * - absent → working memory: defaults to null (scalars) or `[]` (array kinds);\n * ops fill it later.\n * - `type: \"input\"` reads from caller-supplied `initialFields`.\n * - `type: \"literal\"` uses the declared constant.\n * - `type: \"fieldRead\"` copies a sibling/ancestor entry's resolved value.\n * - `type: \"query\"` runs the entry's GROQ against the lake via the\n * supplied client; the result is validated against the entry's declared\n * kind — conforming results land as the value (with `resolvedAt` stamped),\n * a non-conforming result is discarded (default value) and recorded via\n * {@link ResolveFieldContext.recordDiscard}.\n */\n\nimport {checkFieldValue, validateFieldValue} from './core/field-validation.ts'\nimport {paramsForLake} from './core/params.ts'\nimport {getPath} from './core/path.ts'\nimport {gdrFromResource, isGdrUri, type WorkflowResource} from './core/refs.ts'\nimport type {FieldEntry, FieldSource} from './define/schema.ts'\nimport {RequiredFieldNotProvidedError} from './engine/results.ts'\nimport {DEFAULT_CONTENT_PERSPECTIVE} from './subscription-documents.ts'\nimport type {WorkflowClient, WorkflowPerspective} from './types/client.ts'\nimport type {InitialFieldValue, ResolvedFieldEntry} from './types/field-values.ts'\n\n/**\n * Sink the caller supplies to be told a `query`-sourced entry's lake result was\n * discarded (didn't fit the declared kind). The caller owns the instance\n * history + knows the scope, so it turns each into a `fieldQueryDiscarded` row.\n */\nexport type RecordFieldDiscard = (discard: {field: string; detail: string}) => void\n\nexport interface ResolveFieldContext {\n /** Lake client for `type: \"query\"` entry evaluation. Omitted → query\n * field 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`-sourced entries, so\n * field 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 RequiredFieldNotProvidedError} message when\n * a `required` input entry is unfilled. Workflow-scope callers (start/spawn)\n * pass it; stage/activity-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/activity-scope query entries. */\n stageName?: string\n /** Bound to `$activity` inside activity-scope query entries. */\n activityName?: string\n /**\n * Already-resolved field entries in the SAME scope being resolved\n * right now. Exposed to subsequent query-sourced field entries as\n * `$fields.<entryName>`; also the lookup target for\n * `initialValue: { type: \"fieldRead\", scope: \"stage\" }` on a sibling\n * stage-scope entry. Sequential resolution means entry N's seed can\n * read field entries 0..N-1 by id but not later ones.\n */\n resolvedFields?: ResolvedFieldEntry[]\n /**\n * Already-resolved workflow-scope fields. Available when resolving\n * stage- or activity-scope field entries so a `initialValue: { type: \"fieldRead\",\n * scope: \"workflow\" }` can read durable workflow-scope field entries that\n * were resolved at `startInstance` time.\n */\n workflowFields?: ResolvedFieldEntry[]\n /**\n * Resource of the workflow itself. Used to canonicalize raw Sanity\n * reference shapes (`{_ref, _type}`) returned by `type: \"query\"`\n * field 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 * Sink for a `query`-sourced entry whose lake result didn't fit its declared\n * kind and was discarded. The caller (which owns the instance history and\n * knows the scope) turns each into a `fieldQueryDiscarded` audit row, so the\n * discard is visible rather than silent. Omitted → still discards, just not\n * recorded (no caller has a history to write to).\n */\n recordDiscard?: RecordFieldDiscard\n}\n\n/**\n * Derive a read perspective from resolved workflow-scope fields: 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 field entries.\n */\nexport function derivePerspectiveFromFields(\n entries: ResolvedFieldEntry[] | 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 resolveDeclaredFields(args: {\n entryDefs: FieldEntry[] | undefined\n initialFields: InitialFieldValue[]\n ctx: ResolveFieldContext\n randomKey: () => string\n}): Promise<ResolvedFieldEntry[]> {\n const {entryDefs, initialFields, ctx, randomKey} = args\n if (entryDefs === undefined || entryDefs.length === 0) return []\n assertRequiredInputProvided(entryDefs, initialFields, ctx.definitionName)\n const out: ResolvedFieldEntry[] = []\n for (const entry of entryDefs) {\n // Each entry sees the already-resolved ones via `$fields.<entryName>`.\n const scopedCtx: ResolveFieldContext = {...ctx, resolvedFields: out}\n out.push(await resolveOneEntry(entry, initialFields, scopedCtx, randomKey))\n }\n return out\n}\n\n/**\n * Fail fast when a `required` input 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 RequiredFieldNotProvidedError}'s param sibling),\n * rather than failing on the first. Keys on the same name+type as the input read\n * in {@link resolveInputValue}, but is stricter: a present-but-null/undefined\n * value counts as absent here (a required slot needs a real value), whereas\n * {@link resolveInputValue} passes a null fill straight through. The deploy\n * invariant guarantees only workflow-scope `input` entries reach here marked\n * required, so stage/activity resolution no-ops.\n */\nfunction assertRequiredInputProvided(\n entryDefs: FieldEntry[],\n initialFields: InitialFieldValue[],\n definitionName: string | undefined,\n): void {\n const missing = entryDefs\n .filter((entry) => entry.required === true && entry.initialValue?.type === 'input')\n .filter((entry) => {\n const match = initialFields.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 RequiredFieldNotProvidedError({\n ...(definitionName !== undefined ? {definition: definitionName} : {}),\n missing,\n })\n}\n\nconst ARRAY_SLOT_TYPES = new Set<FieldEntry['type']>(['doc.refs', 'array', 'assignees'])\n\n/** Default for an unfilled entry: `[]` for array kinds, `null` otherwise. */\nfunction defaultEntryValue(entryType: FieldEntry['type']): unknown {\n return ARRAY_SLOT_TYPES.has(entryType) ? [] : null\n}\n\n/**\n * Read a caller-supplied `input` 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 `initialFields`. 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 resolveInputValue(\n entry: FieldEntry,\n initialFields: InitialFieldValue[],\n defaultValue: unknown,\n): unknown {\n const initMatch = initialFields.find((s) => s.name === entry.name && s.type === entry.type)\n if (initMatch === undefined) return defaultValue\n assertInputValueShape(entry, initMatch.value)\n return initMatch.value\n}\n\nfunction resolveFieldReadValue(\n source: Extract<FieldSource, {type: 'fieldRead'}>,\n ctx: ResolveFieldContext,\n defaultValue: unknown,\n): unknown {\n const entriesForScope =\n source.scope === 'workflow' ? (ctx.workflowFields ?? []) : (ctx.resolvedFields ?? [])\n const target = entriesForScope.find((s) => s.name === source.field)\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 * `$fields.<entry>.value.id` etc. must be bare too.\n *\n * `$fields` exposes field entries already resolved before this one (sequential\n * resolution). Cyclic references to later field entries produce `undefined` in\n * GROQ and the entry falls through to its default.\n */\nasync function resolveQueryValue(\n entry: FieldEntry,\n source: Extract<FieldSource, {type: 'query'}>,\n ctx: ResolveFieldContext,\n client: WorkflowClient,\n defaultValue: unknown,\n): Promise<unknown> {\n const params = paramsForLake({\n self: ctx.selfId ?? null,\n fields: fieldMapFromResolved(ctx.resolvedFields ?? []),\n stage: ctx.stageName ?? null,\n activity: ctx.activityName ?? 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: FieldEntry,\n initialFields: InitialFieldValue[],\n ctx: ResolveFieldContext,\n defaultValue: unknown,\n): Promise<unknown> {\n const source = entry.initialValue\n if (source === undefined) return defaultValue // working memory — ops fill it later\n if (source.type === 'input') return resolveInputValue(entry, initialFields, defaultValue)\n if (source.type === 'literal') return source.value ?? defaultValue\n if (source.type === 'fieldRead') return resolveFieldReadValue(source, ctx, defaultValue)\n if (source.type === 'query' && ctx.client !== undefined) {\n return resolveQueryValue(entry, source, ctx, ctx.client, defaultValue)\n }\n // \"query\" without a client falls back to the default.\n return defaultValue\n}\n\n/**\n * Build the persisted entry envelope; `query`-sourced entries carry\n * `resolvedAt`, and `object` / `array` entries carry their declared sub-field\n * shape (`fields` / `of`) so the instance is self-describing for op-time\n * validation and rendering.\n */\nfunction buildResolvedEntry(\n entry: FieldEntry,\n value: unknown,\n _key: string,\n now: string,\n): ResolvedFieldEntry {\n return {\n _key,\n _type: entry.type,\n name: entry.name,\n ...(entry.title !== undefined ? {title: entry.title} : {}),\n ...(entry.description !== undefined ? {description: entry.description} : {}),\n value,\n ...(entry.initialValue?.type === 'query' ? {resolvedAt: now} : {}),\n ...(entry.type === 'object' ? {fields: entry.fields ?? []} : {}),\n ...(entry.type === 'array' ? {of: entry.of ?? []} : {}),\n } as ResolvedFieldEntry\n}\n\nasync function resolveOneEntry(\n entry: FieldEntry,\n initialFields: InitialFieldValue[],\n ctx: ResolveFieldContext,\n randomKey: () => string,\n): Promise<ResolvedFieldEntry> {\n const defaultValue = defaultEntryValue(entry.type)\n const value = await resolveEntryValue(entry, initialFields, ctx, defaultValue)\n\n // A query result is lake data resolved at runtime — fail SOFT: if it doesn't\n // fit the declared kind, discard it (fall to the default) and record the\n // discard, rather than aborting materialisation over external data.\n if (entry.initialValue?.type === 'query') {\n const issues = checkFieldValue({\n entryType: entry.type,\n value,\n fields: entry.fields,\n of: entry.of,\n })\n if (issues !== undefined) {\n ctx.recordDiscard?.({field: entry.name, detail: issues.join('; ')})\n return buildResolvedEntry(entry, defaultValue, randomKey(), ctx.now)\n }\n return buildResolvedEntry(entry, value, randomKey(), ctx.now)\n }\n\n // input / literal / fieldRead / working-memory: a shape mismatch is an\n // authoring or caller bug — fail HARD before it leaks into the snapshot.\n validateFieldValue({\n entryType: entry.type,\n entryName: entry.name,\n value,\n fields: entry.fields,\n of: entry.of,\n })\n return buildResolvedEntry(entry, value, randomKey(), ctx.now)\n}\n\n/** Project resolved field entries into the `$fields` shape (entryName → entry envelope). */\nfunction fieldMapFromResolved(entries: ResolvedFieldEntry[]): 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 `initialFields` values for shape correctness\n * BEFORE they hit the persisted instance. Input-sourced doc.ref /\n * doc.refs field 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 assertInputValueShape(entry: FieldEntry, value: unknown): void {\n if (entry.type === 'doc.ref') {\n assertGdrShape(value, `field entry \"${entry.name}\" (doc.ref)`)\n return\n }\n if (entry.type === 'release.ref') {\n assertGdrShape(value, `field 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 input value for field 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 input value for field 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, `field 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 == $fields.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: FieldEntry['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, scopedFieldOverlay} from '../core/params.ts'\nimport {extractDocumentId, type ParsedGdr} from '../core/refs.ts'\nimport type {HydratedSnapshot, LoadedDoc} from '../core/snapshot.ts'\nimport type {Activity, Stage, WorkflowDefinition} from '../define/schema.ts'\nimport {type RecordFieldDiscard, resolveDeclaredFields} from '../field-resolution.ts'\nimport {randomKey} from '../keys.ts'\nimport {hydrateSnapshot} from '../snapshot.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {InitialFieldValue, ResolvedFieldEntry} from '../types/field-values.ts'\nimport type {StageName} from '../types/ids.ts'\nimport {parseDefinitionSnapshot, type WorkflowInstance} from '../types/instance.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 `editField` 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 activity name selects the lexical\n * `$fields` overlay and the `$subworkflows` rows, `vars` carries anything the\n * shell pre-computed (`$can`, `$row`, `$subworkflows`).\n */\nexport interface ConditionScopeOptions {\n activityName?: 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 `$fields` overlay for the activity 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 fields = {\n ...(base.fields as Record<string, unknown>),\n ...scopedFieldOverlay(ctx.instance, ctx.snapshot, opts?.activityName),\n }\n const params: Record<string, unknown> = {\n ...base,\n fields,\n actor: opts?.actor,\n assigned:\n opts?.activityName !== undefined\n ? assignedFor(ctx.instance, opts.activityName, 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` (`activity.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 fields[] from the stage definition + an\n * optional `initialFields` (e.g. supplied to `setStage`). Bound to the\n * instance's subject and to `$stage = stage.name`.\n */\nexport async function resolveStageFieldEntries(args: {\n client: WorkflowClient\n instance: WorkflowInstance\n stage: Stage\n now: string\n initialFields?: InitialFieldValue[]\n recordDiscard?: RecordFieldDiscard\n}): Promise<ResolvedFieldEntry[]> {\n const {client, instance, stage, now, initialFields, recordDiscard} = args\n return resolveDeclaredFields({\n entryDefs: stage.fields,\n initialFields: initialFields ?? [],\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' `initialValue: { type: \"fieldRead\", scope:\n // \"workflow\", ... }` to see the already-resolved workflow-scope fields.\n workflowFields: instance.fields ?? [],\n ...(instance.perspective !== undefined ? {perspective: instance.perspective} : {}),\n ...(recordDiscard !== undefined ? {recordDiscard} : {}),\n },\n randomKey,\n })\n}\n\n/** Same shape as `resolveStageFieldEntries` but scoped to an activity. */\nexport async function resolveActivityFieldEntries(args: {\n client: WorkflowClient\n instance: WorkflowInstance\n stage: Stage\n activity: Activity\n now: string\n recordDiscard?: RecordFieldDiscard\n}): Promise<ResolvedFieldEntry[]> {\n const {client, instance, stage, activity, now, recordDiscard} = args\n return resolveDeclaredFields({\n entryDefs: activity.fields,\n initialFields: [],\n ctx: {\n client,\n now,\n selfId: instance._id,\n tag: instance.tag,\n stageName: stage.name,\n workflowResource: instance.workflowResource,\n activityName: activity.name,\n workflowFields: instance.fields ?? [],\n ...(instance.perspective !== undefined ? {perspective: instance.perspective} : {}),\n ...(recordDiscard !== undefined ? {recordDiscard} : {}),\n },\n randomKey,\n })\n}\n","/**\n * Pure effect-binding resolution.\n *\n * An effect's `bindings` is a `Record<string, groq>` — GROQ reads over the\n * same rendered scope conditions use (`$fields`, `$effects`, `$now`, …). Each\n * binding evaluates to a concrete value and merges with the effect's static\n * `input` to form the params object the handler is called with.\n */\n\nimport {runGroq} from './eval.ts'\nimport type {HydratedSnapshot} from './snapshot.ts'\n\nexport async function resolveBindings(args: {\n bindings: Record<string, string> | undefined\n staticInput: Record<string, unknown> | undefined\n snapshot: HydratedSnapshot\n /** The rendered scope — same param bag conditions evaluate over. */\n params: Record<string, unknown>\n}): Promise<Record<string, unknown>> {\n const resolved: Record<string, unknown> = {}\n for (const [key, groq] of Object.entries(args.bindings ?? {})) {\n resolved[key] = await runGroq(groq, args.params, args.snapshot)\n }\n return {...resolved, ...args.staticInput}\n}\n","import type {GlobalDocumentReference, WorkflowResource} from './core/refs.ts'\nimport type {WorkflowDefinition} from './define/schema.ts'\nimport {randomKey} from './keys.ts'\nimport type {Actor} from './types/actor.ts'\nimport type {WorkflowClient, WorkflowPerspective} from './types/client.ts'\nimport type {EffectsContextEntry} from './types/effects.ts'\nimport type {ResolvedFieldEntry} from './types/field-values.ts'\nimport type {HistoryEntry} from './types/history.ts'\nimport {WORKFLOW_INSTANCE_TYPE, type WorkflowInstance} from './types/instance.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 fields + 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 pinnedContentHash: string | undefined\n definition: WorkflowDefinition\n fields: ResolvedFieldEntry[]\n effectsContext: EffectsContextEntry[]\n ancestors: GlobalDocumentReference[]\n perspective: WorkflowPerspective | undefined\n initialStage: string\n actor: Actor | undefined\n /** Audit rows produced while resolving the seed fields (e.g. discarded\n * query results), appended after the opening `stageEntered`. */\n extraHistory?: HistoryEntry[]\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 ...(args.pinnedContentHash !== undefined ? {pinnedContentHash: args.pinnedContentHash} : {}),\n definitionSnapshot: JSON.stringify(args.definition),\n fields: args.fields,\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 ...(args.extraHistory ?? []),\n ],\n startedAt: now,\n lastChangedAt: now,\n }\n}\n","import type {SanityDocument} from '@sanity/types'\n\nimport type {Stage, Activity} 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 {ResolvedFieldEntry} from '../types/field-values.ts'\nimport type {HistoryEntry} from '../types/history.ts'\nimport type {StageName, ActivityName} from '../types/ids.ts'\nimport {findOpenStageEntry, type StageEntry, type ActivityEntry} from '../types/instance-state.ts'\nimport type {WorkflowInstance} from '../types/instance.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 fields: ResolvedFieldEntry[]\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 field entry arrays need their own copies\n // so ops can mutate without leaking into the source.\n fields: (instance.fields ?? []).map((s) => ({...s})),\n stages: instance.stages.map((s) => ({\n ...s,\n fields: (s.fields ?? []).map((entry) => ({...entry})),\n activities: s.activities.map((t) => ({\n ...t,\n ...(t.fields !== undefined ? {fields: t.fields.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 | 'fields'\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 fields: src.fields,\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 fields: mutation.fields,\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 `activateActivity`'s in-memory `checkSpawnCompletion` flipped the\n // parent's activity 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 activity 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 currentActivities(mutation: MutableInstance): ActivityEntry[] {\n return currentStageEntry(mutation).activities\n}\n\n/** Find an activity definition on the instance's current stage, throwing a\n * consistent error when it isn't declared there. */\nexport function findActivityInCurrentStage(\n ctx: EngineContext,\n activityName: ActivityName,\n): {stage: Stage; activity: Activity} {\n const stage = findStage(ctx.definition, ctx.instance.currentStage)\n const activity = (stage.activities ?? []).find((t) => t.name === activityName)\n if (activity === undefined) {\n throw new Error(\n `Activity \"${activityName}\" not found in current stage \"${stage.name}\" of ${ctx.definition.name}`,\n )\n }\n return {stage, activity}\n}\n\n/** The mutation copy's entry for `activity`. Throws if it vanished — the\n * live instance and its mutation copy must agree on activity identity. */\nexport function requireMutationActivityEntry(\n mutation: MutableInstance,\n activity: ActivityName,\n): ActivityEntry {\n const mutEntry = currentActivities(mutation).find((t) => t.name === activity)\n if (mutEntry === undefined) {\n throw new Error(`Activity \"${activity}\" 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 findCurrentActivities(instance: WorkflowInstance): ActivityEntry[] {\n return findCurrentStageEntry(instance)?.activities ?? []\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 * 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>; activityName?: 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?.activityName !== undefined ? {activityName: opts.activityName} : {}),\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 * History-entry builders shared across the lifecycle boundaries. Leaf\n * module (keys + types only) so the op runner, the stage mover, and the\n * activity activator can all stamp entries without import cycles.\n */\n\nimport {randomKey} from '../keys.ts'\nimport type {Actor} from '../types/actor.ts'\nimport {type ActivityStatus, type FieldScope, isTerminalActivityStatus} from '../types/enums.ts'\nimport type {HistoryEntry} from '../types/history.ts'\nimport type {StageName} from '../types/ids.ts'\nimport type {ActivityEntry} from '../types/instance-state.ts'\n\n/**\n * Audit row for a `query`-sourced field whose lake result didn't fit its\n * declared kind and was discarded (the field fell back to its default).\n * Resolution is fail-soft for query results — lake data is runtime/external,\n * so a mismatch is recorded here rather than aborting materialisation.\n */\nfunction fieldQueryDiscardedEntry(args: {\n scope: FieldScope\n field: string\n detail: string\n at: string\n}): Extract<HistoryEntry, {_type: 'fieldQueryDiscarded'}> {\n return {\n _key: randomKey(),\n _type: 'fieldQueryDiscarded',\n at: args.at,\n scope: args.scope,\n field: args.field,\n detail: args.detail,\n }\n}\n\n/**\n * Bind a `recordDiscard` sink (the {@link ResolveFieldContext.recordDiscard}\n * shape) that appends a {@link fieldQueryDiscardedEntry} to `target` for the\n * given scope + clock. Shared by every field-resolution call site so a\n * discarded query result always lands on the audit trail the same way.\n */\nexport function recordFieldDiscards(\n target: HistoryEntry[],\n scope: FieldScope,\n at: string,\n): (discard: {field: string; detail: string}) => void {\n return (discard) =>\n target.push(fieldQueryDiscardedEntry({scope, field: discard.field, detail: discard.detail, at}))\n}\n\n/**\n * The ONE activity-status flip. Sets the entry's status, stamps\n * `completedAt`/`completedBy` when the new status is terminal, and pushes\n * the `activityStatusChanged` audit row — every boundary that flips an activity\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 applyActivityStatusChange(args: {\n entry: ActivityEntry\n history: HistoryEntry[]\n stage: StageName\n to: ActivityStatus\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 (isTerminalActivityStatus(to)) {\n entry.completedAt = at\n if (actor !== undefined) entry.completedBy = actor.id\n }\n history.push({\n _key: randomKey(),\n _type: 'activityStatusChanged',\n at,\n stage,\n activity: entry.name,\n from,\n to,\n ...(actor !== undefined ? {actor} : {}),\n })\n}\n\n/**\n * Build the three-entry history sequence for a stage move:\n * `stageExited` → `transitionFired` → `stageEntered`. All three share\n * `at`, the `transition` name, `actor`, and the `via`/`reason`\n * discriminators that distinguish condition-driven transitions from\n * admin overrides.\n */\nexport function stageTransitionHistory(args: {\n fromStage: StageName\n toStage: StageName\n at: string\n transition?: string\n actor?: Actor\n via?: 'transition' | 'setStage'\n reason?: string\n}): HistoryEntry[] {\n const {fromStage, toStage, at, transition, actor, via, reason} = args\n const shared = {\n at,\n ...(transition !== undefined ? {transition} : {}),\n ...(actor !== undefined ? {actor} : {}),\n ...(via !== undefined ? {via} : {}),\n ...(reason !== undefined ? {reason} : {}),\n }\n return [\n {\n _key: randomKey(),\n _type: 'stageExited',\n stage: fromStage,\n toStage,\n ...shared,\n },\n {\n _key: randomKey(),\n _type: 'transitionFired',\n fromStage,\n toStage,\n ...shared,\n },\n {\n _key: randomKey(),\n _type: 'stageEntered',\n stage: toStage,\n fromStage,\n ...shared,\n },\n ]\n}\n","/**\n * Pure resolution of the context-free {@link ValueExpr} arms.\n *\n * A `ValueExpr` declared on an op is evaluated into a concrete value. The arms\n * here need no resolver-specific backing data — just the caller params, the\n * acting actor, and the engine clock. No GROQ, no client, no I/O.\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 {ValueExpr} from '../define/schema.ts'\nimport type {Actor} from '../types/actor.ts'\n\n/**\n * The context-free {@link ValueExpr} arms — resolvable from caller params, the\n * actor, and the clock alone. The remaining arms (`self` / `stage` /\n * `fieldRead` / `object`) need resolver-specific backing data and are handled\n * by the in-mutation op resolver (see `engine/ops.ts`) against the mutation it\n * is building.\n */\ntype StaticValueExpr = Extract<ValueExpr, {type: 'literal' | 'param' | 'actor' | 'now'}>\n\nexport function resolveStaticValueExpr(\n src: StaticValueExpr,\n ctx: {params?: Record<string, unknown>; actor?: Actor | undefined; now: string},\n): unknown {\n switch (src.type) {\n case 'literal':\n return src.value\n case 'param':\n return ctx.params?.[src.param]\n case 'actor':\n return ctx.actor\n case 'now':\n return ctx.now\n }\n}\n","import {validateFieldAppendItem, validateFieldValue} from '../core/field-validation.ts'\nimport {getPath} from '../core/path.ts'\nimport {resolveStaticValueExpr} from '../core/source.ts'\nimport type {\n Action,\n ActionParam,\n FieldShape,\n Op,\n OpPredicate,\n StoredFieldRef,\n ValueExpr,\n} from '../define/schema.ts'\nimport {randomKey} from '../keys.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {ResolvedFieldEntry} from '../types/field-values.ts'\nimport type {HistoryEntry} from '../types/history.ts'\nimport type {StageName, ActivityName} from '../types/ids.ts'\nimport {findOpenStageEntry} from '../types/instance-state.ts'\nimport {applyActivityStatusChange} 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, activity activation) — plus action param validation.\n\n/**\n * Op types that mutate workflow fields (vs `status.set`, which only flips an\n * activity 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 FIELD_OP_TYPES = [\n 'field.set',\n 'field.unset',\n 'field.append',\n 'field.updateWhere',\n 'field.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 isFieldOp(summary: OpAppliedSummary): boolean {\n return (FIELD_OP_TYPES as readonly string[]).includes(summary.opType)\n}\n\nexport function validateActionParams(\n action: Action,\n activityName: ActivityName,\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, activity: activityName, 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 activity?: ActivityName\n action?: string\n transition?: string\n /** A direct edit through the edit seam (`editField`) 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 `ValueExpr.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, {\n mutation,\n stage,\n activityName: origin.activity,\n params,\n actor,\n self,\n now,\n })\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.activity !== undefined ? {activity: origin.activity} : {}),\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 activity whose boundary is running — `scope: \"activity\"` targets land here. */\n activityName: ActivityName | 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 'field.set':\n return applyFieldSet(op, ctx)\n case 'field.unset':\n return applyFieldUnset(op, ctx)\n case 'field.append':\n return applyFieldAppend(op, ctx)\n case 'field.updateWhere':\n return applyFieldUpdateWhere(op, ctx)\n case 'field.removeWhere':\n return applyFieldRemoveWhere(op, ctx)\n case 'status.set':\n return applyStatusSet(op, ctx)\n }\n}\n\nfunction applyFieldSet(op: Extract<Op, {type: 'field.set'}>, ctx: OpContext): OpAppliedSummary {\n const value = resolveOpValue(op.value, ctx)\n const entry = locateEntry(ctx, op.target)\n // Wrong-shape writes throw `FieldValueShapeError` — the engine aborts the\n // commit before persisting.\n validateFieldValue({entryType: entry._type, entryName: entry.name, value, ...entryShape(entry)})\n setEntryValue(entry, value)\n return {opType: op.type, target: op.target, resolved: {value}}\n}\n\n/**\n * The declared sub-field shape of a compositional entry, threaded into\n * validation. `object` / `array` resolved entries carry it (the instance is\n * self-describing); every other kind has none.\n */\nfunction entryShape(entry: ResolvedFieldEntry): {fields?: FieldShape[]; of?: FieldShape[]} {\n if (entry._type === 'object') return {fields: entry.fields}\n if (entry._type === 'array') return {of: entry.of}\n return {}\n}\n\n/** Array-valued kinds clear to empty; everything else to null (`!defined`). */\nconst EMPTY_BY_KIND: Partial<Record<ResolvedFieldEntry['_type'], unknown[]>> = {\n 'doc.refs': [],\n array: [],\n assignees: [],\n}\n\nfunction applyFieldUnset(op: Extract<Op, {type: 'field.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 applyFieldAppend(\n op: Extract<Op, {type: 'field.append'}>,\n ctx: OpContext,\n): OpAppliedSummary {\n const item = resolveOpValue(op.value, ctx)\n const entry = locateEntry(ctx, op.target)\n validateFieldAppendItem({\n entryType: entry._type,\n entryName: entry.name,\n item,\n of: entry._type === 'array' ? entry.of : undefined,\n })\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 applyFieldUpdateWhere(\n op: Extract<Op, {type: 'field.updateWhere'}>,\n ctx: OpContext,\n): OpAppliedSummary {\n const entry = locateEntry(ctx, op.target)\n const rows = requireArrayValue(entry, op)\n const merge = resolveOpValue(op.value, ctx)\n if (merge === null || typeof merge !== 'object' || Array.isArray(merge)) {\n throw new Error(\n `field.updateWhere value must resolve to an object of fields to merge (target \"${op.target.field}\")`,\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 applyFieldRemoveWhere(\n op: Extract<Op, {type: 'field.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: ResolvedFieldEntry,\n op: Extract<Op, {type: 'field.updateWhere' | 'field.removeWhere'}>,\n): Record<string, unknown>[] {\n if (!Array.isArray(entry.value)) {\n throw new Error(\n `${op.type} target ${op.target.scope}:\"${op.target.field}\" 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 applyActivityStatusChange} — the ONE activity-status mechanism —\n * after resolving the op's activity name against the open stage.\n */\nfunction applyStatusSet(op: Extract<Op, {type: 'status.set'}>, ctx: OpContext): OpAppliedSummary {\n const entry = findOpenStageEntry(ctx.mutation)?.activities.find((t) => t.name === op.activity)\n if (entry === undefined) {\n throw new Error(\n `status.set targets activity \"${op.activity}\" which has no entry in the open stage`,\n )\n }\n applyActivityStatusChange({\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: {activity: op.activity, status: op.status}}\n}\n\n/**\n * The single write seam for entry values. `ResolvedFieldEntry` 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 validateFieldValue} /\n * {@link validateFieldAppendItem}) or built from already-valid data (the\n * per-kind empty on unset, the where-op transforms over existing rows).\n */\nfunction setEntryValue(entry: ResolvedFieldEntry, 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: StoredFieldRef): ResolvedFieldEntry {\n const host = fieldHost(ctx, target.scope)\n const entry = host?.find((s) => s.name === target.field)\n if (entry === undefined) {\n throw new Error(\n `Op target ${target.scope}:\"${target.field}\" has no resolved field entry on this instance — ` +\n `the deployed definition and the instance state have diverged`,\n )\n }\n return entry\n}\n\nfunction fieldHost(\n ctx: OpContext,\n scope: StoredFieldRef['scope'],\n): ResolvedFieldEntry[] | undefined {\n if (scope === 'workflow') return ctx.mutation.fields\n const stageEntry = findOpenStageEntry(ctx.mutation)\n if (scope === 'stage') return stageEntry?.fields\n const activity = stageEntry?.activities.find((t) => t.name === ctx.activityName)\n if (activity !== undefined && activity.fields === undefined) activity.fields = []\n return activity?.fields\n}\n\nfunction resolveOpValue(src: ValueExpr, ctx: OpContext): unknown {\n switch (src.type) {\n case 'literal':\n case 'param':\n case 'actor':\n case 'now':\n return resolveStaticValueExpr(src, ctx)\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 expression).\n return ctx.self\n case 'stage':\n return ctx.stage\n case 'fieldRead': {\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] = resolveOpValue(fieldSrc, ctx)\n }\n return out\n }\n }\n}\n\nfunction entryValue(entries: ResolvedFieldEntry[] | undefined, name: string): unknown {\n return entries?.find((s) => s.name === name)?.value\n}\n\nfunction readEntryFromMutation(\n ctx: OpContext,\n src: Extract<ValueExpr, {type: 'fieldRead'}>,\n): 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.fields : stageEntry?.fields\n const value = entryValue(host, src.field)\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] === resolveOpValue(p.equals, ctx)\n }\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","/**\n * The engine's own system-actor identity — the audit trail's answer to \"who\n * did this?\" when no human or external caller did, but the engine itself\n * (a resolution gate, a machine step, an effect drain).\n *\n * One definition of the `engine.`-prefixed id convention, shared by every\n * producer that stamps such an actor and by {@link driverKind}, which reads\n * the prefix back to classify a system actor as the engine rather than an\n * external service. Tying both sides to this module keeps the convention from\n * drifting into bare string literals.\n */\n\nimport type {Actor} from '../types/actor.ts'\n\nconst ENGINE_ACTOR_ID_PREFIX = 'engine.'\n\n/** A `system` actor owned by the engine, named by the housekeeping step that\n * stamped it (e.g. `engineSystemActor('machineStep')` → `engine.machineStep`). */\nexport function engineSystemActor(name: string): Actor {\n return {kind: 'system', id: `${ENGINE_ACTOR_ID_PREFIX}${name}`}\n}\n\n/** Whether an actor is the engine itself, as opposed to a human, an agent, or\n * an external service driving the engine with its own `system` actor. */\nexport function isEngineActor(actor: Actor): boolean {\n return actor.kind === 'system' && actor.id.startsWith(ENGINE_ACTOR_ID_PREFIX)\n}\n","import {evaluate, parse} from 'groq-js'\n\nimport type {DeployedDefinition} from '../api/deploy.ts'\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, Activity, WorkflowDefinition} from '../define/schema.ts'\nimport {definitionLookupGroq} from '../definition-query.ts'\nimport {clientForDiscovery, discoverItems} from '../discover.ts'\nimport {derivePerspectiveFromFields, resolveDeclaredFields} from '../field-resolution.ts'\nimport {buildInstanceBase, effectsContextEntry} from '../instance.ts'\nimport {randomKey} from '../keys.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 type {InitialFieldValue, FieldKind} from '../types/field-values.ts'\nimport type {HistoryEntry} from '../types/history.ts'\nimport {WORKFLOW_INSTANCE_TYPE, type WorkflowInstance} from '../types/instance.ts'\nimport {\n ctxConditionParams,\n ctxEvaluateCondition,\n type EngineContext,\n gdrToBareId,\n} from './context.ts'\nimport {recordFieldDiscards} from './history-entries.ts'\nimport type {MutableInstance} from './mutation.ts'\nimport {engineSystemActor} from './system-actor.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` activity 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/** The engine system actor that owns a gate-driven activity flip — the audit\n * trail's answer to \"who resolved this?\" when no human did. */\nexport function gateActor(outcome: GateOutcome): Actor {\n return engineSystemActor(outcome === 'failed' ? 'failWhen' : 'completeWhen')\n}\n\n/** The status a satisfied resolution gate resolves an activity into. */\nexport type GateOutcome = 'done' | 'failed'\n\n/**\n * The activity's effective completion gate — explicit `completeWhen`, or the\n * implicit {@link SUBWORKFLOWS_ALL_DONE} default on a spawning activity (the\n * dominant case costs zero syntax, and a zero-row fan-out resolves\n * vacuously instead of hanging).\n */\nexport function effectiveCompleteWhen(activity: Activity): string | undefined {\n return (\n activity.completeWhen ??\n (activity.subworkflows !== undefined ? SUBWORKFLOWS_ALL_DONE : undefined)\n )\n}\n\n/**\n * Evaluate an activity's resolution gate over the activity-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 activity: Activity,\n vars: Record<string, unknown>,\n): Promise<GateOutcome | undefined> {\n const scope = {activityName: activity.name, vars}\n if (\n activity.failWhen !== undefined &&\n (await ctxEvaluateCondition(ctx, activity.failWhen, scope))\n ) {\n return 'failed'\n }\n const completeWhen = effectiveCompleteWhen(activity)\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 activity: Activity,\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 activity \"${activity.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}, activity ${activity.name})`,\n )\n }\n\n const parentScope = await ctxConditionParams(ctx, {\n activityName: activity.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 initialFields = await projectRowFields(\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 initialFields,\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 projectRowFields} 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.fields)[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 * `initialFields`. The CHILD's field declarations dictate each entry's kind:\n * `with` supplies values for the child's `input`-sourced entries by name;\n * naming an entry the child doesn't declare fails loud.\n */\nasync function projectRowFields(\n ctx: EngineContext,\n sub: Subworkflows,\n childDefinition: WorkflowDefinition,\n parentScope: Record<string, unknown>,\n row: unknown,\n discoveryResource: WorkflowResource | undefined,\n): Promise<InitialFieldValue[]> {\n const out: InitialFieldValue[] = []\n for (const [name, groq] of Object.entries(sub.with ?? {})) {\n const declared = (childDefinition.fields ?? []).find((e) => e.name === name)\n if (declared === undefined) {\n throw new Error(\n `subworkflows.with[\"${name}\"]: subworkflow \"${childDefinition.name}\" declares no field 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 InitialFieldValue['type'],\n name,\n value: value as InitialFieldValue['value'],\n } as InitialFieldValue)\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: FieldKind, 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<DeployedDefinition | 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<DeployedDefinition | 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: DeployedDefinition\n initialFields: InitialFieldValue[]\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, initialFields, 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 `activityEntry.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 fields declarations against the\n // projected `initialFields`. The child's own fields[] declarations dictate\n // which entry names/kinds exist; the projection just fills the\n // `input`-sourced ones. Query and working-memory entries resolve per their\n // own `initialValue`.\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 // A child's workflow-scope query-sourced fields can have their lake result\n // discarded; those rows seed the child instance's history below.\n const fieldDiscards: HistoryEntry[] = []\n const childFields = await resolveDeclaredFields({\n entryDefs: definition.fields,\n initialFields,\n ctx: {\n client,\n now,\n selfId: childDocId,\n tag: childTag,\n workflowResource,\n definitionName: definition.name,\n ...(inheritedPerspective !== undefined ? {perspective: inheritedPerspective} : {}),\n recordDiscard: recordFieldDiscards(fieldDiscards, 'workflow', now),\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 = derivePerspectiveFromFields(childFields) ?? 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 pinnedContentHash: definition.contentHash,\n definition,\n fields: childFields,\n effectsContext: effectsContextEntries,\n ancestors,\n perspective: childPerspective,\n initialStage: definition.initialStage,\n actor,\n ...(fieldDiscards.length > 0 ? {extraHistory: fieldDiscards} : {}),\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 an activity'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","import type {ConditionOutcome} from '../core/eval.ts'\nimport {selfGdr} from '../core/refs.ts'\nimport type {Stage, Activity} 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 {ActivityName} from '../types/ids.ts'\nimport type {ActivityEntry} from '../types/instance-state.ts'\nimport {\n ctxEvaluateConditionOutcome,\n type EngineContext,\n findStage,\n loadContext,\n resolveActivityFieldEntries,\n} from './context.ts'\nimport {queueEffects} from './effects.ts'\nimport {applyActivityStatusChange, recordFieldDiscards} from './history-entries.ts'\nimport {\n findCurrentActivities,\n findActivityInCurrentStage,\n type MutableInstance,\n persist,\n requireMutationActivityEntry,\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'\nimport {engineSystemActor} from './system-actor.ts'\n\n/**\n * Manually activate a `pending` activity — the explicit path for\n * `activation: \"manual\"` activities (the default: an activity never activates\n * silently). No-op if the activity is already active or done.\n */\nexport async function invokeActivity(args: {\n client: WorkflowClient\n instanceId: string\n activity: ActivityName\n options?: EngineCallOptions\n}): Promise<InvokeResult> {\n const {client, instanceId, activity: activityName, 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, activityName, options?.actor)\n}\n\nasync function commitInvoke(\n ctx: EngineContext,\n activityName: ActivityName,\n actor: Actor | undefined,\n): Promise<InvokeResult> {\n const {activity} = findActivityInCurrentStage(ctx, activityName)\n const entry = findCurrentActivities(ctx.instance).find((t) => t.name === activityName)\n if (entry === undefined) {\n throw new Error(\n `Activity \"${activityName}\" has no status entry on instance ${ctx.instance._id}`,\n )\n }\n if (entry.status !== 'pending') {\n return {invoked: false, activity: activityName}\n }\n\n const mutation = startMutation(ctx.instance)\n const mutEntry = requireMutationActivityEntry(mutation, activityName)\n await activateActivity(ctx, mutation, activity, mutEntry, actor)\n await persist(ctx, mutation)\n return {invoked: true, activity: activityName}\n}\n\n/**\n * Activation — the activity's lifecycle moment. The full payload runs here:\n * activity-scoped fields resolves, the activity'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 * activity-context scope (including `$subworkflows`), and the MACHINE-STEP rule\n * closes the loop — an activity 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 activateActivity(\n ctx: EngineContext,\n mutation: MutableInstance,\n activity: Activity,\n entry: ActivityEntry,\n actor: Actor | undefined,\n): Promise<void> {\n // One clock reading for the whole activation so startedAt, any\n // auto-resolve flip, activityActivated, and spawn stamps agree on the time.\n const now = ctx.now\n entry.status = 'active'\n entry.startedAt = now\n if (activity.fields !== undefined && activity.fields.length > 0) {\n const stage = findStage(ctx.definition, mutation.currentStage)\n entry.fields = await resolveActivityFieldEntries({\n client: ctx.client,\n instance: ctx.instance,\n stage,\n activity,\n now,\n recordDiscard: recordFieldDiscards(mutation.history, 'activity', now),\n })\n }\n\n runOps({\n ops: activity.ops,\n mutation,\n stage: mutation.currentStage,\n origin: {activity: activity.name},\n params: {},\n actor,\n self: selfGdr(ctx.instance),\n now,\n })\n\n mutation.history.push({\n _key: randomKey(),\n _type: 'activityActivated',\n at: now,\n stage: mutation.currentStage,\n activity: activity.name,\n ...(actor !== undefined ? {actor} : {}),\n })\n\n await queueEffects(\n ctx,\n mutation,\n activity.effects,\n {kind: 'activity', name: activity.name},\n actor,\n {\n activityName: activity.name,\n },\n )\n\n let pendingChildren: {_id: string; stage: string; status: 'active'}[] | undefined\n if (activity.subworkflows !== undefined) {\n const createsBefore = mutation.pendingCreates.length\n const refs = await spawnSubworkflows(ctx, mutation, activity, activity.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 activity: activity.name,\n instanceRef: ref,\n })\n }\n }\n\n if (await autoResolveOnActivate(ctx, mutation, activity, entry, now, pendingChildren)) return\n resolveMachineStep(mutation, activity, entry, now)\n}\n\n/**\n * Run the activity's resolution gate ({@link evaluateResolutionGate}) at\n * activation, immediately resolving the activity with the gate's system actor\n * when it fires. Returns true when the activity resolved so the caller skips\n * the machine-step check.\n */\nasync function autoResolveOnActivate(\n ctx: EngineContext,\n mutation: MutableInstance,\n activity: Activity,\n entry: ActivityEntry,\n now: string,\n pendingChildren?: {_id: string; stage: string; status: 'active'}[],\n): Promise<boolean> {\n if (activity.failWhen === undefined && effectiveCompleteWhen(activity) === undefined) return false\n const vars =\n pendingChildren !== undefined\n ? {subworkflows: pendingChildren}\n : await activityConditionVars(ctx, entry)\n const outcome = await evaluateResolutionGate(ctx, activity, vars)\n if (outcome === undefined) return false\n applyActivityStatusChange({\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 an activity's conditions — hydrated from the\n * spawned instances so `count($subworkflows[status == 'done'])` works.\n */\nexport async function activityConditionVars(\n ctx: EngineContext,\n entry: ActivityEntry,\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 * An activity 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 activity list where a container hook would have fired\n * invisibly. (A `subworkflows` activity without `completeWhen` is NOT a machine\n * step: the default all-done gate applies via the cascade.)\n */\nfunction resolveMachineStep(\n mutation: MutableInstance,\n activity: Activity,\n entry: ActivityEntry,\n now: string,\n): void {\n const waitsForActor = activity.actions !== undefined && activity.actions.length > 0\n const waitsForCondition =\n activity.completeWhen !== undefined || activity.subworkflows !== undefined\n if (waitsForActor || waitsForCondition) return\n applyActivityStatusChange({\n entry,\n history: mutation.history,\n stage: mutation.currentStage,\n to: 'done',\n at: now,\n actor: engineSystemActor('machineStep'),\n })\n}\n\n/**\n * Build the stage's activity entries at enter: an activity whose `filter` is a definite\n * `false` against the stage's entry fields is `skipped` (conditional enter —\n * different activities 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 activity 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 ActivityEntry.filterEvaluation} so the\n * audit trail tells \"genuinely below threshold\" apart from \"couldn't read it\".\n */\nexport async function buildStageActivities(\n ctx: EngineContext,\n stage: Stage,\n): Promise<ActivityEntry[]> {\n const entries: ActivityEntry[] = []\n for (const activity of stage.activities ?? []) {\n const outcome = await ctxEvaluateConditionOutcome(ctx, activity.filter, {\n activityName: activity.name,\n })\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: activity.name,\n status: inScope ? 'pending' : 'skipped',\n ...(activity.filter !== undefined\n ? {filterEvaluation: buildFilterEvaluation(ctx.now, activity.filter, outcome)}\n : {}),\n })\n }\n return entries\n}\n\n/**\n * The audit record for an activity'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* an\n * activity that \"should\" have skipped is sitting in scope.\n */\nfunction buildFilterEvaluation(\n at: string,\n filter: string,\n outcome: ConditionOutcome,\n): NonNullable<ActivityEntry['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). Activity 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 {activateActivity, buildStageActivities} from './activities.ts'\nimport {\n ctxEvaluateConditionOutcome,\n type EngineContext,\n findStage,\n loadContext,\n resolveStageFieldEntries,\n} from './context.ts'\nimport {queueEffects} from './effects.ts'\nimport {recordFieldDiscards, 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'\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\"` activities, 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 activities (`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 fields: await resolveStageFieldEntries({\n client: ctx.client,\n instance: ctx.instance,\n stage: nextStage,\n now: at,\n recordDiscard: recordFieldDiscards(mutation.history, 'stage', at),\n }),\n activities: await buildStageActivities(ctx, nextStage),\n }\n mutation.stages.push(nextStageEntry)\n\n for (const activity of nextStage.activities ?? []) {\n if (activity.activation !== 'auto') continue\n const entry = nextStageEntry.activities.find((t) => t.name === activity.name)\n if (entry && entry.status === 'pending') {\n await activateActivity(ctx, mutation, activity, 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 // Field-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, Activity, 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 {HistoryEntry} from '../types/history.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 {activateActivity, buildStageActivities, activityConditionVars} from './activities.ts'\nimport {\n buildEngineContext,\n type EngineContext,\n findStage,\n gdrToBareId,\n loadContext,\n resolveStageFieldEntries,\n} from './context.ts'\nimport {deployOrRollback} from './guard-commit.ts'\nimport {applyActivityStatusChange, recordFieldDiscards} from './history-entries.ts'\nimport {currentActivities, findCurrentActivities, 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'\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// activateActivity. Exported so api.ts doesn't reimplement them.\n\n/**\n * Build the initial stage entry + auto-activate its `activation: \"auto\"`\n * activities 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 activities.\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 // Initial-stage stage-scope fields can be query-sourced; a discarded result\n // is appended to history alongside the stage entry in the same patch.\n const discards: HistoryEntry[] = []\n const initialStageEntry: StageEntry = {\n _key: randomKey(),\n name: stage.name,\n enteredAt: now,\n fields: await resolveStageFieldEntries({\n client,\n instance,\n stage,\n now,\n recordDiscard: recordFieldDiscards(discards, 'stage', now),\n }),\n activities: await buildStageActivities(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 ...(discards.length > 0 ? {history: [...instance.history, ...discards]} : {}),\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 autoActivatePrimedActivities(\n client,\n instanceId,\n definition,\n stage,\n actor,\n clientForGdr,\n clock,\n )\n}\n\n/**\n * After the initial stage entry is persisted, re-load and activate the\n * `activation: \"auto\"` activities. Each activation reloads + persists\n * independently so subworkflow fan-outs + auto-resolution see committed\n * state.\n */\nasync function autoActivatePrimedActivities(\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 activity of stage.activities ?? []) {\n if (activity.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 = currentActivities(mutation).find((t) => t.name === activity.name)\n if (mutEntry && mutEntry.status === 'pending') {\n await activateActivity(updatedCtx, mutation, activity, 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 activity 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 activity. 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 = {activity: Activity; outcome: GateOutcome}\n\n/** For each active gated activity, run {@link evaluateResolutionGate} over the\n * activity-context scope and collect the outcome. */\nasync function gatherAutoResolveCandidates(\n ctx: EngineContext,\n activities: Activity[],\n): Promise<AutoResolveCandidate[]> {\n const currentActivitiesList = findCurrentActivities(ctx.instance)\n const candidates: AutoResolveCandidate[] = []\n for (const activity of activities) {\n const entry = currentActivitiesList.find((e) => e.name === activity.name)\n if (entry?.status !== 'active') continue\n const outcome = await evaluateResolutionGate(\n ctx,\n activity,\n await activityConditionVars(ctx, entry),\n )\n if (outcome !== undefined) candidates.push({activity, 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 gatedActivities = (stage.activities ?? []).filter(\n (t) => effectiveCompleteWhen(t) !== undefined || t.failWhen !== undefined,\n )\n if (gatedActivities.length === 0) return 0\n\n const candidates = await gatherAutoResolveCandidates(ctx, gatedActivities)\n if (candidates.length === 0) return 0\n\n const mutation = startMutation(ctx.instance)\n let count = 0\n for (const {activity, outcome} of candidates) {\n const mutEntry = currentActivities(mutation).find((t) => t.name === activity.name)\n if (mutEntry === undefined || mutEntry.status !== 'active') continue\n applyActivityStatusChange({\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 activities before each transition pass so a gate that became\n * satisfied can immediately unblock an `$allActivitiesDone`-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 activity in case its completion gate is now satisfied. If a parent\n * activity 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 activity: Activity\n outcome: GateOutcome\n}\n\n/** The parent whose spawning activity this child belongs to, when that activity'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 * activity, activity 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 activity 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 parentCurrentActivities = findCurrentActivities(parent)\n const activity = (stage.activities ?? []).find((t) => {\n if (t.subworkflows === undefined) return false\n const entry = parentCurrentActivities.find((e) => e.name === t.name)\n return entry?.spawnedInstances?.some((r) => gdrToBareId(r.id) === child._id) ?? false\n })\n if (activity?.subworkflows === undefined) return undefined\n\n const entry = parentCurrentActivities.find((e) => e.name === activity.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(\n ctx,\n activity,\n await activityConditionVars(ctx, entry),\n )\n if (outcome === undefined) return undefined\n return {parent, definition, stage, activity, 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, activity, outcome} = found\n\n // Flip the parent's activity and persist. The flip is the spawning activity'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 = currentActivities(mutation).find((e) => e.name === activity.name)\n if (mutEntry === undefined) return\n applyActivityStatusChange({\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 activity.\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` / `ValueExpr.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 * Activity classification — pure, advisory mapping from an activity's SHAPE to its\n * {@link ActivityKind}, and from a firing {@link Actor} to its {@link DriverKind}.\n *\n * `kind` classifies an activity by its executor (BPMN-aligned) so tooling can render\n * it as what it is; it never affects gating or how an activity resolves. When a\n * definition omits `kind`, {@link deriveActivityKind} computes it from the fields\n * the activity already carries, so existing definitions need no edits and the UI\n * gets a kind regardless.\n */\n\nimport type {Activity} from './define/schema.ts'\nimport {isEngineActor} from './engine/system-actor.ts'\nimport type {Actor} from './types/actor.ts'\nimport type {DriverKind, ActivityKind} from './types/enums.ts'\n\nfunction hasItems(arr: readonly unknown[] | undefined): boolean {\n return arr !== undefined && arr.length > 0\n}\n\n/**\n * Classify an activity from its shape, in precedence order: an activity a person acts on\n * (`actions`) is `user`; otherwise an automated effect step is `service`;\n * otherwise an activity that waits on a condition (`completeWhen` or a `subworkflows`\n * fan-out) is `receive`; otherwise an inline machine step is `script`.\n *\n * Never returns `manual` — off-system work reads identically to a `user` or\n * `receive` activity by shape, so it is only ever an EXPLICIT {@link Activity.kind}.\n */\nexport function deriveActivityKind(activity: Activity): ActivityKind {\n if (hasItems(activity.actions)) return 'user'\n if (hasItems(activity.effects)) return 'service'\n if (activity.completeWhen !== undefined || activity.subworkflows !== undefined) return 'receive'\n return 'script'\n}\n\n/** The effective kind of an activity: the explicitly declared {@link Activity.kind}, or\n * the shape-derived default when omitted. */\nexport function activityKind(activity: Activity): ActivityKind {\n return activity.kind ?? deriveActivityKind(activity)\n}\n\n/**\n * Classify the actor that drove an action for the audit-trail glyph: a human is\n * a `person`, an LLM is an `agent`, and a `system` actor is the `engine` itself\n * ({@link isEngineActor}) or otherwise an external `service`.\n *\n * Advisory and only as trustworthy as the {@link Actor} it reads — actor\n * identity is itself advisory in this engine (the lake/token is authoritative),\n * so this is a best-effort glyph, never an authorization signal.\n */\nexport function driverKind(actor: Actor): DriverKind {\n if (actor.kind === 'user') return 'person'\n if (actor.kind === 'ai') return 'agent'\n return isEngineActor(actor) ? 'engine' : 'service'\n}\n","/**\n * Editable fields — 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 `editField`\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 / activity); 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 FieldEntry,\n StoredFieldRef,\n WorkflowDefinition,\n} from '../define/schema.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {FieldScope} from '../types/enums.ts'\nimport type {EditDisabledReason} from '../types/evaluation.ts'\nimport type {ResolvedFieldEntry, FieldKind} from '../types/field-values.ts'\nimport type {ActivityName} from '../types/ids.ts'\nimport {findOpenStageEntry} from '../types/instance-state.ts'\nimport type {WorkflowInstance} from '../types/instance.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: FieldScope\n /** Present iff `scope === \"activity\"` — the activity whose fields[] holds the slot. */\n activity?: ActivityName\n name: string\n type: FieldKind\n title?: string\n /** The stored reference the op path targets. */\n ref: StoredFieldRef\n /** Baseline AND the stage override — `undefined` means not editable here. */\n effective: Editable | undefined\n}\n\ninterface SlotSite {\n scope: FieldScope\n activity?: ActivityName\n entry: FieldEntry\n}\n\n/** Every declared field slot reachable for editing in `stage`: workflow-scope,\n * this stage's scope, and this stage's activities' scope. */\nfunction slotSites(definition: WorkflowDefinition, stage: Stage): SlotSite[] {\n const sites: SlotSite[] = []\n for (const entry of definition.fields ?? []) sites.push({scope: 'workflow', entry})\n for (const entry of stage.fields ?? []) sites.push({scope: 'stage', entry})\n for (const activity of stage.activities ?? []) {\n for (const entry of activity.fields ?? [])\n sites.push({scope: 'activity', activity: activity.name, entry})\n }\n return sites\n}\n\nfunction toResolvedSlot(site: SlotSite, stage: Stage): ResolvedSlot {\n return {\n scope: site.scope,\n ...(site.activity !== undefined ? {activity: site.activity} : {}),\n name: site.entry.name,\n type: site.entry.type,\n ...(site.entry.title !== undefined ? {title: site.entry.title} : {}),\n ref: {scope: site.scope, field: 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?, field, activity?}`) addressing this slot.\n * An explicit `activity` requires an activity-scope match; an explicit `scope` must\n * match; a bare name matches any scope (the caller disambiguates lexically). */\nexport function editTargetMatches(\n slot: {scope: FieldScope; name: string; activity?: string},\n target: {scope?: FieldScope; field: string; activity?: string},\n): boolean {\n if (slot.name !== target.field) return false\n if (target.activity !== undefined)\n return slot.scope === 'activity' && slot.activity === target.activity\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 * activity before stage before workflow (mirrors `$fields` shadowing). */\nexport const SCOPE_PRECEDENCE: Record<FieldScope, number> = {activity: 0, stage: 1, workflow: 2}\n\n/** Resolve a single edit target by name (+ optional explicit scope / activity).\n * Scope inference, when omitted: an explicit `activity` ⇒ activity scope; otherwise\n * the nearest declaring scope, stage before workflow (mirrors `$fields` reads).\n * Returns `undefined` when no declared slot matches. */\nexport function resolveEditTarget(args: {\n definition: WorkflowDefinition\n stage: Stage\n target: {scope?: FieldScope; field: string; activity?: 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.activity !== undefined ? {activity: site.activity} : {}),\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; an activity-scope slot is open only while its activity is `active`. */\nexport function slotWindowOpen(\n instance: WorkflowInstance,\n slot: {scope: FieldScope; activity?: ActivityName},\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 !== 'activity') return {open: true}\n const status = findOpenStageEntry(instance)?.activities.find(\n (t) => t.name === slot.activity,\n )?.status\n if (status === 'active') return {open: true}\n return {open: false, detail: `activity \"${slot.activity}\" is ${status ?? 'not active'}`}\n}\n\n/** The current resolved value of a slot, read from the instance's runtime\n * fields[] at the slot's scope. `undefined` when the slot hasn't been resolved\n * yet (e.g. an activity-scope slot before its activity activated). */\nexport function readSlotValue(\n instance: WorkflowInstance,\n slot: {scope: FieldScope; activity?: ActivityName; name: string},\n): unknown {\n return slotFieldHost(instance, slot)?.find((e) => e.name === slot.name)?.value\n}\n\nfunction slotFieldHost(\n instance: WorkflowInstance,\n slot: {scope: FieldScope; activity?: ActivityName},\n): ResolvedFieldEntry[] | undefined {\n if (slot.scope === 'workflow') return instance.fields\n const stageEntry = findOpenStageEntry(instance)\n if (slot.scope === 'stage') return stageEntry?.fields\n return stageEntry?.activities.find((t) => t.name === slot.activity)?.fields\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 field 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: StoredFieldRef,\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.field !== ref.field) 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`, `$fields`, …) — 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 {activityKind} from './activity-kind.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, scopedFieldOverlay} from './core/params.ts'\nimport type {ParsedGdr, WorkflowResource} from './core/refs.ts'\nimport type {HydratedSnapshot} from './core/snapshot.ts'\nimport type {Action, RoleAliases, Stage, Activity, 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 {\n DOCUMENT_VALUE_PERMISSIONS,\n isTerminalActivityStatus,\n type ActivityStatus,\n} from './types/enums.ts'\nimport type {\n ActionEvaluation,\n DisabledReason,\n EditableSlotEvaluation,\n EditDisabledReason,\n StageEvaluation,\n ActivityEvaluation,\n TransitionEvaluation,\n WorkflowEvaluation,\n} from './types/evaluation.ts'\nimport {findOpenStageEntry, type ActivityEntry} 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 currentActivityEntries = findOpenStageEntry(instance)?.activities ?? []\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 activityEvaluations: ActivityEvaluation[] = []\n for (const activity of stage.activities ?? []) {\n activityEvaluations.push(\n await evaluateActivity({\n activity,\n statusEntry: currentActivityEntries.find((t) => t.name === activity.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 activities: activityEvaluations,\n transitions: transitionEvaluations,\n }\n\n const pendingOnYou = activityEvaluations.filter((t) => t.pendingOnActor)\n const canInteract = activityEvaluations.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 — an activity-scope slot\n * sees its activity's `$assigned` and lexical `$fields` overlay, exactly as that\n * activity'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.activity !== undefined ? {activity: slot.activity} : {}),\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 === 'activity' && slot.activity !== undefined\n ? activityScopeFor({\n scope,\n instance,\n snapshot,\n actor,\n activityName: slot.activity,\n roleAliases,\n })\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-activity\n * vars (`$assigned`, the lexical `$fields` 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 EvaluateActivityArgs {\n activity: Activity\n statusEntry: ActivityEntry | 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 an activity: the projection's base scope with the activity's\n * lexical `$fields` overlay layered on and `$assigned` set for this actor.\n * Shared by activity-action evaluation and editable activity-slot evaluation so both\n * read identically.\n */\nfunction activityScopeFor(args: {\n scope: Record<string, unknown>\n instance: WorkflowInstance\n snapshot: HydratedSnapshot\n actor: Actor\n activityName: string\n roleAliases: RoleAliases | undefined\n}): Record<string, unknown> {\n const {scope, instance, snapshot, actor, activityName, roleAliases} = args\n return {\n ...scope,\n fields: {\n ...(scope.fields as Record<string, unknown>),\n ...scopedFieldOverlay(instance, snapshot, activityName),\n },\n assigned: assignedFor(instance, activityName, actor, roleAliases),\n }\n}\n\nasync function evaluateActivity(args: EvaluateActivityArgs): Promise<ActivityEvaluation> {\n const {\n activity,\n statusEntry,\n instance,\n actor,\n snapshot,\n scope,\n roleAliases,\n stageHasExits,\n guardDenial,\n } = args\n const status: ActivityStatus = statusEntry?.status ?? 'pending'\n const activityScope = activityScopeFor({\n scope,\n instance,\n snapshot,\n actor,\n activityName: activity.name,\n roleAliases,\n })\n const assigned = activityScope.assigned === true\n\n // Readiness is an activity-level fact (requirements are declared on the activity), 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: activity.requirements,\n snapshot,\n params: activityScope,\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 activity.actions ?? []) {\n actions.push(\n await evaluateAction({\n action,\n status,\n instance,\n snapshot,\n activityScope,\n stageHasExits,\n guardDenial,\n requirementsReason,\n }),\n )\n }\n\n return {\n activity,\n status,\n kind: activityKind(activity),\n // \"pending on actor\" treats both `pending` and `active` as waiting on\n // the assignee — pending activities just haven't been activated yet, but\n // they're still inbox items. The inbox reads the assignees-kind field\n // entry BY KIND (who-data is fields).\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: ActivityStatus\n instance: WorkflowInstance\n snapshot: HydratedSnapshot\n activityScope: Record<string, unknown>\n stageHasExits: boolean\n guardDenial: DisabledReason | undefined\n /** Shared activity-readiness verdict, precomputed once per activity. */\n requirementsReason: DisabledReason | undefined\n}\n\nasync function evaluateAction(args: EvaluateActionArgs): Promise<ActionEvaluation> {\n const {\n action,\n status,\n instance,\n snapshot,\n activityScope,\n stageHasExits,\n guardDenial,\n requirementsReason,\n } = args\n\n // First failing gate wins, ordered most- to least-fundamental: lifecycle\n // (activity/instance/stage state), then the guard pre-flight (a denied instance\n // write dooms every action), then activity 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: activityScope,\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: ActivityStatus,\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 (isTerminalActivityStatus(status)) {\n return {kind: 'activity-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 */\nfunction 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): Promise<WorkflowDefinition[]> {\n // One definition per name in a batch — names, not versions, identify a batch\n // member now. A logical ref resolves to a batch member by name; an explicit\n // version pins an already-deployed one instead. Two definitions sharing a\n // name is therefore ambiguous (no version to tell them apart) — reject it.\n const byName = new Map<string, WorkflowDefinition>()\n for (const def of definitions) {\n if (byName.has(def.name)) {\n throw new Error(\n `workflow.deployDefinitions: duplicate definition name \"${def.name}\" in batch — ` +\n `names identify a batch member (versions are deploy-assigned, not authored)`,\n )\n }\n byName.set(def.name, def)\n }\n const findInBatch = (ref: LogicalRef) => findRefInBatch(byName, ref)\n\n await assertCrossBatchRefsDeployed(client, definitions, {tag, findInBatch})\n\n return topoSortDefinitions(definitions, {findInBatch})\n}\n\nexport interface LogicalRef {\n name: string\n version?: number | 'latest'\n}\n\n/** Resolve a logical ref to a batch member. A ref with no version (or\n * `latest`) matches by name; an explicit numeric version pins an\n * already-deployed version, never a batch member, so it never resolves here. */\nfunction findRefInBatch(\n byName: Map<string, WorkflowDefinition>,\n ref: LogicalRef,\n): WorkflowDefinition | undefined {\n if (typeof ref.version === 'number') return undefined\n return byName.get(ref.name)\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 findInBatch: (ref: LogicalRef) => WorkflowDefinition | undefined\n },\n): Promise<void> {\n const missing: {from: string; ref: string}[] = []\n for (const def of definitions) {\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: def.name, 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 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 if (visited.has(def.name)) return\n if (visiting.has(def.name)) {\n throw new Error(`workflow.deployDefinitions: dependency cycle involving \"${def.name}\"`)\n }\n visiting.add(def.name)\n for (const ref of refsOf(def)) {\n const child = ctx.findInBatch(ref)\n if (child !== undefined) visit(child)\n }\n visiting.delete(def.name)\n visited.add(def.name)\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 activity of stage.activities ?? []) {\n const ref = activity.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 * Content fingerprint of an authored definition: the canonical JSON of its\n * content, hashed. Stamped on the deployed document ({@link DeployedDefinition})\n * and pinned on every instance, so a redeploy of identical content is a no-op\n * and a definition that drifted from what an instance pinned is detectable.\n *\n * Advisory, like every engine check (the lake is the only enforcement point):\n * FNV-1a is a fast, deterministic, dependency-free, isomorphic digest — enough\n * to detect honest change and drift, not a tamper-proof seal. Kept synchronous\n * so the pure planning path ({@link planDefinitionDeploy}) needs no `await`.\n */\nexport function hashDefinitionContent(def: WorkflowDefinition): string {\n const canonical = stableStringify(def)\n let hash = 0xcbf29ce484222325n\n for (let i = 0; i < canonical.length; i++) {\n hash ^= BigInt(canonical.charCodeAt(i))\n hash = (hash * 0x100000001b3n) & 0xffffffffffffffffn\n }\n return hash.toString(16).padStart(16, '0')\n}\n\n/** The latest deployed version of a definition, as far as deploy planning\n * cares: its version number and (when present) the fingerprint it was\n * stamped with. A pre-fingerprint document has no `contentHash` — it then\n * always reads as changed, so the first redeploy after upgrade mints a fresh\n * version. */\nexport interface LatestDeployed {\n version: number\n contentHash?: string\n}\n\nexport interface DeployPlan {\n /** `unchanged` ⇒ identical content already deployed as the latest version;\n * `create` ⇒ a fresh version would be written. Deploy NEVER patches. */\n status: 'create' | 'unchanged'\n version: number\n contentHash: string\n docId: string\n /** The document deploy would write — meaningful only when `status` is `create`.\n * Carries `_id`/`_type` so it drops straight into a `client.create`. */\n document: {_id: string; _type: string} & Record<string, unknown>\n}\n\n/**\n * Decide what deploying one authored definition does, given the latest version\n * already deployed under its name. Content-addressed and create-only: the\n * incoming content's hash decides. Identical to the latest ⇒ no-op; any\n * difference ⇒ the next version (`latest + 1`, or `1` when none is deployed).\n * Neither `version` nor `contentHash` is authored — both are stamped here.\n *\n * The comparison is against the LATEST version only, not the full history:\n * re-deploying content byte-identical to an *older* version mints a new version\n * rather than matching it — history is linear and immutable, never rewound.\n *\n * Shared by {@link deployDefinitions} (which acts on the plan) and the diff\n * tooling (which renders it), so deploy and `definition diff` can never drift.\n */\nexport function planDefinitionDeploy(\n def: WorkflowDefinition,\n latest: LatestDeployed | undefined,\n target: {tag: string; workflowResource: WorkflowResource},\n): DeployPlan {\n const contentHash = hashDefinitionContent(def)\n const unchanged = latest !== undefined && latest.contentHash === contentHash\n const version = unchanged ? latest.version : (latest?.version ?? 0) + 1\n const docId = definitionDocId(target.workflowResource, target.tag, def.name, version)\n const document = {\n ...def,\n _id: docId,\n _type: WORKFLOW_DEFINITION_TYPE,\n tag: target.tag,\n version,\n contentHash,\n }\n return {status: unchanged ? 'unchanged' : 'create', version, contentHash, docId, document}\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<DeployedDefinition> {\n if (version !== undefined) {\n const doc = await client.fetch<DeployedDefinition | null>(definitionLookupGroq(true), {\n definition,\n version,\n 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 loadLatestDeployed(client, definition, tag)\n if (!latest) {\n throw new Error(`No deployed definition for workflow ${definition}`)\n }\n return latest\n}\n\n/**\n * The latest deployed version of a definition visible to `tag`, or undefined\n * when none is deployed. The non-throwing counterpart of {@link loadDefinition}\n * — deploy planning treats \"nothing deployed yet\" as a normal `create`, not an\n * error. Returns the full document so callers can also render the prior shape.\n */\nexport async function loadLatestDeployed(\n client: Pick<WorkflowClient, 'fetch'>,\n definition: string,\n tag: string,\n): Promise<DeployedDefinition | undefined> {\n const doc = await client.fetch<DeployedDefinition | null>(definitionLookupGroq(false), {\n definition,\n tag,\n })\n return doc ?? undefined\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 carries `_id` plus\n * the deploy-stamped envelope the authored {@link WorkflowDefinition} never\n * had: the assigned `version` and the content fingerprint it was minted from\n * ({@link hashDefinitionContent}). A pre-fingerprint document may lack\n * `contentHash` at runtime — see {@link LatestDeployed}. */\nexport type DeployedDefinition = WorkflowDefinition & {\n _id: string\n tag?: string\n version: number\n /** Optional: a document deployed before content-addressing has none — see\n * {@link LatestDeployed}. Every version this engine deploys carries one. */\n contentHash?: string\n}\n","import {retractStageGuards} from '../guards-lifecycle.ts'\nimport {randomKey} from '../keys.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {StageName} from '../types/ids.ts'\nimport {findOpenStageEntry} from '../types/instance-state.ts'\nimport {type EngineContext, findStage, loadContext} from './context.ts'\nimport {buildEffectHistoryEntry} from './effects.ts'\nimport {persist, startMutation} from './mutation.ts'\nimport type {EngineCallOptions} from './results.ts'\n\nexport type AbortResult = {fired: false} | {fired: true; stage: StageName}\n\n/**\n * Admin override — hard-stop an in-flight instance where it stands.\n * Unlike reaching a terminal stage this is not a graceful exit: no\n * transition fires (so no transition ops or effects), activity 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 {driverKind} from '../activity-kind.ts'\nimport {selfGdr} from '../core/refs.ts'\nimport type {Action, Stage, Activity} from '../define/schema.ts'\nimport {advisoryCan} from '../evaluate.ts'\nimport {randomKey} from '../keys.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {ActivityName} from '../types/ids.ts'\nimport {ctxEvaluateCondition, type EngineContext, loadCallContext} from './context.ts'\nimport {queueEffects} from './effects.ts'\nimport {\n findCurrentActivities,\n findActivityInCurrentStage,\n requireMutationActivityEntry,\n startMutation,\n} from './mutation.ts'\nimport {isFieldOp, 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 activity. The action's whole behaviour is\n * its ops + effects — activity 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`, `$fields`, …). 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 activity\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 activity the winning writer already completed\n * fails with the normal \"activity must be active\" error rather than retrying.\n */\nexport async function fireAction(args: {\n client: WorkflowClient\n instanceId: string\n activity: ActivityName\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, activity, 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, activity, 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 activity,\n action,\n attempts: CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS,\n })\n}\n\n/**\n * Resolve and gate an action fire: locate the activity + action in the\n * current stage, evaluate the action's condition with the caller bound\n * (`$actor` / `$assigned`), require the live activity 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 activityName: ActivityName,\n actionName: string,\n callerParams: Record<string, unknown> | undefined,\n options: EngineCallOptions | undefined,\n): Promise<{stage: Stage; activity: Activity; action: Action; params: Record<string, unknown>}> {\n const actor = options?.actor\n const {stage, activity} = findActivityInCurrentStage(ctx, activityName)\n const action = (activity.actions ?? []).find((a) => a.name === actionName)\n if (action === undefined) {\n throw new Error(`Action \"${actionName}\" not declared on activity \"${activityName}\"`)\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 activityName,\n ...(actor !== undefined ? {actor} : {}),\n ...(can !== undefined ? {vars: {can}} : {}),\n })\n if (!filterOk) {\n throw new Error(`Action \"${actionName}\" filter rejected on activity \"${activityName}\"`)\n }\n\n const entry = findCurrentActivities(ctx.instance).find((t) => t.name === activityName)\n if (entry === undefined || entry.status !== 'active') {\n throw new Error(\n `Activity \"${activityName}\" 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, activityName, callerParams)\n return {stage, activity, action, params}\n}\n\nasync function commitAction(\n ctx: EngineContext,\n activityName: ActivityName,\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 activityName,\n actionName,\n callerParams,\n options,\n )\n\n const mutation = startMutation(ctx.instance)\n const mutEntry = requireMutationActivityEntry(mutation, activityName)\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 activity: activityName,\n action: actionName,\n ...(actor !== undefined ? {actor, driverKind: driverKind(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. Activity 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: {activity: activityName, 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 activityName,\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 field op ran). A\n // failed refresh rolls the commit back rather than leaving guards stale.\n await persistThenDeploy(ctx, mutation, () =>\n ranOps.some(isFieldOp) ? refreshStageGuards(ctx, mutation, stage.name) : Promise.resolve(),\n )\n\n return {\n fired: true,\n activity: activityName,\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, Activity, Transition, WorkflowDefinition} from '../define/schema.ts'\nimport type {Actor} from './actor.ts'\nimport type {FieldScope, ActivityKind, ActivityStatus, TerminalActivityStatus} from './enums.ts'\nimport type {FieldKind} from './field-values.ts'\nimport type {ActionName, StageName, ActivityName} 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: 'activity-not-active'\n status: TerminalActivityStatus\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 activity's declared {@link Activity.requirements} aren't all satisfied —\n * the readiness axis. The activity 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: an activity-scope slot whose activity 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: FieldScope\n /** Present iff `scope === \"activity\"`. */\n activity?: ActivityName\n name: string\n type: FieldKind\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 ActivityEvaluation {\n activity: Activity\n status: ActivityStatus\n /**\n * The activity's effective {@link ActivityKind} — the explicit {@link Activity.kind}, or\n * the shape-derived default when omitted. Advisory: a label so a consumer can\n * render each activity as what it is (decision / wait / effect / off-system).\n */\n kind: ActivityKind\n /** Whether this activity is the current actor's responsibility right now. */\n pendingOnActor: boolean\n /**\n * The activity's unmet {@link Activity.requirements}, by name — present iff at least\n * one is unmet. The activity's own readiness summary: a consumer can explain why\n * the whole activity 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 activities: ActivityEvaluation[]\n transitions: TransitionEvaluation[]\n}\n\nexport interface WorkflowEvaluation {\n instance: WorkflowInstance\n definition: WorkflowDefinition\n actor: Actor\n currentStage: StageEvaluation\n /** Active activities whose assignees-kind field entry matches the actor. */\n pendingOnYou: ActivityEvaluation[]\n /** True if at least one action on any active activity is allowed. */\n canInteract: boolean\n /**\n * Declared-editable slots in the current scope (workflow + current stage +\n * its activities), 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 activity: ActivityName\n readonly action: ActionName\n\n constructor(args: {activity: ActivityName; action: ActionName; reason: DisabledReason}) {\n super(formatDisabledReason(args.activity, args.action, args.reason))\n this.name = 'ActionDisabledError'\n this.reason = args.reason\n this.activity = args.activity\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 'activity-not-active': (r) => `activity 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(\n activity: ActivityName,\n action: ActionName,\n reason: DisabledReason,\n): string {\n const detail = (disabledReasonDetail[reason.kind] as (r: DisabledReason) => string)(reason)\n return `Action \"${activity}:${action}\" is not allowed: ${detail}`\n}\n\n/** Edit-seam twin of {@link ActionDisabledError}: thrown by `editField` when\n * the slot can't be edited by the caller. Carries the structured reason. */\nexport class EditFieldDeniedError extends Error {\n readonly reason: EditDisabledReason\n readonly target: {scope: FieldScope; field: string; activity?: string}\n\n constructor(args: {\n target: {scope: FieldScope; field: string; activity?: string}\n reason: EditDisabledReason\n }) {\n super(formatEditDisabledReason(args.target, args.reason))\n this.name = 'EditFieldDeniedError'\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: FieldScope; field: string; activity?: string},\n reason: EditDisabledReason,\n): string {\n const detail = (editDisabledReasonDetail[reason.kind] as (r: EditDisabledReason) => string)(\n reason,\n )\n const where = target.activity !== undefined ? `${target.activity}.${target.field}` : target.field\n return `Field \"${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 {FieldScope} from '../types/enums.ts'\nimport {EditFieldDeniedError} from '../types/evaluation.ts'\nimport {ctxEvaluateCondition, type EngineContext, findStage, loadCallContext} from './context.ts'\nimport {startMutation} from './mutation.ts'\nimport {isFieldOp, runOps} from './ops.ts'\nimport {persistThenDeploy, refreshStageGuards} from './persist-deploy.ts'\nimport {\n CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS,\n ConcurrentEditFieldError,\n type EditFieldResult,\n type EngineCallOptions,\n isRevisionConflict,\n} from './results.ts'\n\n/**\n * The generic edit seam (EDEX-1319). `editField` 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 `field.*` 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 EditFieldTarget {\n /** Omit to resolve lexically (activity slot if `activity` set, else stage then workflow). */\n scope?: FieldScope\n field: string\n /** Required to address an activity-scope slot. */\n activity?: 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 editField(args: {\n client: WorkflowClient\n instanceId: string\n target: EditFieldTarget\n mode?: EditMode\n value?: unknown\n options?: EngineCallOptions\n}): Promise<EditFieldResult> {\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 ConcurrentEditFieldError({\n instanceId,\n target: labelTarget(target),\n attempts: CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS,\n })\n}\n\nasync function commitEdit(\n ctx: EngineContext,\n target: EditFieldTarget,\n mode: EditMode,\n value: unknown,\n options: EngineCallOptions | undefined,\n): Promise<EditFieldResult> {\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 field 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 === 'activity' && slot.activity !== undefined\n ? {activity: slot.activity}\n : {}),\n },\n params: {},\n actor,\n self: selfGdr(ctx.instance),\n now: ctx.now,\n })\n\n // An edit can change a field 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(isFieldOp) ? 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 EditFieldDeniedError} 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.activity !== undefined ? {activityName: slot.activity} : {}),\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 EditFieldDeniedError({target: slotTarget(slot), reason})\n}\n\nfunction buildEditOp(slot: ResolvedSlot, mode: EditMode, value: unknown): Op {\n if (mode === 'unset') return {type: 'field.unset', target: slot.ref}\n if (value === undefined) {\n throw new Error(`editField mode \"${mode}\" requires a value for slot \"${slot.name}\"`)\n }\n return {\n type: mode === 'append' ? 'field.append' : 'field.set',\n target: slot.ref,\n value: {type: 'literal', value},\n }\n}\n\nfunction slotTarget(slot: ResolvedSlot): {scope: FieldScope; field: string; activity?: string} {\n return {\n scope: slot.scope,\n field: slot.name,\n ...(slot.activity !== undefined ? {activity: slot.activity} : {}),\n }\n}\n\nfunction labelTarget(target: EditFieldTarget): {\n scope: FieldScope\n field: string\n activity?: string\n} {\n return {\n scope: target.scope ?? (target.activity !== undefined ? 'activity' : 'workflow'),\n field: target.field,\n ...(target.activity !== undefined ? {activity: target.activity} : {}),\n }\n}\n\nfunction describeTarget(target: EditFieldTarget): string {\n const where = target.activity !== undefined ? `${target.activity}.${target.field}` : target.field\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 {invokeActivity as engineInvokeActivity} from '../engine/activities.ts'\nimport {cascadeAutoTransitions, propagateToAncestors} from '../engine/cascade.ts'\nimport {editField as engineEditField, type EditMode, type EditFieldTarget} from '../engine/edit.ts'\nimport type {EngineCallOptions, OpAppliedSummary} from '../engine/results.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 EditFieldDeniedError,\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`, `editField`):\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 activity: string,\n action: string,\n): void {\n const actionEval = evaluation.currentStage.activities\n .find((t) => t.activity.name === activity)\n ?.actions.find((a) => a.action.name === action)\n if (actionEval?.allowed === false && actionEval.disabledReason) {\n throw new ActionDisabledError({activity, action, reason: actionEval.disabledReason})\n }\n}\n\n/**\n * Soft-gate before an edit write: throw {@link EditFieldDeniedError} 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: EditFieldTarget): 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 EditFieldDeniedError({\n target: {\n scope: slot.scope,\n field: slot.name,\n ...(slot.activity !== undefined ? {activity: slot.activity} : {}),\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: EditFieldTarget\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 engineEditField>>['ranOps']> {\n const {client, instance, target, mode, value, actor, grants, clock, clientForGdr} = args\n const result = await engineEditField({\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 activity 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 activity: 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, activity, action, params, actor, grants, clock, clientForGdr} = args\n const options = buildEngineCallOptions({actor, grants, clock, clientForGdr})\n const pending =\n findOpenStageEntry(instance)?.activities.find((t) => t.name === activity)?.status === 'pending'\n if (pending) {\n await engineInvokeActivity({client, instanceId: instance._id, activity, options})\n }\n const result = await engineFireAction({\n client,\n instanceId: instance._id,\n activity,\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 * (`activity.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 activities. Runtimes fire actions on activities 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 an activity with an action\n * that flips it to `failed`, plus an auto-transition filtered on\n * `anyActivityFailed`. 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 * activities (via `fireAction`) or in the lake (as document mutations\n * that filters can read).\n * - No `invokeActivity`. Activities auto-activate on stage entry. Editor's first\n * `fireAction` against a pending activity auto-invokes it before\n * applying the action.\n *\n * What filters can read:\n *\n * - Activity state on the instance (`*[_id == $self][0].stages[id == $stage && !defined(exitedAt)][0].activities[...]`)\n * - Document content in the lake (`*[_type == \"...\" && ...]`)\n * - Reserved params: `$self`, `$fields`, `$parent`, `$ancestors`, `$stage`,\n * `$now`, `$activities`, `$allActivitiesDone`, `$anyActivityFailed`\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: activities are workflow state,\n * the lake is content state, effectsContext is handler fuel.\n */\n\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 {extractDocumentId, type GdrUri, isGdrUri, type WorkflowResource} from '../core/refs.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 {recordFieldDiscards} from '../engine/history-entries.ts'\nimport {setStage as engineSetStage} from '../engine/stages.ts'\nimport {type EvaluateArgs, evaluateInstance} from '../evaluate.ts'\nimport {derivePerspectiveFromFields, resolveDeclaredFields} from '../field-resolution.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 {instanceWatchesDocument} from '../subscription-documents.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 {WORKFLOW_INSTANCE_TYPE, type WorkflowInstance} from '../types/instance.ts'\nimport {deleteDefinition as deleteDefinitionInternal} from './delete-definition.ts'\nimport {\n loadDefinition,\n loadDefinitionVersions,\n loadLatestDeployed,\n planDefinitionDeploy,\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 EditFieldArgs,\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. Definitions are\n * immutable and content-addressed: the author writes no version, and each\n * deploy compares a definition's content fingerprint to the latest version\n * already deployed under its name. Identical content is a no-op\n * (`unchanged`); any change mints the next version (`created`) — deploy\n * never patches a deployed version, so a definition can't change out from\n * under the instances pinned to it. `startInstance` picks the highest\n * version by default. The engine figures out the dependency order itself\n * (children before parents that spawn them via `subworkflows.definition`)\n * and reports a per-definition outcome (`created` / `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). Also rejects a batch with duplicate\n // names — without an authored version, a name is the batch identity.\n const ordered = await sortByDependencies(client, definitions, tag)\n\n // 3. Content-addressed, create-only deploy. For each definition compare\n // its content fingerprint to the latest deployed version: identical ⇒\n // no-op; any change ⇒ create the next version. Deploy NEVER patches a\n // deployed version — that would mutate the definition out from under\n // instances pinned to it. Every create lands in one transaction;\n // a colliding `_id` (a concurrent deploy minted the same version)\n // fails the whole batch rather than clobbering.\n const results: DeployDefinitionResult[] = []\n const tx = client.transaction()\n let hasWrites = false\n for (const def of ordered) {\n const latest = await loadLatestDeployed(client, def.name, tag)\n const plan = planDefinitionDeploy(def, latest, {tag, workflowResource})\n if (plan.status === 'unchanged') {\n results.push({definition: def.name, version: plan.version, status: 'unchanged'})\n continue\n }\n tx.create(plan.document)\n hasWrites = true\n results.push({definition: def.name, version: plan.version, status: 'created'})\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 activityStatus, queues onEnter\n * effects, auto-activates activities). 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 initialFields,\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 field entries resolve in declaration order. Later\n // entries can read earlier ones via `$fields.<name>` in their GROQ.\n // There's no privileged entry name — `$fields` exposes every\n // declared entry keyed by its author-chosen name.\n // Workflow-scope query-sourced fields can have their lake result discarded;\n // collect those audit rows to seed the new instance's history below.\n const fieldDiscards: HistoryEntry[] = []\n const resolvedFields = await resolveDeclaredFields({\n entryDefs: definition.fields ?? [],\n initialFields: initialFields ?? [],\n ctx: {\n client,\n now,\n selfId: id,\n tag,\n workflowResource,\n definitionName: definition.name,\n ...(perspective !== undefined ? {perspective} : {}),\n recordDiscard: recordFieldDiscards(fieldDiscards, 'workflow', now),\n },\n randomKey,\n })\n\n // Perspective resolution: an explicit `perspective` arg wins;\n // otherwise derive it from a populated `release.ref` field entry. This is\n // what makes a release-targeting workflow self-describing — the\n // caller fills the field entry and the engine figures out the read\n // perspective, rather than every caller having to pass it.\n const effectivePerspective = perspective ?? derivePerspectiveFromFields(resolvedFields)\n\n const base = buildInstanceBase({\n id,\n now,\n tag,\n workflowResource,\n definitionName: definition.name,\n pinnedVersion: definition.version,\n pinnedContentHash: definition.contentHash,\n definition,\n fields: resolvedFields,\n effectsContext: effectsContextEntries,\n ancestors: ancestors ?? [],\n perspective: effectivePerspective,\n initialStage: definition.initialStage,\n actor,\n ...(fieldDiscards.length > 0 ? {extraHistory: fieldDiscards} : {}),\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 an activity. If the activity 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 activity,\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 activityEntry = findOpenStageEntry(before)?.activities.find((t) => t.name === activity)\n if (activityEntry === 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, activity, action)\n return applyAction({\n client,\n instance,\n activity,\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 field 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 * `field.*` 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 editField: async (args: Clocked<EditFieldArgs>): 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 an activity 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`, `$fields`, `$parent`,\n * `$ancestors`, `$stage`, `$now`, `$effects`, `$activities`,\n * `$allActivitiesDone`, `$anyActivityFailed` — 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 * activities' 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.activities)}\n },\n\n /**\n * Materialised spawned children of a parent instance.\n *\n * Walks `history` for `spawned` events — the durable\n * record. (The per-activity `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 `activity` to restrict to a single spawning activity on the parent.\n */\n children: async (args: {\n client: WorkflowClient\n tag: string\n workflowResource: WorkflowResource\n instanceId: string\n activity?: string\n }): Promise<WorkflowInstance[]> => {\n const {client, tag, instanceId, activity} = 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) => activity === undefined || h.activity === activity)\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 * Every in-flight instance whose reactive watch-set includes `document` —\n * the reverse of {@link subscriptionDocumentsForInstance}.\n *\n * For a non-reactive, content-change-driven runtime (a Sanity Function, an\n * Inngest/durable worker, any server) that holds no instances in memory: a\n * document changed; which instances should it `tick`? The watch-set covers\n * the instance itself, its ancestors, and the docs named by\n * `doc.ref` / `doc.refs` / `release.ref` field entries on the workflow scope\n * **and the current stage** — so a hand-rolled GROQ over `fields[]` gets it\n * subtly wrong (misses stage-scope refs, `release.ref`, ancestors).\n *\n * A coarse GROQ prefilter narrows candidates server-side (in-flight,\n * tag-scoped, mentioning the doc anywhere in state); the authoritative match\n * is {@link instanceWatchesDocument}, derived from `collectWatchRefs`, so the\n * reverse stays in lockstep with the forward set and honours the\n * open-stage-only rule the prefilter deliberately over-approximates.\n *\n * Single-resource: instances always live in the engine's own resource, so\n * this reads one client (unlike {@link guardsForInstance}, whose guard docs\n * are scattered across the watched resources). \"Routed by resource\" applies\n * to the **subject**: a cross-dataset doc is matched by its full,\n * resource-qualified GDR URI, never its bare id, so an instance watching\n * `dataset:A:ds:doc` is not matched by a change to `dataset:B:ds:doc`.\n *\n * `document` must be a resource-qualified GDR URI; a bare id is rejected\n * (it can't be resource-routed and would silently mismatch). Sorted by\n * `startedAt` ascending.\n */\n instancesForDocument: async (args: {\n client: WorkflowClient\n tag: string\n workflowResource: WorkflowResource\n document: GdrUri\n }): Promise<WorkflowInstance[]> => {\n const {client, tag, document} = args\n validateTag(tag)\n if (!isGdrUri(document)) {\n throw new Error(\n `workflow.instancesForDocument: \"document\" must be a resource-qualified GDR URI ` +\n `(e.g. \"dataset:project:dataset:doc-id\"); got: ${JSON.stringify(document)}`,\n )\n }\n // True when a field-entry value is the doc (doc.ref / release.ref, whose\n // value is a GDR) or contains it (doc.refs, whose value is a GDR array).\n // One sub-expression, evaluated against the instance's `fields` at top\n // level and each stage's `fields` inside `stages[...]`, so the workflow-\n // and stage-scope arms can't drift. The whole prefilter is a deliberate\n // superset (it scans exited stages too); the exact open-stage narrowing\n // is instanceWatchesDocument's job.\n const fieldRefsDoc = `count(fields[value.id == $document]) > 0 || count(fields[$document in value[].id]) > 0`\n const query = `*[\n _type == \"${WORKFLOW_INSTANCE_TYPE}\" && ${tagScopeFilter()} && !defined(completedAt) && (\n _id == $bareId ||\n $document in ancestors[].id ||\n ${fieldRefsDoc} ||\n count(stages[${fieldRefsDoc}]) > 0\n )\n ] | order(startedAt asc)`\n const candidates = await client.fetch<WorkflowInstance[]>(query, {\n tag,\n document,\n bareId: extractDocumentId(document),\n })\n return candidates.filter((instance) => instanceWatchesDocument(instance, document))\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 {\n parseGdr,\n type GdrUri,\n type GlobalDocumentReference,\n type WorkflowResource,\n} from '../core/refs.ts'\nimport {WORKFLOW_DEFINITION_TYPE, type Effect, type WorkflowDefinition} from '../define/schema.ts'\nimport {isRevisionConflict} from '../engine/results.ts'\nimport {engineSystemActor} from '../engine/system-actor.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 {buildClientForGdr} from './operations.ts'\nimport type {\n DrainEffectsResult,\n EffectHandler,\n EngineLogger,\n LoggerFactory,\n MissingHandlerDeployInfo,\n MissingHandlerInfo,\n MissingHandlerPolicy,\n ResourceClientResolver,\n VerifyDeployedDefinitionsResult,\n} from './types.ts'\nimport {workflow} from './workflow.ts'\n\nexport async function verifyDeployedDefinitionsInternal(args: {\n client: WorkflowClient\n 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.activities ?? []) {\n visitEffects(t.effects, `stage[${stage.name}].activity[${t.name}].effects`)\n for (const a of t.actions ?? []) {\n visitEffects(\n a.effects,\n `stage[${stage.name}].activity[${t.name}].action[${a.name}].effects`,\n )\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 // Routes a handler's cross-resource subject write to the right client.\n // A split-dataset deploy keeps the instance in the engine's resource\n // (where completeEffect writes) while the subject lives in another;\n // `buildClientForGdr` falls back to the engine client for unmapped\n // resources, and `parseGdr` throws on a bare id so a handler that hands\n // one over fails loud instead of silently patching the wrong dataset.\n const routeGdr = buildClientForGdr(client, resourceClients)\n const clientFor = (ref: GdrUri | GlobalDocumentReference): WorkflowClient =>\n routeGdr(parseGdr(typeof ref === 'string' ? ref : ref.id))\n const drainerActor: Actor = args.access?.actor ?? engineSystemActor('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 clientFor,\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: {\n client: WorkflowClient\n clientFor: (ref: GdrUri | GlobalDocumentReference) => WorkflowClient\n instanceId: string\n logger: LoggerFactory\n },\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 clientFor: ctx.clientFor,\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, EditFieldTarget} 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 an activity, gated on the held content, then cascade. */\n fireAction(args: {\n activity: 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 editField(args: {\n target: EditFieldTarget\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` / `editField`); `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({activity, 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), activity, 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 activity,\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 editField({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 {GdrUri, 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 EditFieldArgs,\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 field slot directly (the generic edit seam):\n * reassign / reschedule / claim-by-hand / append-to-log, then cascade. */\n editField: (args: Bound<EditFieldArgs>) => 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` field 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 field entries, unioned over all deployed versions.\n * Needs no live instance. Guards whose resource is only known per-instance\n * (input/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 activity. Sorted by `startedAt` asc. */\n children: (args: {instanceId: string; activity?: string}) => Promise<WorkflowInstance[]>\n /** The reverse of {@link Engine.subscriptionDocumentsForInstance}: every\n * in-flight instance whose watch-set includes `document` (a resource-qualified\n * GDR URI). For a non-reactive, content-change-driven runtime deciding which\n * instances a changed doc should `tick`. Matches the same ref set the forward\n * watch-set uses (self, ancestors, current-stage `doc.ref`/`doc.refs`/`release.ref`)\n * via the shared `collectWatchRefs`. Sorted by `startedAt` asc. */\n instancesForDocument: (args: {document: GdrUri}) => 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`, `$fields`, `$parent`, `$ancestors`, `$stage`, `$now`,\n * `$effects`, `$activities`, `$allActivitiesDone`, `$anyActivityFailed`) 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 editField: (rest) => workflow.editField(bind<EditFieldArgs>(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, activity}) =>\n workflow.children({\n client,\n tag,\n workflowResource,\n instanceId,\n ...(activity !== undefined ? {activity} : {}),\n }),\n instancesForDocument: ({document}) =>\n workflow.instancesForDocument({client, tag, workflowResource, document}),\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 the latest deployed\n// version of its name as create / unchanged, reusing the engine's own\n// content-addressed deploy planner so a diff lines up exactly with what\n// `deployDefinitions` would do (never a re-derivation). Pure reasoning:\n// callers own the fetch and render the result.\n\nimport {\n loadLatestDeployed,\n planDefinitionDeploy,\n stripSystemFields,\n type LatestDeployed,\n} from './api/deploy.ts'\nimport type {WorkflowResource} from './core/refs.ts'\nimport 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 /** The version this deploy WOULD write, or the matched version when unchanged. */\n version: number\n status: 'create' | 'unchanged'\n docId: string\n /** The document deploy would write — including the stamped `version` and\n * `contentHash`. */\n expected: Record<string, unknown>\n /** The latest deployed document, system fields stripped — the prior shape to\n * diff against. Absent when nothing is deployed yet. */\n existing?: Record<string, unknown>\n}\n\n/**\n * Compare one local definition against the latest deployed version of its\n * name (or its absence), classifying it via the engine's own content-addressed\n * planner ({@link planDefinitionDeploy}). Create-only: a content change is a\n * NEW version, never an in-place update — so there is no `update` verdict.\n * Pure — the caller owns the fetch.\n */\nexport function diffEntry(\n def: WorkflowDefinition,\n latestRaw: Record<string, unknown> | undefined,\n target: DeployTarget,\n): DiffEntry {\n const plan = planDefinitionDeploy(def, asLatest(latestRaw), target)\n const existing = latestRaw ? stripSystemFields(latestRaw) : undefined\n return {\n name: def.name,\n version: plan.version,\n status: plan.status,\n docId: plan.docId,\n expected: plan.document,\n ...(existing !== undefined ? {existing} : {}),\n }\n}\n\n/** Narrow a fetched document to the `{version, contentHash}` the planner reads.\n * Fetched docs are cast (never parsed), so read both fields defensively — a\n * pre-fingerprint document has no `contentHash` and reads as changed. */\nfunction asLatest(raw: Record<string, unknown> | undefined): LatestDeployed | undefined {\n if (raw === undefined) return undefined\n const version = typeof raw.version === 'number' ? raw.version : 0\n return {version, ...(typeof raw.contentHash === 'string' ? {contentHash: raw.contentHash} : {})}\n}\n\n/** Compare each definition against the latest deployed version of its name. */\nexport async function computeDiffEntries(\n client: Pick<WorkflowClient, 'fetch'>,\n defs: WorkflowDefinition[],\n target: DeployTarget,\n): Promise<DiffEntry[]> {\n const entries: DiffEntry[] = []\n for (const def of defs) {\n const latest = await loadLatestDeployed(client, def.name, target.tag)\n entries.push(diffEntry(def, latest, target))\n }\n return entries\n}\n","/**\n * Display metadata for the discriminator literals the engine persists\n * (history entries, field-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 {DriverKind, ActivityKind} from './types/enums.ts'\nimport type {FieldKind} from './types/field-values.ts'\nimport type {HistoryEntry} from './types/history.ts'\nimport {WORKFLOW_INSTANCE_TYPE} from './types/instance.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 activityActivated: {\n title: 'Activity activated',\n description: 'An activity flipped from `pending` to `active` and its onEnter effects queued.',\n },\n activityStatusChanged: {\n title: 'Activity status changed',\n description: \"An action or op flipped an activity's status (active → done / skipped / failed).\",\n },\n actionFired: {\n title: 'Action fired',\n description:\n 'An action was invoked against an activity — 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: \"An activity'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 field-mutation op (field.set / field.append / status.set / etc.) ran during an action commit.',\n },\n fieldQueryDiscarded: {\n title: 'Query result discarded',\n description:\n \"A query-sourced field's GROQ result didn't fit the field's declared kind, so it was discarded and the field fell back to its default.\",\n },\n} satisfies Record<HistoryEntry['_type'], DisplayMetadata>\n\n/**\n * Field-entry `_type` discriminators. The entry's kind defines what\n * shape `value` takes (single GDR vs array, scalar vs notes log).\n */\nexport const FIELD_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 string: {\n title: 'String value',\n description: 'Free-form single-line string entry.',\n },\n text: {\n title: 'Text value',\n description: 'Free-form multiline string entry.',\n },\n number: {\n title: 'Number value',\n description: 'Numeric entry.',\n },\n boolean: {\n title: 'Boolean value',\n description: 'True/false entry.',\n },\n date: {\n title: 'Date value',\n description: 'Date-only (YYYY-MM-DD) entry, no time component.',\n },\n datetime: {\n title: 'Date / time value',\n description: 'ISO-8601 timestamp entry.',\n },\n url: {\n title: 'URL value',\n description: 'Validated URL entry.',\n },\n actor: {\n title: 'Actor value',\n description: 'A typed (user|ai|system) actor identity — a concrete principal.',\n },\n assignee: {\n title: 'Assignee',\n description: 'A single typed (user|role) assignee — who is expected/responsible.',\n },\n assignees: {\n title: 'Assignees',\n description: 'Ordered list of typed (user|role) assignees.',\n },\n object: {\n title: 'Object',\n description: 'An object with named sub-fields; the value is keyed by sub-field name.',\n },\n array: {\n title: 'Array',\n description:\n 'An array of objects shaped by the declared `of` sub-fields; ops add/update/remove rows.',\n },\n} satisfies Record<FieldKind, DisplayMetadata>\n\n/**\n * Op `type` discriminators — the stored mutation primitives.\n */\nexport const OP_DISPLAY = {\n 'field.set': {\n title: 'Set field entry',\n description: \"Overwrite a field entry's value with a resolved value expression.\",\n },\n 'field.unset': {\n title: 'Unset field entry',\n description: 'Reset a field entry to its default (null for scalars, [] for array kinds).',\n },\n 'field.append': {\n title: 'Append to field entry',\n description: 'Push a resolved item onto an array-kind entry (array, assignees, doc.refs).',\n },\n 'field.updateWhere': {\n title: 'Update matching rows',\n description: 'Merge fields into rows of an array-kind entry that match the predicate.',\n },\n 'field.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 activity status',\n description:\n \"Flip an activity'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 fields.',\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 * Activity-kind labels — the per-kind renderer's heading + tooltip. Kept OUT of\n * the combined {@link DISPLAY} map: kinds are a classification axis a consumer\n * looks up deliberately, not a `_type`, and `\"service\"` collides with the\n * same-named {@link DRIVER_KIND_DISPLAY} key.\n */\nexport const ACTIVITY_KIND_DISPLAY = {\n user: {\n title: 'User activity',\n description: 'A person acts via the app — renders action buttons ranked by outcome.',\n },\n service: {\n title: 'Service activity',\n description: 'An automated system or effect does the work — renders effect drain status.',\n },\n script: {\n title: 'Script activity',\n description: 'The engine runs a step inline and resolves on activation — an audit row.',\n },\n manual: {\n title: 'Manual activity',\n description:\n 'Work done off-system, acknowledged by a person or verified by a predicate — renders an instruction card with a deep-link.',\n },\n receive: {\n title: 'Receive activity',\n description:\n 'No actor; the engine waits on a condition — renders \"waiting until …\", no buttons.',\n },\n} satisfies Record<ActivityKind, DisplayMetadata>\n\n/**\n * Driver-kind labels — the actor glyph for \"who fired this action\", recorded\n * on the `actionFired` history entry. Standalone for the same reason as\n * {@link ACTIVITY_KIND_DISPLAY}.\n */\nexport const DRIVER_KIND_DISPLAY = {\n person: {title: 'Person', description: 'A human fired this action.'},\n agent: {title: 'Agent', description: 'An AI agent fired this action.'},\n service: {title: 'Service', description: 'An external system or Function fired this action.'},\n engine: {\n title: 'Engine',\n description: 'The workflow engine itself drove this — a gate, machine step, or housekeeping.',\n },\n} satisfies Record<DriverKind, DisplayMetadata>\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 ...FIELD_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":["currentActivities","actorFulfillsRole","v","parseGroq","parse","evaluate","gdrUri","doc","schema","randomKey","isTerminalActivityStatus","WORKFLOW_DEFINITION_TYPE","andConditions","DOCUMENT_VALUE_PERMISSIONS","engineAbortInstance","engineEditField","engineInvokeActivity","engineFireAction","cascade","deleteDefinitionInternal","engineCompleteEffect","engineSetStage","queryGuardsForInstance","queryGuardsForDefinition","evaluateGroq"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/core/eval.ts","../src/types/instance-state.ts","../src/core/errors.ts","../src/core/json.ts","../src/core/params.ts","../src/core/path.ts","../src/core/snapshot.ts","../src/core/source.ts","../src/keys.ts","../src/engine/history-entries.ts","../src/engine/results.ts","../src/engine/ops.ts","../src/api/validate.ts","../src/available-actions.ts","../src/clock.ts","../src/types/authorization.ts","../src/core/guards.ts","../src/diagnostics.ts","../src/guard-bindings.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/field-resolution.ts","../src/engine/context.ts","../src/core/bindings.ts","../src/instance.ts","../src/engine/mutation.ts","../src/engine/guard-commit.ts","../src/engine/persist-deploy.ts","../src/engine/effects.ts","../src/definition-query.ts","../src/discover.ts","../src/engine/system-actor.ts","../src/engine/spawn.ts","../src/engine/activities.ts","../src/engine/stages.ts","../src/engine/cascade.ts","../src/permissions.ts","../src/access.ts","../src/activity-kind.ts","../src/core/editability.ts","../src/evaluate.ts","../src/instances-query.ts","../src/api/deploy.ts","../src/engine/abort.ts","../src/types/evaluation.ts","../src/engine/actions.ts","../src/engine/edit.ts","../src/api/operations.ts","../src/api/delete-definition.ts","../src/api/workflow.ts","../src/api/types.ts","../src/api/drain.ts","../src/api/instance-session.ts","../src/api/engine-factory.ts","../src/definition-diff.ts","../src/display.ts"],"sourcesContent":["/**\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({groq: 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 (`activity.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, params: args.params, snapshot: args.snapshot})\n out[name] = isUnevaluable(result) ? null : Boolean(result)\n }\n return out\n}\n\n/**\n * Evaluate an activity'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,\n params,\n snapshot,\n}: {\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/**\n * Boundary syntax check for a condition: a GROQ parse error and/or the\n * `_type`-scan rejection, as human-readable issues (empty = well-formed).\n * Shared by deploy-time definition validation and the effect-completion\n * boundary, so every door a condition can enter speaks the same grammar.\n * The scan check is regex-based (`*[` followed by `_type`); false negatives\n * slip through harmlessly — a runtime scan still returns empty.\n *\n * With `boundVars`, every `$var` the condition reads must be in the list.\n * groq-js resolves an unbound parameter to null at evaluation, so an\n * out-of-scope read (or a typo) is a SILENT never-true — reject it here\n * instead. Only contexts whose bound set is statically fixed can pass this\n * (op `where`s); contexts that also bind author predicates cannot.\n */\nexport function conditionSyntaxIssues(groq: string, boundVars?: readonly string[]): string[] {\n const issues: string[] = []\n let tree: unknown\n try {\n tree = parse(groq)\n } catch (err) {\n issues.push(err instanceof Error ? err.message : String(err))\n }\n // A `_type` scan is a discovery query, not a predicate. Conditions evaluate\n // against the in-memory snapshot, which never contains \"all docs of type X\",\n // so a type scan returns empty and the workflow appears stuck.\n if (/\\*\\s*\\[\\s*_type\\b/.test(groq)) {\n issues.push(\n \"condition scans by `_type` — that's a discovery query, not a predicate. \" +\n 'Conditions evaluate against the in-memory snapshot (instance + ancestors + ' +\n 'field-declared docs). To bring extra docs in scope, declare a `doc.ref` ' +\n '(or `doc.refs`) field entry on the workflow or this stage. For lake scans like ' +\n '\"all articles in this release\", use `subworkflows.forEach` instead.',\n )\n }\n if (boundVars !== undefined && tree !== undefined) {\n const read = new Set<string>()\n collectParameterNames(tree, read)\n for (const name of read) {\n if (!boundVars.includes(name)) {\n issues.push(\n `reads $${name}, which this scope does not bind — an unbound variable evaluates ` +\n `to GROQ null, so the condition silently never matches. Bound here: ` +\n boundVars.map((n) => `$${n}`).join(', '),\n )\n }\n }\n }\n return issues\n}\n\n/**\n * Every `$var` a parsed condition reads, collected from the groq-js AST\n * (`Parameter` nodes) — exact, unlike a regex scan, which a `$name` inside a\n * string literal would false-positive.\n */\nfunction collectParameterNames(node: unknown, out: Set<string>): void {\n if (Array.isArray(node)) {\n for (const item of node) collectParameterNames(item, out)\n return\n }\n if (typeof node !== 'object' || node === null) return\n const candidate = node as {type?: unknown; name?: unknown}\n if (candidate.type === 'Parameter' && typeof candidate.name === 'string') {\n out.add(candidate.name)\n }\n for (const value of Object.values(node)) collectParameterNames(value, out)\n}\n","/**\n * Per-stage instance state.\n *\n * The instance carries `stages: StageEntry[]` — one entry per stage the\n * instance has been in, in entry order. The CURRENT stage is the last\n * entry whose `exitedAt` is undefined. Past stages persist with\n * `exitedAt` set so the audit trail is complete.\n *\n * Each StageEntry owns its activities. ActivityEntry is the activity's runtime state\n * (status, who/when, spawned subworkflows). Its `name` matches the\n * authoring `Activity.name`.\n */\n\nimport type {GlobalDocumentReference} from '../core/refs.ts'\nimport type {ActivityStatus} from './enums.ts'\nimport type {ResolvedFieldEntry} from './field-values.ts'\nimport type {StageName, ActivityName} from './ids.ts'\n\nexport interface ActivityEntry {\n _key: string\n /** Matches the authoring `Activity.name`. */\n name: ActivityName\n status: ActivityStatus\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 activity in scope) rather than reading this as a deliberate\n * `false`; `truthy` is `false` here but the activity is NOT skipped.\n */\n unevaluable?: boolean\n detail?: string\n }\n /**\n * Subworkflows started by this activity (via `activity.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 activity's\n * `completeWhen` / `failWhen`.\n */\n spawnedInstances?: GlobalDocumentReference[]\n /** Activity-scoped resolved field entries. Absent until the engine writes to it. */\n fields?: ResolvedFieldEntry[]\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 field entries. */\n fields: ResolvedFieldEntry[]\n activities: ActivityEntry[]\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/**\n * The current stage's {@link ActivityEntry} named `activityName`, or\n * `undefined` when the open stage holds no such activity (including when\n * `activityName` is itself `undefined`). Composes {@link findOpenStageEntry}\n * with the by-name lookup that activity ops, editability, params, and the\n * operation pre-flights all need — callers keep their own `.status` / `.fields`\n * chain off the result.\n */\nexport function findCurrentActivityEntry(\n host: {stages: StageEntry[]; currentStage: StageName},\n activityName: ActivityName | undefined,\n): ActivityEntry | undefined {\n return findOpenStageEntry(host)?.activities.find((a) => a.name === activityName)\n}\n","/**\n * Pure error helpers — no client, no I/O. The one home for the engine's\n * \"coerce an unknown caught value\" + \"rethrow with context\" idioms, so the\n * message shape and cause-chaining can't drift across call sites.\n */\n\n/** A human-readable message for an unknown caught value: `.message` for an\n * {@link Error}, otherwise `String(value)`. */\nfunction errorMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err)\n}\n\n/**\n * Rethrow `err` wrapped with a `context` prefix while preserving the original\n * as the new error's `cause`. The single shape for the engine's\n * \"operation X failed: <why>\" rethrows — returns `never` so a `catch` body that\n * calls it satisfies the surrounding function's return type.\n */\nexport function rethrowWithContext(err: unknown, context: string): never {\n throw new Error(`${context}: ${errorMessage(err)}`, {cause: err})\n}\n","/**\n * Recursively rebuild a JSON-ish value, replacing every string leaf with\n * `transform(str, key)`. `key` is the object property the string sits under\n * (for an array element, its enclosing array's property), `undefined` at the\n * root. Objects and arrays are cloned; `null`/`undefined` and non-string\n * scalars pass through.\n *\n * The single deep-walk the engine's leaf-rewriting passes share — lake-param id\n * stripping ({@link paramsForLake}), snapshot `_ref` rewriting\n * ({@link restampForSnapshot}), and deploy-time resource-alias expansion\n * ({@link expandResourceAliases}) — so the descent skeleton lives in one place\n * and only the per-leaf transform differs.\n */\nexport function mapJsonStrings(\n value: unknown,\n transform: (str: string, key: string | undefined) => string,\n): unknown {\n // `key` is the recursion-carried enclosing property — undefined at the root,\n // never supplied by callers — so it rides the inner walk, not the public arity.\n const walk = (val: unknown, key: string | undefined): unknown => {\n if (typeof val === 'string') return transform(val, key)\n if (Array.isArray(val)) return val.map((item) => walk(item, key))\n if (val !== null && typeof val === 'object') {\n const out: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(val)) out[k] = walk(v, k)\n return out\n }\n return val\n }\n return walk(value, 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: the always-bound vars of the\n * {@link CONDITION_VARS} inventory. Context-bound vars (caller / spawn)\n * and the author's pre-evaluated predicates ride in via `extra` — the\n * shell composes them per evaluation context.\n *\n * `assignedFor(instance, activityName, actor, roleAliases)` — the `$assigned`\n * computation: does the caller match the activity's `assignees`-kind field\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 type {Assignee, ResolvedFieldEntry} from '../types/field-values.ts'\nimport {\n findCurrentActivityEntry,\n findOpenStageEntry,\n type ActivityEntry,\n type StageEntry,\n} from '../types/instance-state.ts'\nimport type {WorkflowInstance} from '../types/instance.ts'\nimport {rethrowWithContext} from './errors.ts'\nimport {mapJsonStrings} from './json.ts'\nimport {selfGdr, toBareId} 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, `$fields` doc-ref reads render the HYDRATED document\n * (`$fields.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 currentActivities = findOpenStageEntry(instance)?.activities ?? []\n return {\n self: selfGdr(instance),\n fields: renderedFields(instance.fields ?? [], 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 /** `$effectStatus` — has the named effect drained for THIS stage entry? */\n effectStatus: effectStatusMap(instance),\n /** `$activities` — the current stage's activity rows, statuses included. */\n activities: currentActivities,\n ...activityGateParams(currentActivities),\n ...extra,\n }\n}\n\n/**\n * The `$allActivitiesDone` / `$anyActivityFailed` gate pair over one stage's\n * activity rows — shared by the full rendered scope and the op-`where` scope.\n */\nexport function activityGateParams(activities: readonly ActivityEntry[]): {\n allActivitiesDone: boolean\n anyActivityFailed: boolean\n} {\n return {\n allActivitiesDone: activities.every(\n (activity) => activity.status === 'done' || activity.status === 'skipped',\n ),\n anyActivityFailed: activities.some((activity) => activity.status === 'failed'),\n }\n}\n\n/**\n * `$fields.<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). Activity- and stage-scope entries ride in via the evaluation\n * context's `extra` ({@link scopedFieldOverlay}) and shadow lexically.\n */\nexport function renderedFields(\n entries: readonly ResolvedFieldEntry[],\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: ResolvedFieldEntry, 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-/activity-scope fields in the current evaluation context —\n * merged over the workflow-scope `$fields` map so inner declarations shadow\n * outer ones, exactly like the deploy-time lexical resolution of writes.\n * Takes the structural `stages` + `currentStage` host (the shape\n * {@link findOpenStageEntry} reads) so the persisted instance and the engine's\n * mutable copy share the one shadowing rule.\n */\nexport function scopedFieldOverlay({\n instance,\n snapshot,\n activityName,\n}: {\n instance: {stages: StageEntry[]; currentStage: string}\n snapshot: HydratedSnapshot | undefined\n activityName?: string | undefined\n}): Record<string, unknown> {\n const stageEntry = findOpenStageEntry(instance)\n if (stageEntry === undefined) return {}\n const stageFields = renderedFields(stageEntry.fields ?? [], snapshot)\n const activity = activityName\n ? stageEntry.activities.find((t) => t.name === activityName)\n : undefined\n return {...stageFields, ...renderedFields(activity?.fields ?? [], snapshot)}\n}\n\n/**\n * The `$assigned` computation: true iff the caller matches the activity's\n * `assignees`-kind field 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,\n activityName,\n actor,\n roleAliases,\n}: {\n instance: WorkflowInstance\n activityName: string\n actor: Actor | undefined\n roleAliases: RoleAliases | undefined\n}): boolean {\n if (actor === undefined) return false\n const activity = findCurrentActivityEntry(instance, activityName)\n const entry = activity?.fields?.find((s) => s._type === 'assignees')\n if (entry === undefined) return false\n return (entry.value as Assignee[]).some((a) =>\n a.type === 'user'\n ? a.id === actor.id\n : actorFulfillsRole({actorRoles: actor.roles, required: a.role, aliases: roleAliases}),\n )\n}\n\n/**\n * `$effectStatus` — effect name → the status of the latest completed run\n * QUEUED under the current stage entry; a name absent until its effect\n * drains for this entry. Re-entry-safe where naive `effectHistory` reads are\n * not: the match is the queueing entry's `_key` (never a timestamp, which\n * ties under frozen clocks and same-commit loop-backs), so runs queued under\n * a prior entry of the same stage — even ones completing late, after\n * re-entry — never count, and a gate like `$effectStatus['<effect>'] ==\n * 'done'` holds until the fresh run lands. Rows persisted before the stamp\n * never match (fail closed).\n *\n * Structural host (like {@link scopedFieldOverlay}) so the persisted instance\n * and the engine's mutable copy share the one computation.\n */\nexport function effectStatusMap(instance: {\n stages: StageEntry[]\n currentStage: string\n effectHistory: WorkflowInstance['effectHistory']\n}): Record<string, 'done' | 'failed'> {\n const entry = findOpenStageEntry(instance)\n if (entry === undefined) return {}\n const out: Record<string, 'done' | 'failed'> = {}\n for (const run of instance.effectHistory) {\n if (run.stageEntryKey === entry._key) out[run.name] = run.status\n }\n return out\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(\n instance: Pick<WorkflowInstance, 'effectsContext'>,\n): 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 rethrowWithContext(err, `effectsContext entry \"${entry.name}\" holds unparseable JSON`)\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 == $fields.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 `$fields` 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' ? toBareId(params.self) : params.self,\n parent: typeof params.parent === 'string' ? toBareId(params.parent) : params.parent,\n ancestors: Array.isArray(params.ancestors)\n ? params.ancestors.map((a) => (typeof a === 'string' ? toBareId(a) : a))\n : params.ancestors,\n fields: stripFieldsForLake(params.fields),\n }\n}\n\nfunction stripFieldsForLake(value: unknown): unknown {\n return mapJsonStrings(value, (s) => toBareId(s))\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, field-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 * 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 {mapJsonStrings} from './json.ts'\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, gdrUri: uri, resource})\n docs.push(restamped)\n knownIds.add(uri)\n }\n return {docs, knownIds}\n}\n\n/**\n * A snapshot with nothing hydrated — derefs and `*[...]` joins see an empty\n * dataset. Fresh per call: `knownIds` is mutable, so callers never share one.\n */\nexport function emptySnapshot(): HydratedSnapshot {\n return {docs: [], knownIds: new Set()}\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,\n gdrUri,\n resource,\n}: {\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 return mapJsonStrings(value, (str, key) =>\n // Only `_ref` string values become URIs; already-qualified ones pass through.\n key === '_ref' && !str.includes(':') ? gdrFromResource(resource, str) : str,\n )\n}\n","/**\n * Pure resolution of the context-free {@link ValueExpr} arms.\n *\n * A `ValueExpr` declared on an op is evaluated into a concrete value. The arms\n * here need no resolver-specific backing data — just the caller params, the\n * acting actor, and the engine clock. No GROQ, no client, no I/O.\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 {ValueExpr} from '../define/schema.ts'\nimport type {Actor} from '../types/actor.ts'\n\n/**\n * The context-free {@link ValueExpr} arms — resolvable from caller params, the\n * actor, and the clock alone. The remaining arms (`self` / `stage` /\n * `fieldRead` / `object`) need resolver-specific backing data and are handled\n * by the in-mutation op resolver (see `engine/ops.ts`) against the mutation it\n * is building.\n */\ntype StaticValueExpr = Extract<ValueExpr, {type: 'literal' | 'param' | 'actor' | 'now'}>\n\nexport function resolveStaticValueExpr(\n src: StaticValueExpr,\n ctx: {params?: Record<string, unknown>; actor?: Actor | undefined; now: string},\n): unknown {\n switch (src.type) {\n case 'literal':\n return src.value\n case 'param':\n return ctx.params?.[src.param]\n case 'actor':\n return ctx.actor\n case 'now':\n return ctx.now\n }\n}\n","/** Hex-encoded random key, sliced to {@link length} chars. Used for every\n * Sanity array `_key` and document id suffix the engine mints. */\nexport function randomKey(length = 12): string {\n const bytes = new Uint8Array(length)\n globalThis.crypto.getRandomValues(bytes)\n return [...bytes]\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n .slice(0, length)\n}\n\n/**\n * Mint the Sanity document `_id` for a workflow instance — a fresh\n * {@link randomKey} suffix, so every instance (root or spawned child) gets a\n * unique doc id under its tag. Lives in the shell, not `core/`, because it\n * draws randomness; the deterministic {@link definitionDocId} is the pure-core\n * counterpart. Bare form — Sanity rejects `:` in document IDs, so this is\n * never a GDR URI.\n */\nexport function instanceDocId(tag: string): string {\n return `${tag}.wf-instance.${randomKey()}`\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 * activity activator can all stamp entries without import cycles.\n */\n\nimport {randomKey} from '../keys.ts'\nimport type {Actor} from '../types/actor.ts'\nimport {type ActivityStatus, type FieldScope, isTerminalActivityStatus} from '../types/enums.ts'\nimport type {HistoryEntry} from '../types/history.ts'\nimport type {StageName} from '../types/ids.ts'\nimport type {ActivityEntry} from '../types/instance-state.ts'\n\n/**\n * Audit row for a `query`-sourced field whose lake result didn't fit its\n * declared kind and was discarded (the field fell back to its default).\n * Resolution is fail-soft for query results — lake data is runtime/external,\n * so a mismatch is recorded here rather than aborting materialisation.\n */\nfunction fieldQueryDiscardedEntry(args: {\n scope: FieldScope\n field: string\n detail: string\n at: string\n}): Extract<HistoryEntry, {_type: 'fieldQueryDiscarded'}> {\n return {\n _key: randomKey(),\n _type: 'fieldQueryDiscarded',\n at: args.at,\n scope: args.scope,\n field: args.field,\n detail: args.detail,\n }\n}\n\n/**\n * Bind a `recordDiscard` sink (the {@link ResolveFieldContext.recordDiscard}\n * shape) that appends a {@link fieldQueryDiscardedEntry} to `target` for the\n * given scope + clock. Shared by every field-resolution call site so a\n * discarded query result always lands on the audit trail the same way.\n */\nexport function recordFieldDiscards({\n target,\n scope,\n at,\n}: {\n target: HistoryEntry[]\n scope: FieldScope\n at: string\n}): (discard: {field: string; detail: string}) => void {\n return (discard) =>\n target.push(fieldQueryDiscardedEntry({scope, field: discard.field, detail: discard.detail, at}))\n}\n\n/**\n * The ONE activity-status flip. Sets the entry's status, stamps\n * `completedAt`/`completedBy` when the new status is terminal, and pushes\n * the `activityStatusChanged` audit row — every boundary that flips an activity\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 applyActivityStatusChange(args: {\n entry: ActivityEntry\n history: HistoryEntry[]\n stage: StageName\n to: ActivityStatus\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 (isTerminalActivityStatus(to)) {\n entry.completedAt = at\n if (actor !== undefined) entry.completedBy = actor.id\n }\n history.push({\n _key: randomKey(),\n _type: 'activityStatusChanged',\n at,\n stage,\n activity: 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 {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 {FieldScope, ActivityStatus} from '../types/enums.ts'\nimport {WorkflowError} from '../types/errors.ts'\nimport type {StageName, ActivityName} 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 activity: ActivityName\n}\n\nexport interface OpAppliedSummary {\n opType: string\n target?: {scope: FieldScope; field: string}\n resolved?: Record<string, unknown>\n}\n\nexport interface ActionResult {\n fired: boolean\n activity: ActivityName\n action: string\n newStatus?: ActivityStatus\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 WorkflowError<'action-params-invalid'> {\n readonly action: string\n readonly activity: ActivityName\n readonly issues: {param: string; reason: string}[]\n constructor(args: {\n action: string\n activity: ActivityName\n issues: {param: string; reason: string}[]\n }) {\n const lines = args.issues.map((i) => ` - ${i.param}: ${i.reason}`).join('\\n')\n super(\n 'action-params-invalid',\n `Action \"${args.action}\" on activity \"${args.activity}\" rejected: invalid params\\n${lines}`,\n )\n this.name = 'ActionParamsInvalidError'\n this.action = args.action\n this.activity = args.activity\n this.issues = args.issues\n }\n}\n\n/**\n * Thrown when the ops an effect handler returns from its completion don't\n * parse against the stored op schema — a malformed `field.*` / `status.set`\n * (bad `type`, missing `target`, wrong `value` shape). The completion does not\n * commit; the engine has not mutated state. Mirrors {@link ActionParamsInvalidError}:\n * a handler is external code, so its returned ops are validated at the\n * completion boundary rather than trusted to be well-formed.\n */\nexport class EffectOpsInvalidError extends WorkflowError<'effect-ops-invalid'> {\n readonly effect: string\n readonly issues: string[]\n constructor(args: {effect: string; issues: string[]}) {\n const lines = args.issues.map((i) => ` - ${i}`).join('\\n')\n super(\n 'effect-ops-invalid',\n `Effect \"${args.effect}\" returned invalid completion ops:\\n${lines}`,\n )\n this.name = 'EffectOpsInvalidError'\n this.effect = args.effect\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 field entry marked `required`. Mirrors {@link ActionParamsInvalidError}:\n * the engine has NOT created the instance — a missing load-bearing field\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 RequiredFieldNotProvidedError extends WorkflowError<'required-field-not-provided'> {\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-field-not-provided',\n `Required input fields${where} were not provided:\\n${lines}\\n` +\n `Provide each via \\`initialFields\\` when starting standalone, or via the parent's ` +\n `\\`subworkflows.with\\` when spawned.`,\n )\n this.name = 'RequiredFieldNotProvidedError'\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 WorkflowError<'workflow-state-diverged'> {\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-state-diverged',\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 WorkflowError<'partial-guard-deploy'> {\n readonly stageName: string\n readonly deployed: number\n constructor(args: {stageName: string; deployed: number; cause: unknown}) {\n super(\n 'partial-guard-deploy',\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 WorkflowError<'concurrent-fire-action'> {\n readonly instanceId: string\n readonly activity: ActivityName\n readonly action: string\n readonly attempts: number\n constructor(args: {\n instanceId: string\n activity: ActivityName\n action: string\n attempts: number\n }) {\n super(\n 'concurrent-fire-action',\n `Action \"${args.action}\" on activity \"${args.activity}\" (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.activity = args.activity\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 activity) 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 `editField` 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 ConcurrentEditFieldError extends WorkflowError<'concurrent-edit-field'> {\n readonly instanceId: string\n readonly target: {scope: FieldScope; field: string; activity?: string}\n readonly attempts: number\n constructor(args: {\n instanceId: string\n target: {scope: FieldScope; field: string; activity?: string}\n attempts: number\n }) {\n const where =\n args.target.activity !== undefined\n ? `${args.target.activity}.${args.target.field}`\n : args.target.field\n super(\n 'concurrent-edit-field',\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 = 'ConcurrentEditFieldError'\n this.instanceId = args.instanceId\n this.target = args.target\n this.attempts = args.attempts\n }\n}\n\nexport interface EditFieldResult {\n edited: boolean\n target: {scope: FieldScope; field: string; activity?: 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.field.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 WorkflowError<'cascade-limit'> {\n readonly instanceId: string\n readonly limit: number\n constructor(args: {instanceId: string; limit: number}) {\n super(\n 'cascade-limit',\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 * as v from 'valibot'\n\nimport {conditionSyntaxIssues, evaluateCondition} from '../core/eval.ts'\nimport {\n formatIssues,\n validateFieldAppendItem,\n validateFieldValue,\n} from '../core/field-validation.ts'\nimport {\n activityGateParams,\n effectsContextMap,\n effectStatusMap,\n renderedFields,\n scopedFieldOverlay,\n} from '../core/params.ts'\nimport {getPath} from '../core/path.ts'\nimport {emptySnapshot} from '../core/snapshot.ts'\nimport {resolveStaticValueExpr} from '../core/source.ts'\nimport {\n type Action,\n type ActionParam,\n type FieldOp,\n type FieldShape,\n type Op,\n StoredFieldOpSchema,\n type StoredFieldRef,\n type ValueExpr,\n} from '../define/schema.ts'\nimport {randomKey} from '../keys.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {ResolvedFieldEntry} from '../types/field-values.ts'\nimport type {HistoryEntry} from '../types/history.ts'\nimport type {StageName, ActivityName, EffectName} from '../types/ids.ts'\nimport {findCurrentActivityEntry, findOpenStageEntry} from '../types/instance-state.ts'\nimport {applyActivityStatusChange} from './history-entries.ts'\nimport type {MutableInstance} from './mutation.ts'\nimport {ActionParamsInvalidError, EffectOpsInvalidError, type OpAppliedSummary} from './results.ts'\n\n// Op runner — shared by every lifecycle boundary that carries ops (action\n// fire, transition fire, activity activation) — plus action param validation.\n\n/**\n * Op types that mutate workflow fields (vs `status.set`, which only flips an\n * activity 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 FIELD_OP_TYPES = [\n 'field.set',\n 'field.unset',\n 'field.append',\n 'field.updateWhere',\n 'field.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 isFieldOp(summary: OpAppliedSummary): boolean {\n return (FIELD_OP_TYPES as readonly string[]).includes(summary.opType)\n}\n\nexport function validateActionParams({\n action,\n activityName,\n callerParams,\n}: {\n action: Action\n activityName: ActivityName\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, activity: activityName, 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) &&\n value.every((ref) => checkParamType(ref, {...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 activity?: ActivityName\n action?: string\n transition?: string\n /** A direct edit through the edit seam (`editField`) rather than an\n * action/transition/activation. */\n edit?: true\n /** The effect whose completion returned these ops — the state half of an\n * effect, applied in the completion commit. */\n effect?: EffectName\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 `ValueExpr.self`. */\n self: string\n /** Shell-supplied clock reading (ISO) — `now` op-source + history `at`. */\n now: string\n}\n\nexport async function runOps(args: RunOpsArgs): Promise<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 = await applyOp(op, {\n mutation,\n stage,\n activityName: origin.activity,\n params,\n actor,\n self,\n now,\n })\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 / effect), the op's type + resolved\n * target, 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.activity !== undefined ? {activity: origin.activity} : {}),\n ...(origin.action !== undefined ? {action: origin.action} : {}),\n ...(origin.transition !== undefined ? {transition: origin.transition} : {}),\n ...(origin.edit === true ? {edit: true} : {}),\n ...(origin.effect !== undefined ? {effect: origin.effect} : {}),\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\n/**\n * Validate the `field.*` ops an effect handler returned from its completion. A\n * handler is external data, so its ops are parsed against {@link StoredFieldOpSchema}\n * at the completion boundary (rather than at deploy like an action's) — a\n * malformed op fails loud here, and `status.set` is rejected by construction\n * (the field-op schema has no such arm): an effect reports its result as field\n * state, never by flipping an activity status. Activity-scope targets are\n * rejected too — an effect has no firing activity at completion time, so it\n * writes workflow- or stage-scope fields and lets the gate read them. A\n * where-op's `where` gets the same parse + `_type`-scan check deploy applies\n * to definition-carried ops, so a malformed condition aborts the completion\n * here instead of throwing raw from groq-js mid-commit. Valid ops run through\n * the same {@link runOps} applier every other boundary uses.\n */\nexport function validateEffectOps(ops: unknown, effectName: EffectName): FieldOp[] {\n const result = v.safeParse(v.array(StoredFieldOpSchema), ops)\n if (!result.success) {\n throw new EffectOpsInvalidError({effect: effectName, issues: formatIssues(result.issues)})\n }\n const activityScoped = result.output.find((op) => op.target.scope === 'activity')\n if (activityScoped !== undefined) {\n throw new EffectOpsInvalidError({\n effect: effectName,\n issues: [\n `${activityScoped.type} targets an activity-scope field — an effect's completion ops write workflow- or stage-scope fields`,\n ],\n })\n }\n const whereIssues = result.output.flatMap((op) =>\n op.type === 'field.updateWhere' || op.type === 'field.removeWhere'\n ? conditionSyntaxIssues(op.where, WHERE_SCOPE_PARAM_NAMES).map(\n (issue) => `${op.type} target \"${op.target.field}\" where: ${issue}`,\n )\n : [],\n )\n if (whereIssues.length > 0) {\n throw new EffectOpsInvalidError({effect: effectName, issues: whereIssues})\n }\n return result.output\n}\n\ninterface OpContext {\n mutation: MutableInstance\n stage: StageName\n /** The activity whose boundary is running — `scope: \"activity\"` targets land here. */\n activityName: ActivityName | undefined\n params: Record<string, unknown>\n actor: Actor | undefined\n self: string\n now: string\n}\n\nasync function applyOp(op: Op, ctx: OpContext): Promise<OpAppliedSummary> {\n switch (op.type) {\n case 'field.set':\n return applyFieldSet(op, ctx)\n case 'field.unset':\n return applyFieldUnset(op, ctx)\n case 'field.append':\n return applyFieldAppend(op, ctx)\n case 'field.updateWhere':\n return applyFieldUpdateWhere(op, ctx)\n case 'field.removeWhere':\n return applyFieldRemoveWhere(op, ctx)\n case 'status.set':\n return applyStatusSet(op, ctx)\n }\n}\n\nfunction applyFieldSet(op: Extract<Op, {type: 'field.set'}>, ctx: OpContext): OpAppliedSummary {\n const value = resolveOpValue(op.value, ctx)\n const entry = locateEntry(ctx, op.target)\n // Wrong-shape writes throw `FieldValueShapeError` — the engine aborts the\n // commit before persisting.\n validateFieldValue({entryType: entry._type, entryName: entry.name, value, ...entryShape(entry)})\n setEntryValue(entry, value)\n return {opType: op.type, target: op.target, resolved: {value}}\n}\n\n/**\n * The declared sub-field shape of a compositional entry, threaded into\n * validation. `object` / `array` resolved entries carry it (the instance is\n * self-describing); every other kind has none.\n */\nfunction entryShape(entry: ResolvedFieldEntry): {fields?: FieldShape[]; of?: FieldShape[]} {\n if (entry._type === 'object') return {fields: entry.fields}\n if (entry._type === 'array') return {of: entry.of}\n return {}\n}\n\n/** Array-valued kinds clear to empty; everything else to null (`!defined`). */\nconst EMPTY_BY_KIND: Partial<Record<ResolvedFieldEntry['_type'], unknown[]>> = {\n 'doc.refs': [],\n array: [],\n assignees: [],\n}\n\nfunction applyFieldUnset(op: Extract<Op, {type: 'field.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 applyFieldAppend(\n op: Extract<Op, {type: 'field.append'}>,\n ctx: OpContext,\n): OpAppliedSummary {\n const item = resolveOpValue(op.value, ctx)\n const entry = locateEntry(ctx, op.target)\n validateFieldAppendItem({\n entryType: entry._type,\n entryName: entry.name,\n item,\n of: entry._type === 'array' ? entry.of : undefined,\n })\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\nasync function applyFieldUpdateWhere(\n op: Extract<Op, {type: 'field.updateWhere'}>,\n ctx: OpContext,\n): Promise<OpAppliedSummary> {\n const entry = locateEntry(ctx, op.target)\n const rows = requireArrayValue(entry, op)\n const merge = resolveOpValue(op.value, ctx)\n if (merge === null || typeof merge !== 'object' || Array.isArray(merge)) {\n throw new Error(\n `field.updateWhere value must resolve to an object of fields to merge (target \"${op.target.field}\")`,\n )\n }\n const matches = await rowMatches({where: op.where, rows, ctx})\n setEntryValue(\n entry,\n rows.map((row, index) =>\n matches[index] ? {...row, ...(merge as Record<string, unknown>)} : row,\n ),\n )\n return {opType: op.type, target: op.target, resolved: {merge}}\n}\n\nasync function applyFieldRemoveWhere(\n op: Extract<Op, {type: 'field.removeWhere'}>,\n ctx: OpContext,\n): Promise<OpAppliedSummary> {\n const entry = locateEntry(ctx, op.target)\n const rows = requireArrayValue(entry, op)\n const matches = await rowMatches({where: op.where, rows, ctx})\n setEntryValue(\n entry,\n rows.filter((_, index) => !matches[index]),\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: ResolvedFieldEntry,\n op: Extract<Op, {type: 'field.updateWhere' | 'field.removeWhere'}>,\n): Record<string, unknown>[] {\n if (!Array.isArray(entry.value)) {\n throw new Error(\n `${op.type} target ${op.target.scope}:\"${op.target.field}\" 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 applyActivityStatusChange} — the ONE activity-status mechanism —\n * after resolving the op's activity name against the open stage.\n */\nfunction applyStatusSet(op: Extract<Op, {type: 'status.set'}>, ctx: OpContext): OpAppliedSummary {\n const entry = findCurrentActivityEntry(ctx.mutation, op.activity)\n if (entry === undefined) {\n throw new Error(\n `status.set targets activity \"${op.activity}\" which has no entry in the open stage`,\n )\n }\n applyActivityStatusChange({\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: {activity: op.activity, status: op.status}}\n}\n\n/**\n * The single write seam for entry values. `ResolvedFieldEntry` 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 validateFieldValue} /\n * {@link validateFieldAppendItem}) or built from already-valid data (the\n * per-kind empty on unset, the where-op transforms over existing rows).\n */\nfunction setEntryValue(entry: ResolvedFieldEntry, 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: StoredFieldRef): ResolvedFieldEntry {\n const host = fieldHost(ctx, target.scope)\n const entry = host?.find((s) => s.name === target.field)\n if (entry === undefined) {\n throw new Error(\n `Op target ${target.scope}:\"${target.field}\" has no resolved field entry on this instance — ` +\n `the deployed definition and the instance state have diverged`,\n )\n }\n return entry\n}\n\nfunction fieldHost(\n ctx: OpContext,\n scope: StoredFieldRef['scope'],\n): ResolvedFieldEntry[] | undefined {\n if (scope === 'workflow') return ctx.mutation.fields\n const stageEntry = findOpenStageEntry(ctx.mutation)\n if (scope === 'stage') return stageEntry?.fields\n const activity = stageEntry?.activities.find((t) => t.name === ctx.activityName)\n if (activity !== undefined && activity.fields === undefined) activity.fields = []\n return activity?.fields\n}\n\nfunction resolveOpValue(src: ValueExpr, ctx: OpContext): unknown {\n switch (src.type) {\n case 'literal':\n case 'param':\n case 'actor':\n case 'now':\n return resolveStaticValueExpr(src, ctx)\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 expression).\n return ctx.self\n case 'stage':\n return ctx.stage\n case 'fieldRead': {\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] = resolveOpValue(fieldSrc, ctx)\n }\n return out\n }\n }\n}\n\nfunction entryValue(entries: ResolvedFieldEntry[] | undefined, name: string): unknown {\n return entries?.find((s) => s.name === name)?.value\n}\n\nfunction readEntryFromMutation(\n ctx: OpContext,\n src: Extract<ValueExpr, {type: 'fieldRead'}>,\n): 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.fields : stageEntry?.fields\n const value = entryValue(host, src.field)\n if (value !== undefined) return value\n }\n return undefined\n}\n\n/** No docs are hydrated at op time, so `where` evaluates over params alone —\n * derefs and joins see an empty dataset (GROQ null → no match). */\nconst EMPTY_SNAPSHOT = emptySnapshot()\n\n/**\n * Evaluate a where-op's `where` condition once per row: rendered-scope GROQ\n * with the op-only `$row` / `$params` bound. Truthy means the row matches;\n * GROQ null (an unevaluable comparison — a missing key, an incomparable\n * operand) never matches — `where` selects rows, it doesn't gate, so\n * undecidable stays out instead of failing closed. Everything but `$row` is\n * row-invariant, so the scope is assembled once for the whole walk.\n */\nasync function rowMatches({\n where,\n rows,\n ctx,\n}: {\n where: string\n rows: readonly Record<string, unknown>[]\n ctx: OpContext\n}): Promise<boolean[]> {\n const base = whereParams(ctx)\n return Promise.all(\n rows.map((row) =>\n evaluateCondition({\n condition: where,\n snapshot: EMPTY_SNAPSHOT,\n params: {...base, row},\n }),\n ),\n )\n}\n\n/**\n * Exactly the variables a where-op's `where` may read: the keys\n * {@link whereParams} binds plus the per-row `$row`. The deploy check and the\n * effect-completion boundary reject any other read via\n * {@link conditionSyntaxIssues} — groq-js evaluates an unbound variable to\n * null, so an out-of-scope read (or a typo) would otherwise silently match no\n * rows. Grow this list and `whereParams` together.\n */\nexport const WHERE_SCOPE_PARAM_NAMES = [\n 'row',\n 'params',\n 'actor',\n 'now',\n 'self',\n 'stage',\n 'fields',\n 'effects',\n 'effectStatus',\n 'activities',\n 'allActivitiesDone',\n 'anyActivityFailed',\n] as const\n\n/**\n * The rendered-scope slice a `where` condition sees — everything the mutation\n * itself can answer without hydration: raw field values (the one lexical\n * overlay, {@link scopedFieldOverlay}, with no doc rendering), `$effects` and\n * `$effectStatus`, the activity rows and gate pair, plus the op-only `$params`\n * (the caller merges `$row`). `$parent`/`$ancestors` are not bound (the\n * mutation doesn't carry ancestry), neither are `$can`/`$assigned`/\n * named-condition booleans, and `doc.ref` fields hold their reference\n * envelope, never the hydrated document.\n */\nfunction whereParams(ctx: OpContext): Record<string, unknown> {\n const activities = findOpenStageEntry(ctx.mutation)?.activities ?? []\n return {\n params: ctx.params,\n actor: ctx.actor ?? null,\n now: ctx.now,\n self: ctx.self,\n stage: ctx.stage,\n fields: {\n ...renderedFields(ctx.mutation.fields, undefined),\n ...scopedFieldOverlay({\n instance: ctx.mutation,\n snapshot: undefined,\n activityName: ctx.activityName,\n }),\n },\n effects: effectsContextMap(ctx.mutation),\n effectStatus: effectStatusMap(ctx.mutation),\n activities,\n ...activityGateParams(activities),\n }\n}\n","import {parse as parseGroq} from 'groq-js'\n\nimport {conditionSyntaxIssues} from '../core/eval.ts'\nimport {isGuardReadExpr} from '../core/guard-reads.ts'\nimport type {Guard, Stage, FieldEntry, Activity, Op, WorkflowDefinition} from '../define/schema.ts'\nimport {WHERE_SCOPE_PARAM_NAMES} from '../engine/ops.ts'\n\n/**\n * Parse-validate every GROQ string in a (stored, desugared) definition\n * before deploy. Surfaces malformed predicates, conditions, bindings, and\n * `activity.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.fields ?? []) {\n v.checkEntry(entry, `workflow.fields \"${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 `validateDefinition(\"${definition.name}\"): ` +\n `${v.errors.length} deploy-time 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 /** {@link checkCondition} plus the closed-scope `$var` check — op `where`s\n * only, the one condition context whose bound set is statically fixed. */\n checkWhere: (groq: string, where: string) => void\n /** Parse-check a `query`-sourced field entry's GROQ. */\n checkEntry: (entry: FieldEntry, 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 // Parse + `_type`-scan rejection live in the shared {@link conditionSyntaxIssues},\n // so the effect-completion boundary rejects exactly what deploy rejects.\n const pushConditionIssues = (where: string, issues: string[]) => {\n for (const issue of issues) {\n errors.push(` · ${where}: ${issue}`)\n }\n }\n const checkCondition = (groq: string, where: string) =>\n pushConditionIssues(where, conditionSyntaxIssues(groq))\n const checkWhere = (groq: string, where: string) =>\n pushConditionIssues(where, conditionSyntaxIssues(groq, WHERE_SCOPE_PARAM_NAMES))\n const checkEntry = (entry: FieldEntry, label: string) => {\n if (entry.initialValue?.type === 'query') tryParse(entry.initialValue.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\", \"$fields.<name>[.path]\", or \"$effects['<name>'][.path]\" (guards store resolved ` +\n `values; the lake cannot see $fields or $effects)`,\n )\n }\n return {errors, tryParse, checkCondition, checkWhere, checkEntry, checkGuardRead}\n}\n\nfunction validateStage(v: DefinitionValidator, stage: Stage): void {\n for (const entry of stage.fields ?? []) {\n v.checkEntry(entry, `stage \"${stage.name}\".fields \"${entry.name}\"`)\n }\n for (const guard of stage.guards ?? []) {\n validateGuardReads({v, stageName: 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 checkOpWheres({v, ops: t.ops, label: `transition \"${t.name}\"`})\n for (const [key, groq] of effectBindings(t.effects)) {\n v.tryParse(groq, `transition \"${t.name}\" effect binding \"${key}\"`)\n }\n }\n for (const activity of stage.activities ?? []) {\n validateActivity({v, stageName: stage.name, activity})\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({\n v,\n stageName,\n guard,\n}: {\n v: DefinitionValidator\n stageName: string\n guard: Guard\n}): 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 validateActivity({\n v,\n stageName,\n activity,\n}: {\n v: DefinitionValidator\n stageName: string\n activity: Activity\n}): void {\n const where = `stage \"${stageName}\" activity \"${activity.name}\"`\n for (const entry of activity.fields ?? []) {\n v.checkEntry(entry, `${where}.fields \"${entry.name}\"`)\n }\n if (activity.filter !== undefined) v.checkCondition(activity.filter, `${where}.filter`)\n if (activity.completeWhen !== undefined)\n v.checkCondition(activity.completeWhen, `${where}.completeWhen`)\n if (activity.failWhen !== undefined) v.checkCondition(activity.failWhen, `${where}.failWhen`)\n for (const [name, groq] of Object.entries(activity.requirements ?? {})) {\n v.checkCondition(groq, `${where}.requirements \"${name}\"`)\n }\n checkOpWheres({v, ops: activity.ops, label: where})\n for (const [key, groq] of effectBindings(activity.effects)) {\n v.tryParse(groq, `${where} effect binding \"${key}\"`)\n }\n validateActivityActions(v, activity)\n if (activity.subworkflows !== undefined)\n validateSubworkflows({v, where, sub: activity.subworkflows})\n}\n\nfunction validateActivityActions(v: DefinitionValidator, activity: Activity): void {\n for (const a of activity.actions ?? []) {\n if (a.filter !== undefined) {\n v.checkCondition(a.filter, `activity \"${activity.name}\" action \"${a.name}\".filter`)\n }\n checkOpWheres({v, ops: a.ops, label: `activity \"${activity.name}\" action \"${a.name}\"`})\n for (const [key, groq] of effectBindings(a.effects)) {\n v.tryParse(groq, `activity \"${activity.name}\" action \"${a.name}\" effect binding \"${key}\"`)\n }\n }\n}\n\n/** The where-ops' `where` is a condition like any filter — parse-check it (and\n * reject `_type` scans) wherever ops appear: activities, actions, transitions.\n * Its bound set is statically fixed ({@link WHERE_SCOPE_PARAM_NAMES}), so this\n * is the one condition site that can also reject out-of-scope `$var` reads —\n * an unbound variable is GROQ null and would silently match no rows. */\nfunction checkOpWheres({\n v,\n ops,\n label,\n}: {\n v: DefinitionValidator\n ops: readonly Op[] | undefined\n label: string\n}): void {\n for (const op of ops ?? []) {\n if (op.type === 'field.updateWhere' || op.type === 'field.removeWhere') {\n v.checkWhere(op.where, `${label} ${op.type} where`)\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,\n where,\n sub,\n}: {\n v: DefinitionValidator\n where: string\n sub: NonNullable<Activity['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 activities\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 {ActivityStatus} from './types/enums.ts'\nimport type {\n ActionEvaluation,\n DisabledReason,\n ActivityEvaluation,\n WorkflowEvaluation,\n} from './types/evaluation.ts'\n\nexport interface AvailableAction {\n activity: string\n activityStatus: ActivityStatus\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 an activity — its `allowed`\n * state, structured `disabledReason`, and declared params, tagged with the\n * owning activity. The per-action atom both projections share:\n * {@link availableActions} flattens it across a stage's activities; a consumer\n * that keeps per-activity nesting (e.g. the MCP) maps it over an activity's actions\n * directly, so the verdict shape has a single source. */\nexport function actionVerdict(\n activity: ActivityEvaluation,\n action: ActionEvaluation,\n): AvailableAction {\n return {\n activity: activity.activity.name,\n activityStatus: activity.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 activities into the actions the actor\n * could fire, each carrying whether it's allowed (and why not). */\nexport function availableActions(activities: ActivityEvaluation[]): AvailableAction[] {\n return activities.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'\nimport {WorkflowError} from './errors.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.\n *\n * The enforcement story hangs off this type: the lake does not evaluate\n * this doc type — it is the engine's placeholder for the lake's\n * forthcoming guard primitive (the lake reserves `system.*`). Until that\n * primitive ships, deployed guards deny OPTIMISTICALLY engine-side only, on\n * every project plan, and the lake ACL is the only hard gate. At cutover the\n * `temp.` prefix drops here, in exactly one place, and deployed guards become\n * lake-enforced (a breaking type change for already-persisted guard docs).\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 /**\n * Provenance stamp — who registered the guard (the engine writes its own\n * marker here). Unenforced: nothing reads `owner`, and there is no\n * owner/admin modification rule — guard deploy/refresh/retract ride the\n * caller's token like every other engine write. A lake-enforced guard can\n * therefore lock the engine's own housekeeping out (self-lockout) until a\n * dedicated engine execution identity exists.\n */\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 /**\n * Caller-asserted actor id, resolved as `identity()` in the predicate.\n * Advisory — the engine takes the caller's word for who is acting; only\n * the lake's own token identity is authenticated.\n */\n identity?: string\n}\n\n/**\n * One denying guard, as carried by both the read-side verdict\n * (`mutation-guard-denied` in {@link DisabledReason}) and the thrown\n * {@link MutationGuardDeniedError} — one shape for the same denial, so a\n * consumer renders it once.\n */\nexport interface DeniedGuardRef {\n guardId: string\n name?: string\n}\n\n/**\n * Thrown when one or more guards deny a mutation — raised by the engine's\n * optimistic pre-flight and the bench's write seam; carries every denial.\n * Fail-closed: a predicate that errors or is non-true denies.\n *\n * The ONE guard-denial error: every verb whose write a guard denies —\n * `fireAction`, `editField`, `tick`, a session tick, a bench write — throws\n * this class, never a verb-specific wrapper.\n */\nexport class MutationGuardDeniedError extends WorkflowError<'mutation-guard-denied'> {\n readonly denied: DeniedGuardRef[]\n readonly documentId: string\n readonly action: MutationGuardAction\n\n constructor(args: {documentId: string; action: MutationGuardAction; denied: DeniedGuardRef[]}) {\n const ids = args.denied.map((d) => d.guardId).join(', ')\n super(\n 'mutation-guard-denied',\n `Mutation on \"${args.documentId}\" (${args.action}) denied by guard(s) [${ids}]`,\n )\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, shared by every\n * 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: deniedGuardRefs(args.guards),\n })\n }\n}\n\n/**\n * The one mapping from {@link MutationGuardDoc} to the structured\n * {@link DeniedGuardRef} payload — shared by the thrown error and the\n * read-side `mutation-guard-denied` verdict, so the two can't drift.\n */\nexport function deniedGuardRefs(guards: readonly MutationGuardDoc[]): DeniedGuardRef[] {\n return guards.map((g) => ({\n guardId: g._id,\n ...(g.name !== undefined ? {name: g.name} : {}),\n }))\n}\n\n/**\n * Human label per denying guard — the authored `name` when present, else the\n * raw guard id. The one display convention for rendering a denial to a\n * person; the payload keeps the raw ids for operators locating the guard doc.\n */\nexport function deniedGuardLabels(denied: readonly DeniedGuardRef[]): string[] {\n return denied.map((d) => d.name ?? d.guardId)\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 {@link GUARD_DOC_TYPE} doc and\n * to 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 deployed guard docs\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 caller-asserted actor id (advisory — see\n * {@link MutationContext.identity}), the same way `permissions.ts` feeds\n * 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 the engine's optimistic\n * 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,\n doc,\n action,\n}: {\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 * The param bag a guard predicate evaluates against — the one place the\n * guard-dialect identifiers (`GUARD_PREDICATE_VARS`) are bound.\n */\nexport function guardPredicateParams(args: {\n guard: MutationGuardDoc\n action: MutationGuardAction\n}): Record<string, unknown> {\n return {guard: args.guard, mutation: {action: args.action}}\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 = guardPredicateParams({guard, 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, action: 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 applies 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 — an inherent window of\n * the optimistic model (nothing re-evaluates guards at commit); the\n * rollback/diverged 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 {ActivityStatus} from './types/enums.ts'\nimport type {\n ActivityEvaluation,\n TransitionEvaluation,\n WorkflowEvaluation,\n} from './types/evaluation.ts'\nimport type {Assignee, ResolvedFieldEntry} from './types/field-values.ts'\nimport type {HistoryEntry} from './types/history.ts'\nimport {findOpenStageEntry, type StageEntry} from './types/instance-state.ts'\nimport type {WorkflowInstance} from './types/instance.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 activity looking merely \"active\", so it wins over the activity- and\n * transition-level symptoms it produces. Note an active activity 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-activity'; activity: string}\n | {kind: 'no-transition-fires'}\n /**\n * Every activity 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 activity 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'; activity: string; assignees: Assignee[]; actions: string[]}\n // Healthy in-flight, but not yet actionable: an active activity whose declared\n // requirements aren't all met — the readiness axis. It flips to `waiting`\n // once the preconditions hold (typically when a sibling activity 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'; activity: 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-activity`\n * are not yet callable engine operations — see {@link SuggestedRemediation.available}.\n */\nexport type RemediationVerb =\n | 'retry-effect'\n | 'drain-effects'\n | 'reset-activity'\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 activities: ActivityEvaluation[]\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 activities + 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 activities: evaluation.currentStage.activities,\n transitions: evaluation.currentStage.transitions,\n assignees: Object.fromEntries(\n evaluation.currentStage.activities.map((t) => [\n t.activity.name,\n assigneesOf(stage, t.activity.name),\n ]),\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 an activity in a stage — the runtime half of the\n * \"who is this waiting on\" answer. Empty when the activity is unassigned. */\nfunction assigneesOf(stage: StageEntry | undefined, activityName: string): Assignee[] {\n const entry = stage?.activities.find((t) => t.name === activityName)\n return (entry?.fields ?? [])\n .filter((s): s is Extract<ResolvedFieldEntry, {_type: 'assignees'}> => s._type === 'assignees')\n .flatMap((s) => s.value)\n}\n\n/** An activity that has resolved one way or another — done or skipped. */\nfunction isResolved(status: ActivityStatus): boolean {\n return status === 'done' || status === 'skipped'\n}\n\n/**\n * A failed effect whose origin activity 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 activity 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(\n input.activities.filter((t) => !isResolved(t.status)).map((t) => t.activity.name),\n )\n const effect = [...input.instance.effectHistory]\n .reverse()\n .find(\n (e) => e.status === 'failed' && e.origin.kind === 'activity' && stalled.has(e.origin.name),\n )\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 failedActivityCause(input: DiagnoseInput): StuckCause | undefined {\n const failed = input.activities.find((t) => t.status === 'failed')\n return failed ? {kind: 'failed-activity', activity: failed.activity.name} : undefined\n}\n\n/** An active activity 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 // An activity 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.activities.find(\n (t) =>\n t.status === 'active' &&\n (t.activity.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 activity: active.activity.name,\n assignees: input.assignees[active.activity.name] ?? [],\n actions: (active.activity.actions ?? []).map((a) => a.name),\n }\n}\n\n/** An active activity held by the readiness axis — its declared requirements\n * aren't all met, so none of its actions can fire yet. Requires the activity 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 activity elsewhere; the hold is not a stuck cause. */\nfunction blockedState(input: DiagnoseInput): Extract<Diagnosis, {state: 'blocked'}> | undefined {\n const blocked = input.activities.find(\n (t) =>\n t.status === 'active' &&\n (t.activity.actions ?? []).length > 0 &&\n (t.unmetRequirements ?? []).length > 0,\n )\n if (blocked === undefined) {\n return undefined\n }\n return {\n state: 'blocked',\n activity: blocked.activity.name,\n requirements: blocked.unmetRequirements ?? [],\n assignees: input.assignees[blocked.activity.name] ?? [],\n }\n}\n\n/**\n * Every activity 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.activities.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 activity 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 failedActivityCause(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-activity`, 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-activity':\n return [\n {verb: 'reset-activity', rationale: 'Reset or skip the failed activity.'},\n {\n verb: 'set-stage',\n rationale: 'Move the instance past the failed activity 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 {EFFECTS_READ, FIELD_READ} from './core/guard-reads.ts'\nimport {effectsContextMap} from './core/params.ts'\nimport {getPath} from './core/path.ts'\nimport {isGdrUri, parseGdr, resourceFromParsed, selfGdr} from './core/refs.ts'\nimport type {ParsedGdr, WorkflowResource} from './core/refs.ts'\nimport type {WorkflowInstance} from './types/instance.ts'\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/**\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-field-op / effect-completion\n * refresh): the engine bakes the value into the guard doc, so the lake never\n * needs to see `$fields` or `$effects`. Deliberately a tiny reader, not full\n * GROQ: a guard value is `\"$self\"`, `\"$now\"`, `\"$fields.<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 fieldRead = FIELD_READ.exec(expr)\n if (fieldRead !== null) {\n const entry = (ctx.instance.fields ?? []).find((s) => s.name === fieldRead[1])\n const value = entry?.value\n return fieldRead[2] !== undefined ? getPath(value, fieldRead[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 `\"$fields.<name>[.path]\", or \"$effects['<name>'][.path]\" (guards store resolved values; ` +\n `the lake cannot see $fields 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[]): WorkflowResource {\n const resource = resourceFromParsed(targets[0]!.parsed)\n for (const g of targets) {\n const r = resourceFromParsed(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 `$fields`/`$effects`) to workflow fields. */\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","// Instance — the persisted instance document (see WORKFLOW_INSTANCE_TYPE).\n\nimport type {SanityDocument} from '@sanity/types'\n\nimport {rethrowWithContext} from '../core/errors.ts'\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 {ResolvedFieldEntry} from './field-values.ts'\nimport type {HistoryEntry} from './history.ts'\nimport type {StageName} from './ids.ts'\nimport type {StageEntry} from './instance-state.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 /**\n * Content fingerprint of the pinned definition version (see\n * {@link hashDefinitionContent}). Pinned alongside the version so a consumer\n * can detect a deployed definition that drifted from what this instance\n * started on. Advisory — the engine enforces nothing; this enables detection,\n * not prevention. Absent when the instance was started against a definition\n * deployed before content-addressing (it carried no hash to pin).\n */\n pinnedContentHash?: string\n /** Frozen JSON snapshot of the definition at the moment the instance started. */\n definitionSnapshot: string\n /**\n * Workflow-level resolved field entries.\n * Populated from the workflow definition's `fields[]` declarations plus\n * the caller-supplied `initialFields` 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\", initialValue: { type: \"input\" } }`\n * entry to the workflow definition. Conditions then read it as\n * `$fields.subject`. There is no other subject mechanism.\n */\n fields: ResolvedFieldEntry[]\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 field-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 activities.\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 rethrowWithContext(err, `Failed to parse definitionSnapshot on instance \"${instance._id}\"`)\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` field 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` field entries, and the **release** docs named\n * by `release.ref` field entries — on the workflow scope, the current stage,\n * and the current stage's activities (an exited stage's refs drop out at all\n * three scopes). Order: self, ancestors, content field entries, release field\n * entries. May contain 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 const activityFields = stage?.activities.map((activity) => activity.fields) ?? []\n return [\n gdrRef({res: instance.workflowResource, documentId: instance._id, type: instance._type}),\n ...instance.ancestors,\n ...entryDocRefs(instance.fields),\n ...entryDocRefs(stage?.fields),\n ...activityFields.flatMap(entryDocRefs),\n ...entryReleaseRefs(instance.fields),\n ...entryReleaseRefs(stage?.fields),\n ...activityFields.flatMap(entryReleaseRefs),\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` field 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 * Whether {@link document} is in {@link instance}'s reactive watch-set — the\n * reverse of {@link subscriptionDocumentsForInstance}. Both derive from\n * {@link collectWatchRefs}, the single source of truth, so \"which docs does\n * this instance watch\" and \"which instances watch this doc\" stay in lockstep\n * — the same way {@link hydrateSnapshot}'s load-set does. Matching is on the\n * resource-qualified GDR URI, so a cross-dataset subject (`dataset:A:ds:doc`)\n * never matches a same-id doc in another resource (`dataset:B:ds:doc`).\n *\n * A non-reactive, content-change-driven runtime uses this to decide whether a\n * changed document should re-`tick` an instance it does not hold in memory.\n */\nexport function instanceWatchesDocument(instance: WorkflowInstance, document: GdrUri): boolean {\n return collectWatchRefs(instance).some((ref) => ref.id === document)\n}\n\n/**\n * Pull the {@link GlobalDocumentReference} values out of `doc.ref` /\n * `doc.refs` (content) field entries. Content only — release field entries come\n * from {@link entryReleaseRefs}, so guard discovery (which reads this via\n * `collectEntryDocUris`) stays scoped to content docs.\n */\nexport function entryDocRefs(entries: unknown): GlobalDocumentReference[] {\n return fieldEntries(entries).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 * field 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(entries: unknown): GlobalDocumentReference[] {\n return fieldEntries(entries).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 * field 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(entries: unknown): GlobalDocumentReference[] {\n return fieldEntries(entries).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-field entry array to the `{_type, value}` shape\n * the ref extractors read. Tolerates `unknown` (resolved field entry arrays are\n * polymorphic) and drops non-object entries.\n */\nfunction fieldEntries(entries: unknown): {_type?: string; value?: unknown}[] {\n if (!Array.isArray(entries)) return []\n return entries.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` field entry on\n * the workflow OR the current stage,\n * - or the `system.release` doc named by a `release.ref` field 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 {\n resourceFromParsed,\n selfGdr,\n tryParseGdr,\n type ParsedGdr,\n type WorkflowResource,\n} 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 defaultClient: client,\n clientForGdr,\n defaultResource: 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/field 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,\n clientForGdr,\n defaultResource,\n uri,\n perspective,\n}: {\n defaultClient: WorkflowClient\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient\n defaultResource: WorkflowResource\n uri: string\n perspective: WorkflowPerspective\n}): Promise<LoadedDoc | null> {\n const parsed = tryParseGdr(uri)\n if (parsed === undefined) {\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({client: defaultClient, id: uri, perspective})\n if (!doc) return null\n return {doc, resource: defaultResource}\n }\n const routed = clientForGdr(parsed)\n const doc = await readDoc({client: routed, id: 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 field-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,\n id,\n perspective,\n}: {\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\n/**\n * Walk resolved field entries and collect every GDR URI mentioned by a\n * `doc.ref` or `doc.refs` field entry's value. The GDR-keyed id list lake\n * guard discovery needs; {@link entryDocRefs} is the typed source.\n */\nexport function collectEntryDocUris(resolvedFieldEntries: unknown): string[] {\n return entryDocRefs(resolvedFieldEntries).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 {\n resourceFromParsed,\n tryParseGdr,\n type ParsedGdr,\n type WorkflowResource,\n} from './core/refs.ts'\nimport type {Stage, FieldEntry, WorkflowDefinition} from './define/schema.ts'\nimport {collectEntryDocUris} from './snapshot.ts'\nimport {GUARD_DOC_TYPE, type MutationGuardDoc} from './types/authorization.ts'\nimport type {CompiledQuery, 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): CompiledQuery {\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 applies 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, not enforcement);\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 InstanceGuardsQueryArgs {\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(\n args: InstanceGuardsQueryArgs,\n): Promise<MutationGuardDoc[]> {\n const {client, clientForGdr, instance} = args\n\n const stateUris = [\n ...collectEntryDocUris(instance.fields),\n ...instance.stages.flatMap((stage) => collectEntryDocUris(stage.fields)),\n ...instance.stages.flatMap((stage) =>\n stage.activities.flatMap((activity) => collectEntryDocUris(activity.fields)),\n ),\n ]\n const clients = resourceClientMap({\n base: instance.workflowResource,\n baseClient: client,\n clientForGdr,\n gdrs: stateUris.map((uri) => tryParseGdr(uri)),\n })\n const {query, params} = instanceGuardQuery(instance._id)\n return queryGuardsAcross({clients: clients.values(), query, params})\n}\n\nexport interface DefinitionGuardsQueryArgs {\n client: WorkflowClient\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient\n workflowResource: WorkflowResource\n definition: string\n /** Every deployed version of {@link DefinitionGuardsQueryArgs.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 DefinitionGuardsQueryArgs.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 `fieldRead` of a field entry whose\n * `initialValue` is a literal GDR — or to the workflow resource (`self`, or a\n * `query`-sourced field entry, which restamps into it). Guards whose resource is\n * only known once an instance exists — reading a `subject` / `input` / otherwise\n * runtime-sourced field 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: DefinitionGuardsQueryArgs,\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: DefinitionGuardsQueryArgs,\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, definition: def})),\n )\n const clients = resourceClientMap({\n base: workflowResource,\n baseClient: client,\n clientForGdr,\n gdrs,\n })\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 * `$fields` read string; the only static non-workflow case is an entry whose\n * declared `initialValue` is a literal GDR. Everything else (`input`,\n * `query`, or working memory) resolves at runtime — the documented\n * per-instance boundary.\n */\nfunction staticIdRefGdr({\n idRef,\n stage,\n definition,\n}: {\n idRef: string\n stage: Stage\n definition: WorkflowDefinition\n}): ParsedGdr | undefined {\n const read = /^\\$fields\\.([\\w-]+)/.exec(idRef)\n if (read === null) return undefined\n const seed = entriesInScope(stage, definition).find((e) => e.name === read[1])?.initialValue\n return seed?.type === 'literal' ? gdrFromValue(seed.value) : undefined\n}\n\n/** The statically-declared entries reachable from a stage's guards. */\nfunction entriesInScope(stage: Stage, definition: WorkflowDefinition): readonly FieldEntry[] {\n return [\n ...(definition.fields ?? []),\n ...(stage.fields ?? []),\n ...(stage.activities ?? []).flatMap((activity) => activity.fields ?? []),\n ]\n}\n\n/** Parse a GDR from a literal `initialValue` — 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\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,\n baseClient,\n clientForGdr,\n gdrs,\n}: {\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,\n query,\n params,\n}: {\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 (field-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 field-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\n/**\n * The API surface the engine's reads and writes assume. Every client bound to\n * the engine pins this one version so they cannot drift apart.\n */\nexport const ENGINE_API_VERSION = '2026-04-29'\n\n/**\n * A compiled lake read — what the engine's query builders return and what a\n * reactive adapter's live-query store subscribes with, so the stateless and\n * reactive paths run the same GROQ.\n */\nexport interface CompiledQuery {\n query: string\n params: Record<string, string>\n}\n\nexport interface WorkflowClient {\n // oxlint-disable-next-line max-params -- interface member mirrors @sanity/client's positional fetch(query, params?, options?) shape; external implementors must keep it\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 field 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 field 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 persisted mutation-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. A deliberate simplification; orphan\n * accumulation + cross-dataset non-atomicity are documented seams.\n *\n * Reconcile runs post-persist, outside the instance's `ifRevisionId` guard, so\n * both primitives gate on the instance's live committed stage (see\n * {@link committedStage}) to drop stale / superseded reconciles. The window\n * between that live-stage read and the guard write is itself non-atomic across\n * resources — the same documented-seam direction (over-lock) as above.\n *\n * Enforcement is OPTIMISTIC: deploying a guard does not make the lake enforce\n * it. The engine evaluates guards itself (core/guards.ts); the bench throws.\n */\n\nimport {compileGuard, lakeGuardId} from './core/guards.ts'\nimport type {ParsedGdr, 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\n/**\n * Whether a guard has been lifted (retracted to the unconditional-allow\n * predicate). A lift patches the predicate and keeps the doc, so lifted\n * guards still appear in guard queries and streams — this is the\n * discriminator a consumer filters or renders by.\n */\nexport function isGuardLifted(guard: Pick<MutationGuardDoc, 'predicate'>): boolean {\n return guard.predicate === GUARD_LIFTED_PREDICATE\n}\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,\n instance,\n stageName,\n now,\n}: {\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({\n guard,\n instance: args.instance,\n stageName: args.stageName,\n now: args.now,\n })\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-lock 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 live.\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","/**\n * Resolve a definition's `fields[]` declarations into `ResolvedFieldEntry`s.\n *\n * Shared by:\n * - `workflow.startInstance` (workflow-scope fields)\n * - engine stage entry (stage-scope fields on StageEntry)\n * - engine activity activation (activity-scope fields on ActivityEntry)\n *\n * `initialValue` (FieldSource) semantics:\n * - absent → working memory: defaults to null (scalars) or `[]` (array kinds);\n * ops fill it later.\n * - `type: \"input\"` reads from caller-supplied `initialFields`.\n * - `type: \"literal\"` uses the declared constant.\n * - `type: \"fieldRead\"` copies a sibling/ancestor entry's resolved value.\n * - `type: \"query\"` runs the entry's GROQ against the lake via the\n * supplied client; the result is validated against the entry's declared\n * kind — conforming results land as the value (with `resolvedAt` stamped),\n * a non-conforming result is discarded (default value) and recorded via\n * {@link ResolveFieldContext.recordDiscard}.\n */\n\nimport {rethrowWithContext} from './core/errors.ts'\nimport {checkFieldValue, isBareSeedId, validateFieldValue} from './core/field-validation.ts'\nimport {paramsForLake} from './core/params.ts'\nimport {getPath} from './core/path.ts'\nimport {isGdrUri, toPhysicalGdr, type WorkflowResource} from './core/refs.ts'\nimport type {FieldEntry, FieldShape, FieldSource} from './define/schema.ts'\nimport {RequiredFieldNotProvidedError} from './engine/results.ts'\nimport {DEFAULT_CONTENT_PERSPECTIVE} from './subscription-documents.ts'\nimport type {WorkflowClient, WorkflowPerspective} from './types/client.ts'\nimport {ContractViolationError} from './types/errors.ts'\nimport type {InitialFieldValue, ResolvedFieldEntry} from './types/field-values.ts'\n\n/**\n * Sink the caller supplies to be told a `query`-sourced entry's lake result was\n * discarded (didn't fit the declared kind). The caller owns the instance\n * history + knows the scope, so it turns each into a `fieldQueryDiscarded` row.\n */\nexport type RecordFieldDiscard = (discard: {field: string; detail: string}) => void\n\nexport interface ResolveFieldContext {\n /** Lake client for `type: \"query\"` entry evaluation. Omitted → query\n * field 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`-sourced entries, so\n * field 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 RequiredFieldNotProvidedError} message when\n * a `required` input entry is unfilled. Workflow-scope callers (start/spawn)\n * pass it; stage/activity-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/activity-scope query entries. */\n stageName?: string\n /** Bound to `$activity` inside activity-scope query entries. */\n activityName?: string\n /**\n * Already-resolved field entries in the SAME scope being resolved\n * right now. Exposed to subsequent query-sourced field entries as\n * `$fields.<entryName>`; also the lookup target for\n * `initialValue: { type: \"fieldRead\", scope: \"stage\" }` on a sibling\n * stage-scope entry. Sequential resolution means entry N's seed can\n * read field entries 0..N-1 by id but not later ones.\n */\n resolvedFields?: ResolvedFieldEntry[]\n /**\n * Already-resolved workflow-scope fields. Available when resolving\n * stage- or activity-scope field entries so a `initialValue: { type: \"fieldRead\",\n * scope: \"workflow\" }` can read durable workflow-scope field entries that\n * were resolved at `startInstance` time.\n */\n workflowFields?: ResolvedFieldEntry[]\n /**\n * Resource of the workflow itself. Used to canonicalize raw Sanity\n * reference shapes (`{_ref, _type}`) returned by `type: \"query\"`\n * field 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 * Sink for a `query`-sourced entry whose lake result didn't fit its declared\n * kind and was discarded. The caller (which owns the instance history and\n * knows the scope) turns each into a `fieldQueryDiscarded` audit row, so the\n * discard is visible rather than silent. Omitted → still discards, just not\n * recorded (no caller has a history to write to).\n */\n recordDiscard?: RecordFieldDiscard\n}\n\n/**\n * Derive a read perspective from resolved workflow-scope fields: 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 field entries.\n */\nexport function derivePerspectiveFromFields(\n entries: ResolvedFieldEntry[] | 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 resolveDeclaredFields(args: {\n entryDefs: FieldEntry[] | undefined\n initialFields: InitialFieldValue[]\n ctx: ResolveFieldContext\n randomKey: () => string\n}): Promise<ResolvedFieldEntry[]> {\n const {entryDefs, initialFields, ctx, randomKey} = args\n if (entryDefs === undefined || entryDefs.length === 0) return []\n assertRequiredInputProvided({entryDefs, initialFields, definitionName: ctx.definitionName})\n const out: ResolvedFieldEntry[] = []\n for (const entry of entryDefs) {\n // Each entry sees the already-resolved ones via `$fields.<entryName>`.\n const scopedCtx: ResolveFieldContext = {...ctx, resolvedFields: out}\n out.push(await resolveOneEntry({entry, initialFields, ctx: scopedCtx, randomKey}))\n }\n return out\n}\n\n/**\n * Fail fast when a `required` input 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 RequiredFieldNotProvidedError}'s param sibling),\n * rather than failing on the first. Keys on the same name+type as the input read\n * in {@link resolveInputValue}, but is stricter: a present-but-null/undefined\n * value counts as absent here (a required field needs a real value), whereas\n * {@link resolveInputValue} passes a null fill straight through. The deploy\n * invariant guarantees only workflow-scope `input` entries reach here marked\n * required, so stage/activity resolution no-ops.\n */\nfunction assertRequiredInputProvided({\n entryDefs,\n initialFields,\n definitionName,\n}: {\n entryDefs: FieldEntry[]\n initialFields: InitialFieldValue[]\n definitionName: string | undefined\n}): void {\n const missing = entryDefs\n .filter((entry) => entry.required === true && entry.initialValue?.type === 'input')\n .filter((entry) => {\n const match = initialFields.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 RequiredFieldNotProvidedError({\n ...(definitionName !== undefined ? {definition: definitionName} : {}),\n missing,\n })\n}\n\nconst ARRAY_FIELD_TYPES = new Set<FieldEntry['type']>(['doc.refs', 'array', 'assignees'])\n\n/** Default for an unfilled entry: `[]` for array kinds, `null` otherwise. */\nfunction defaultEntryValue(entryType: FieldEntry['type']): unknown {\n return ARRAY_FIELD_TYPES.has(entryType) ? [] : null\n}\n\n/**\n * Read a caller-supplied `input` 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 `initialFields`. 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 resolveInputValue({\n entry,\n initialFields,\n defaultValue,\n}: {\n entry: FieldEntry\n initialFields: InitialFieldValue[]\n defaultValue: unknown\n}): unknown {\n const initMatch = initialFields.find((s) => s.name === entry.name && s.type === entry.type)\n if (initMatch === undefined) return defaultValue\n assertInputValueShape(entry, initMatch.value)\n return initMatch.value\n}\n\nfunction resolveFieldReadValue({\n source,\n ctx,\n defaultValue,\n}: {\n source: Extract<FieldSource, {type: 'fieldRead'}>\n ctx: ResolveFieldContext\n defaultValue: unknown\n}): unknown {\n const entriesForScope =\n source.scope === 'workflow' ? (ctx.workflowFields ?? []) : (ctx.resolvedFields ?? [])\n const target = entriesForScope.find((s) => s.name === source.field)\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 * `$fields.<entry>.value.id` etc. must be bare too.\n *\n * `$fields` exposes field entries already resolved before this one (sequential\n * resolution). Cyclic references to later field entries produce `undefined` in\n * GROQ and the entry falls through to its default.\n */\nasync function resolveQueryValue({\n entry,\n source,\n ctx,\n client,\n defaultValue,\n}: {\n entry: FieldEntry\n source: Extract<FieldSource, {type: 'query'}>\n ctx: ResolveFieldContext\n client: WorkflowClient\n defaultValue: unknown\n}): Promise<unknown> {\n const params = paramsForLake({\n self: ctx.selfId ?? null,\n fields: fieldMapFromResolved(ctx.resolvedFields ?? []),\n stage: ctx.stageName ?? null,\n activity: ctx.activityName ?? 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 (\n normalizeQueryResult({\n entryType: entry.type,\n raw: result,\n workflowResource: ctx.workflowResource,\n }) ?? defaultValue\n )\n } catch (err) {\n rethrowWithContext(err, `Failed to resolve query entry \"${entry.name}\" (${entry.type})`)\n }\n}\n\nasync function resolveEntryValue({\n entry,\n initialFields,\n ctx,\n defaultValue,\n}: {\n entry: FieldEntry\n initialFields: InitialFieldValue[]\n ctx: ResolveFieldContext\n defaultValue: unknown\n}): Promise<unknown> {\n const source = entry.initialValue\n if (source === undefined) return defaultValue // working memory — ops fill it later\n if (source.type === 'input') return resolveInputValue({entry, initialFields, defaultValue})\n if (source.type === 'literal') return resolveLiteralValue({entry, source, ctx, defaultValue})\n if (source.type === 'fieldRead') return resolveFieldReadValue({source, ctx, defaultValue})\n if (source.type === 'query' && ctx.client !== undefined) {\n return resolveQueryValue({entry, source, ctx, client: ctx.client, defaultValue})\n }\n // \"query\" without a client falls back to the default.\n return defaultValue\n}\n\n/**\n * Materialise a literal seed. The authoring grammar admits bare document ids\n * in ref positions (`doc.ref` / `doc.refs` / `release.ref` entries and the\n * same kinds nested in `object` / `array` sub-shapes); the engine stores GDR\n * URIs, so each bare id is rooted at the workflow's home resource here.\n * `@<alias>:` refs were already expanded to GDR URIs at deploy, and GDR URIs\n * pass through; without a `workflowResource` a bare id passes through and\n * fails the shape validation loudly.\n */\nfunction resolveLiteralValue({\n entry,\n source,\n ctx,\n defaultValue,\n}: {\n entry: FieldEntry\n source: Extract<FieldSource, {type: 'literal'}>\n ctx: ResolveFieldContext\n defaultValue: unknown\n}): unknown {\n const value = source.value ?? defaultValue\n if (ctx.workflowResource === undefined) return value\n return rootSeedRefIds({\n entryType: entry.type,\n value,\n fields: entry.fields,\n of: entry.of,\n home: ctx.workflowResource,\n })\n}\n\nfunction rootSeedRefIds({\n entryType,\n value,\n fields,\n of,\n home,\n}: {\n entryType: string\n value: unknown\n fields?: readonly FieldShape[] | undefined\n of?: readonly FieldShape[] | undefined\n home: WorkflowResource\n}): unknown {\n if (value === null || value === undefined) return value\n if (entryType === 'doc.ref' || entryType === 'release.ref') return rootRefObject(value, home)\n if (entryType === 'doc.refs') {\n return Array.isArray(value) ? value.map((item) => rootRefObject(item, home)) : value\n }\n if (entryType === 'object') return rootSubfieldRefIds({row: value, shapes: fields ?? [], home})\n if (entryType === 'array') {\n return Array.isArray(value)\n ? value.map((row) => rootSubfieldRefIds({row, shapes: of ?? [], home}))\n : value\n }\n return value\n}\n\n/** Root exactly what the seed grammar calls a bare id; anything else (a GDR\n * URI, or junk that fails validation later) passes through untouched. */\nfunction rootRefObject(value: unknown, home: WorkflowResource): unknown {\n if (typeof value !== 'object' || value === null || !('id' in value)) return value\n const id = (value as {id: unknown}).id\n if (typeof id !== 'string' || !isBareSeedId(id)) return value\n return {...value, id: toPhysicalGdr(id, home)}\n}\n\nfunction rootSubfieldRefIds({\n row,\n shapes,\n home,\n}: {\n row: unknown\n shapes: readonly FieldShape[]\n home: WorkflowResource\n}): unknown {\n if (typeof row !== 'object' || row === null || Array.isArray(row)) return row\n const record = row as Record<string, unknown>\n const out = {...record}\n for (const shape of shapes) {\n if (!(shape.name in record)) continue\n out[shape.name] = rootSeedRefIds({\n entryType: shape.type,\n value: record[shape.name],\n fields: shape.fields,\n of: shape.of,\n home,\n })\n }\n return out\n}\n\n/**\n * Build the persisted entry envelope; `query`-sourced entries carry\n * `resolvedAt`, and `object` / `array` entries carry their declared sub-field\n * shape (`fields` / `of`) so the instance is self-describing for op-time\n * validation and rendering.\n */\nfunction buildResolvedEntry({\n entry,\n value,\n _key,\n now,\n}: {\n entry: FieldEntry\n value: unknown\n _key: string\n now: string\n}): ResolvedFieldEntry {\n return {\n _key,\n _type: entry.type,\n name: entry.name,\n ...(entry.title !== undefined ? {title: entry.title} : {}),\n ...(entry.description !== undefined ? {description: entry.description} : {}),\n value,\n ...(entry.initialValue?.type === 'query' ? {resolvedAt: now} : {}),\n ...(entry.type === 'object' ? {fields: entry.fields ?? []} : {}),\n ...(entry.type === 'array' ? {of: entry.of ?? []} : {}),\n } as ResolvedFieldEntry\n}\n\nasync function resolveOneEntry({\n entry,\n initialFields,\n ctx,\n randomKey,\n}: {\n entry: FieldEntry\n initialFields: InitialFieldValue[]\n ctx: ResolveFieldContext\n randomKey: () => string\n}): Promise<ResolvedFieldEntry> {\n const defaultValue = defaultEntryValue(entry.type)\n const value = await resolveEntryValue({entry, initialFields, ctx, defaultValue})\n\n // A query result is lake data resolved at runtime — fail SOFT: if it doesn't\n // fit the declared kind, discard it (fall to the default) and record the\n // discard, rather than aborting materialisation over external data.\n if (entry.initialValue?.type === 'query') {\n const issues = checkFieldValue({\n entryType: entry.type,\n value,\n fields: entry.fields,\n of: entry.of,\n })\n if (issues !== undefined) {\n ctx.recordDiscard?.({field: entry.name, detail: issues.join('; ')})\n return buildResolvedEntry({entry, value: defaultValue, _key: randomKey(), now: ctx.now})\n }\n return buildResolvedEntry({entry, value, _key: randomKey(), now: ctx.now})\n }\n\n // input / literal / fieldRead / working-memory: a shape mismatch is an\n // authoring or caller bug — fail HARD before it leaks into the snapshot.\n validateFieldValue({\n entryType: entry.type,\n entryName: entry.name,\n value,\n fields: entry.fields,\n of: entry.of,\n })\n return buildResolvedEntry({entry, value, _key: randomKey(), now: ctx.now})\n}\n\n/** Project resolved field entries into the `$fields` shape (entryName → entry envelope). */\nfunction fieldMapFromResolved(entries: ResolvedFieldEntry[]): 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 `initialFields` values for shape correctness\n * BEFORE they hit the persisted instance. Input-sourced doc.ref /\n * doc.refs field 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 assertInputValueShape(entry: FieldEntry, value: unknown): void {\n if (entry.type === 'doc.ref') {\n assertGdrShape(value, `field entry \"${entry.name}\" (doc.ref)`)\n return\n }\n if (entry.type === 'release.ref') {\n assertGdrShape(value, `field 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 ContractViolationError(\n `Invalid input value for field 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 ContractViolationError(\n `Invalid input value for field 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, `field 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 ContractViolationError(\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 ContractViolationError(\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 ContractViolationError(\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 == $fields.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,\n raw,\n workflowResource,\n}: {\n entryType: FieldEntry['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/**\n * Coerce an already-GDR-shaped `{id, type}` value. A known-scheme URI\n * passes through; otherwise the id is bare and {@link toPhysicalGdr} roots it\n * at the workflow resource. Returns null when the shape doesn't match so\n * 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: toPhysicalGdr(r.id, workflowResource), 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: toPhysicalGdr(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 a doc id in the workflow resource.\n if (typeof raw === 'string' && workflowResource) {\n return {id: toPhysicalGdr(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, scopedFieldOverlay} from '../core/params.ts'\nimport type {ParsedGdr} from '../core/refs.ts'\nimport type {HydratedSnapshot, LoadedDoc} from '../core/snapshot.ts'\nimport type {Activity, Stage, WorkflowDefinition} from '../define/schema.ts'\nimport {type RecordFieldDiscard, resolveDeclaredFields} from '../field-resolution.ts'\nimport {randomKey} from '../keys.ts'\nimport {hydrateSnapshot} from '../snapshot.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport {InstanceNotFoundError} from '../types/errors.ts'\nimport type {InitialFieldValue, ResolvedFieldEntry} from '../types/field-values.ts'\nimport type {StageName} from '../types/ids.ts'\nimport {parseDefinitionSnapshot, type WorkflowInstance} from '../types/instance.ts'\nimport {\n CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS,\n type EngineCallOptions,\n isRevisionConflict,\n} from './results.ts'\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 `editField` retry loops reload through, so\n * the two can't drift in how they wire the clock/router.\n */\nexport function loadCallContext({\n client,\n instanceId,\n options,\n}: {\n client: WorkflowClient\n instanceId: string\n options: {clock?: Clock; clientForGdr?: (parsed: ParsedGdr) => WorkflowClient} | undefined\n}): Promise<EngineContext> {\n return loadContext({\n client,\n instanceId,\n options: {\n ...(options?.clock ? {clock: options.clock} : {}),\n ...(options?.clientForGdr ? {clientForGdr: options.clientForGdr} : {}),\n },\n })\n}\n\n/**\n * Run `commit` under optimistic-locking retry: reload a fresh {@link EngineContext}\n * (new `_rev`), commit through `persist`'s `ifRevisionId` guard, and on a lost\n * race reload + re-commit across {@link CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS}\n * attempts before throwing `onExhausted()`. A non-conflict error throws\n * immediately. The shared retry shell for the `fireAction` and `editField`\n * verbs, so the two can't drift in how they reload-and-retry. Reloading also\n * re-gates each attempt: a retry whose target the winning writer already\n * advanced fails with the normal gate error rather than retrying forever.\n */\nexport async function retryOnRevisionConflict<T>(args: {\n client: WorkflowClient\n instanceId: string\n options: EngineCallOptions | undefined\n commit: (ctx: EngineContext) => Promise<T>\n onExhausted: () => Error\n}): Promise<T> {\n const {client, instanceId, options, commit, onExhausted} = 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 commit(ctx)\n } catch (error) {\n if (!isRevisionConflict(error)) throw error\n // Lost the optimistic-locking race — reload and retry.\n }\n }\n throw onExhausted()\n}\n\nexport async function loadContext({\n client,\n instanceId,\n options,\n}: {\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 InstanceNotFoundError({instanceId})\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 activity name selects the lexical\n * `$fields` overlay and the `$subworkflows` rows, `vars` carries anything the\n * shell pre-computed (`$can`, `$row`, `$subworkflows`).\n */\nexport interface ConditionScopeOptions {\n activityName?: 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 `$fields` overlay for the activity 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 fields = {\n ...(base.fields as Record<string, unknown>),\n ...scopedFieldOverlay({\n instance: ctx.instance,\n snapshot: ctx.snapshot,\n activityName: opts?.activityName,\n }),\n }\n const params: Record<string, unknown> = {\n ...base,\n fields,\n actor: opts?.actor,\n assigned:\n opts?.activityName !== undefined\n ? assignedFor({\n instance: ctx.instance,\n activityName: opts.activityName,\n actor: opts?.actor,\n roleAliases: ctx.definition.roleAliases,\n })\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,\n condition,\n opts,\n}: {\n ctx: EngineContext\n condition: string | undefined\n opts?: ConditionScopeOptions | undefined\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` (`activity.filter`, transition\n * routing) read the outcome form and branch on `unevaluable`. */\nexport async function ctxEvaluateCondition({\n ctx,\n condition,\n opts,\n}: {\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 fields[] from the stage definition + an\n * optional `initialFields` (e.g. supplied to `setStage`). Bound to the\n * instance's subject and to `$stage = stage.name`.\n */\nexport async function resolveStageFieldEntries(args: {\n client: WorkflowClient\n instance: WorkflowInstance\n stage: Stage\n now: string\n initialFields?: InitialFieldValue[]\n recordDiscard?: RecordFieldDiscard\n}): Promise<ResolvedFieldEntry[]> {\n const {client, instance, stage, now, initialFields, recordDiscard} = args\n return resolveDeclaredFields({\n entryDefs: stage.fields,\n initialFields: initialFields ?? [],\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' `initialValue: { type: \"fieldRead\", scope:\n // \"workflow\", ... }` to see the already-resolved workflow-scope fields.\n workflowFields: instance.fields ?? [],\n ...(instance.perspective !== undefined ? {perspective: instance.perspective} : {}),\n ...(recordDiscard !== undefined ? {recordDiscard} : {}),\n },\n randomKey,\n })\n}\n\n/** Same shape as `resolveStageFieldEntries` but scoped to an activity. */\nexport async function resolveActivityFieldEntries(args: {\n client: WorkflowClient\n instance: WorkflowInstance\n stage: Stage\n activity: Activity\n now: string\n recordDiscard?: RecordFieldDiscard\n}): Promise<ResolvedFieldEntry[]> {\n const {client, instance, stage, activity, now, recordDiscard} = args\n return resolveDeclaredFields({\n entryDefs: activity.fields,\n initialFields: [],\n ctx: {\n client,\n now,\n selfId: instance._id,\n tag: instance.tag,\n stageName: stage.name,\n workflowResource: instance.workflowResource,\n activityName: activity.name,\n workflowFields: instance.fields ?? [],\n ...(instance.perspective !== undefined ? {perspective: instance.perspective} : {}),\n ...(recordDiscard !== undefined ? {recordDiscard} : {}),\n },\n randomKey,\n })\n}\n","/**\n * Pure effect-binding resolution.\n *\n * An effect's `bindings` is a `Record<string, groq>` — GROQ reads over the\n * same rendered scope conditions use (`$fields`, `$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, params: args.params, snapshot: args.snapshot})\n }\n return {...resolved, ...args.staticInput}\n}\n","import type {GlobalDocumentReference, WorkflowResource} from './core/refs.ts'\nimport type {WorkflowDefinition} from './define/schema.ts'\nimport {randomKey} from './keys.ts'\nimport type {Actor} from './types/actor.ts'\nimport type {WorkflowClient, WorkflowPerspective} from './types/client.ts'\nimport type {EffectsContextEntry} from './types/effects.ts'\nimport {InstanceNotFoundError} from './types/errors.ts'\nimport type {ResolvedFieldEntry} from './types/field-values.ts'\nimport type {HistoryEntry} from './types/history.ts'\nimport {WORKFLOW_INSTANCE_TYPE, type WorkflowInstance} from './types/instance.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,\n instanceId,\n tag,\n}: {\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 InstanceNotFoundError({instanceId})\n }\n\n if (doc.tag !== tag) {\n throw new InstanceNotFoundError({\n instanceId,\n detail: 'not visible to this engine: tag mismatch',\n })\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 fields + 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 pinnedContentHash: string | undefined\n definition: WorkflowDefinition\n fields: ResolvedFieldEntry[]\n effectsContext: EffectsContextEntry[]\n ancestors: GlobalDocumentReference[]\n perspective: WorkflowPerspective | undefined\n initialStage: string\n actor: Actor | undefined\n /** Audit rows produced while resolving the seed fields (e.g. discarded\n * query results), appended after the opening `stageEntered`. */\n extraHistory?: HistoryEntry[]\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 ...(args.pinnedContentHash !== undefined ? {pinnedContentHash: args.pinnedContentHash} : {}),\n definitionSnapshot: JSON.stringify(args.definition),\n fields: args.fields,\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 ...(args.extraHistory ?? []),\n ],\n startedAt: now,\n lastChangedAt: now,\n }\n}\n","import type {SanityDocument} from '@sanity/types'\n\nimport type {Stage, Activity} 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 {ContractViolationError} from '../types/errors.ts'\nimport type {ResolvedFieldEntry} from '../types/field-values.ts'\nimport type {HistoryEntry} from '../types/history.ts'\nimport type {StageName, ActivityName} from '../types/ids.ts'\nimport {findOpenStageEntry, type StageEntry, type ActivityEntry} from '../types/instance-state.ts'\nimport type {WorkflowInstance} from '../types/instance.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 fields: ResolvedFieldEntry[]\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 field entry arrays need their own copies\n // so ops can mutate without leaking into the source.\n fields: (instance.fields ?? []).map((s) => ({...s})),\n stages: instance.stages.map((s) => ({\n ...s,\n fields: (s.fields ?? []).map((entry) => ({...entry})),\n activities: s.activities.map((t) => ({\n ...t,\n ...(t.fields !== undefined ? {fields: t.fields.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 | 'fields'\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 fields: src.fields,\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 fields: mutation.fields,\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 `activateActivity`'s in-memory `checkSpawnCompletion` flipped the\n // parent's activity 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({\n client: ctx.client,\n instanceId: body._id,\n actor: actorForPriming,\n clientForGdr: ctx.clientForGdr,\n clock: ctx.clock,\n })\n await cascadeAutoTransitions({\n client: ctx.client,\n instanceId: body._id,\n actor: actorForPriming,\n clientForGdr: ctx.clientForGdr,\n clock: ctx.clock,\n })\n await propagateToAncestors({\n client: ctx.client,\n instanceId: body._id,\n actor: actorForPriming,\n clientForGdr: ctx.clientForGdr,\n clock: ctx.clock,\n })\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 activity 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 currentActivities(mutation: MutableInstance): ActivityEntry[] {\n return currentStageEntry(mutation).activities\n}\n\n/** Find an activity definition on the instance's current stage, throwing a\n * consistent error when it isn't declared there. */\nexport function findActivityInCurrentStage(\n ctx: EngineContext,\n activityName: ActivityName,\n): {stage: Stage; activity: Activity} {\n const stage = findStage(ctx.definition, ctx.instance.currentStage)\n const activity = (stage.activities ?? []).find((t) => t.name === activityName)\n if (activity === undefined) {\n throw new ContractViolationError(\n `Activity \"${activityName}\" not found in current stage \"${stage.name}\" of ${ctx.definition.name}`,\n )\n }\n return {stage, activity}\n}\n\n/** The mutation copy's entry for `activity`. Throws if it vanished — the\n * live instance and its mutation copy must agree on activity identity. */\nexport function requireMutationActivityEntry(\n mutation: MutableInstance,\n activity: ActivityName,\n): ActivityEntry {\n const mutEntry = currentActivities(mutation).find((t) => t.name === activity)\n if (mutEntry === undefined) {\n throw new Error(`Activity \"${activity}\" 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 findCurrentActivities(instance: WorkflowInstance): ActivityEntry[] {\n return findCurrentStageEntry(instance)?.activities ?? []\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 guards). 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 * 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 guards. 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,\n mutation,\n deploy,\n}: {\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 * {@link persistThenDeploy} specialised to the ops/effect-completion policy:\n * refresh the stage's guards iff this commit changed state a guard reads,\n * else skip the redeploy. The single home for that refresh-or-skip decision so\n * the action, edit, and effect-completion paths can't drift on it; a failed\n * refresh still rolls the commit back (via {@link persistThenDeploy}).\n */\nexport async function persistThenMaybeRefresh({\n ctx,\n mutation,\n stageName,\n didChangeState,\n}: {\n ctx: EngineContext\n mutation: MutableInstance\n stageName: StageName\n didChangeState: boolean\n}): Promise<void> {\n await persistThenDeploy({\n ctx,\n mutation,\n deploy: () =>\n didChangeState ? refreshStageGuards({ctx, mutation, stageName}) : Promise.resolve(),\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 */\nasync function refreshStageGuards({\n ctx,\n mutation,\n stageName,\n}: {\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 {selfGdr, type GlobalDocumentReference} from '../core/refs.ts'\nimport type {Effect, FieldOp} 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 {EffectNotFoundError} from '../types/errors.ts'\nimport type {HistoryEntry} from '../types/history.ts'\nimport {findOpenStageEntry} from '../types/instance-state.ts'\nimport {ctxConditionParams, type EngineContext, loadCallContext} from './context.ts'\nimport {materializeInstance, type MutableInstance, startMutation} from './mutation.ts'\nimport {isFieldOp, runOps, validateEffectOps} from './ops.ts'\nimport {persistThenMaybeRefresh} from './persist-deploy.ts'\nimport {EffectOpsInvalidError} from './results.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. When the\n * handler returns `ops`, they are validated and applied in this same commit —\n * the state half of an effect, run through the shared op applier (target\n * resolution + value-kind validation), exactly like an action's ops.\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 ops?: FieldOp[]\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, ops, detail, error, durationMs, options} =\n args\n const ctx = await loadCallContext({client, instanceId, options})\n return commitCompleteEffect({\n ctx,\n effectKey,\n status,\n outputs,\n ops,\n detail,\n error,\n durationMs,\n actor: 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 ...(pending.stageEntryKey !== undefined ? {stageEntryKey: pending.stageEntryKey} : {}),\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,\n effectName,\n outputs,\n}: {\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,\n effectKey,\n status,\n outputs,\n ops,\n detail,\n error,\n durationMs,\n actor,\n}: {\n ctx: EngineContext\n effectKey: string\n status: 'done' | 'failed'\n outputs: Record<string, string | number | boolean | GlobalDocumentReference> | undefined\n ops: FieldOp[] | 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 EffectNotFoundError({instanceId: ctx.instance._id, effectKey})\n }\n // A failed effect carries no ops: the drainer only forwards a handler's ops on\n // success (a throw is failure and returns nothing), and a failed *outcome* is\n // reported by `field.set`ting it on a `done` completion (a gate then branches\n // on the field). Reject the contradictory combination rather than mutating\n // state on a failed completion.\n if (status === 'failed' && ops !== undefined && ops.length > 0) {\n throw new EffectOpsInvalidError({\n effect: pending.name,\n issues: [\n 'ops cannot accompany a failed completion — field.set the outcome on a done completion instead',\n ],\n })\n }\n // External data — validate before any mutation so a malformed op aborts the\n // completion rather than crashing mid-commit (mirrors action-op parsing,\n // which happens at deploy).\n const validatedOps = ops !== undefined ? validateEffectOps(ops, pending.name) : []\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, effectName: 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 // The state half of the effect: run the returned ops through the shared\n // applier in this same commit, attributed to the completing actor. Targets\n // resolve against the CURRENT open stage (the instance may have advanced\n // since the effect queued); an unresolvable target fails loud, as for any op.\n const ranOps = await runOps({\n ops: validatedOps,\n mutation,\n stage: ctx.instance.currentStage,\n origin: {effect: pending.name},\n params: pending.params,\n actor,\n self: selfGdr(ctx.instance),\n now: ranAt,\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\n // back. A field op the handler returned can invalidate a guard just as\n // `outputs` can, so either triggers the refresh.\n const needsGuardRefresh = wroteEffectsContext || ranOps.some(isFieldOp)\n await persistThenMaybeRefresh({\n ctx,\n mutation,\n stageName: ctx.instance.currentStage,\n didChangeState: needsGuardRefresh,\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,\n origin,\n params,\n actor,\n now,\n stageEntryKey,\n}: {\n effect: Effect\n origin: EffectOrigin\n params: Record<string, unknown>\n actor: Actor | undefined\n now: string\n stageEntryKey: string | undefined\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 ...(stageEntryKey !== undefined ? {stageEntryKey} : {}),\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 *\n * Each entry is stamped with the `_key` of the stage entry it belongs to —\n * the open entry at queue time by default. A transition queues its effects\n * BEFORE the next stage entry exists, so that call site passes the\n * pre-minted key of the entry being entered via `opts.stageEntryKey`.\n */\nexport async function queueEffects({\n ctx,\n mutation,\n effects,\n origin,\n actor,\n opts,\n}: {\n ctx: EngineContext\n mutation: MutableInstance\n effects: Effect[] | undefined\n origin: EffectOrigin\n actor: Actor | undefined\n opts?: {\n callerParams?: Record<string, unknown>\n activityName?: string\n stageEntryKey?: string\n }\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 stageEntryKey = opts?.stageEntryKey ?? findOpenStageEntry(liveCtx.instance)?._key\n const params = await ctxConditionParams(liveCtx, {\n ...(opts?.activityName !== undefined ? {activityName: opts.activityName} : {}),\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({\n effect,\n origin,\n params: resolved,\n actor,\n now,\n stageEntryKey,\n })\n mutation.pendingEffects.push(pending)\n mutation.history.push(history)\n }\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 {type ParsedGdr, tryParseGdr} 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,\n clientForGdr,\n subjectGdrUri,\n}: {\n defaultClient: WorkflowClient\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient\n subjectGdrUri: string | undefined\n}): WorkflowClient {\n if (subjectGdrUri === undefined) return defaultClient\n const parsed = tryParseGdr(subjectGdrUri)\n return parsed !== undefined ? clientForGdr(parsed) : defaultClient\n}\n","/**\n * The engine's own system-actor identity — the audit trail's answer to \"who\n * did this?\" when no human or external caller did, but the engine itself\n * (a resolution gate, a machine step, an effect drain).\n *\n * One definition of the `engine.`-prefixed id convention, shared by every\n * producer that stamps such an actor and by {@link driverKind}, which reads\n * the prefix back to classify a system actor as the engine rather than an\n * external service. Tying both sides to this module keeps the convention from\n * drifting into bare string literals.\n */\n\nimport type {Actor} from '../types/actor.ts'\n\nconst ENGINE_ACTOR_ID_PREFIX = 'engine.'\n\n/** A `system` actor owned by the engine, named by the housekeeping step that\n * stamped it (e.g. `engineSystemActor('machineStep')` → `engine.machineStep`). */\nexport function engineSystemActor(name: string): Actor {\n return {kind: 'system', id: `${ENGINE_ACTOR_ID_PREFIX}${name}`}\n}\n\n/** Whether an actor is the engine itself, as opposed to a human, an agent, or\n * an external service driving the engine with its own `system` actor. */\nexport function isEngineActor(actor: Actor): boolean {\n return actor.kind === 'system' && actor.id.startsWith(ENGINE_ACTOR_ID_PREFIX)\n}\n","import {evaluate, parse} from 'groq-js'\n\nimport type {DeployedDefinition} from '../api/deploy.ts'\nimport {runGroq} from '../core/eval.ts'\nimport {buildParams} from '../core/params.ts'\nimport {\n gdrFromResource,\n isGdrUri,\n resourceFromGdrUri,\n sameResource,\n selfGdr,\n toBareId,\n type GlobalDocumentReference,\n type WorkflowResource,\n} from '../core/refs.ts'\nimport type {Subworkflows, Activity, WorkflowDefinition} from '../define/schema.ts'\nimport {definitionLookupGroq} from '../definition-query.ts'\nimport {clientForDiscovery, discoverItems} from '../discover.ts'\nimport {derivePerspectiveFromFields, resolveDeclaredFields} from '../field-resolution.ts'\nimport {buildInstanceBase, effectsContextEntry} from '../instance.ts'\nimport {instanceDocId, randomKey} from '../keys.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 type {InitialFieldValue, FieldKind} from '../types/field-values.ts'\nimport type {HistoryEntry} from '../types/history.ts'\nimport type {StageName} from '../types/ids.ts'\nimport type {ActivityEntry} from '../types/instance-state.ts'\nimport {WORKFLOW_INSTANCE_TYPE, type WorkflowInstance} from '../types/instance.ts'\nimport {ctxConditionParams, ctxEvaluateCondition, type EngineContext} from './context.ts'\nimport {applyActivityStatusChange, recordFieldDiscards} from './history-entries.ts'\nimport type {MutableInstance} from './mutation.ts'\nimport {engineSystemActor} from './system-actor.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` activity 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/** The engine system actor that owns a gate-driven activity flip — the audit\n * trail's answer to \"who resolved this?\" when no human did. */\nfunction gateActor(outcome: GateOutcome): Actor {\n return engineSystemActor(outcome === 'failed' ? 'failWhen' : 'completeWhen')\n}\n\n/** The status a satisfied resolution gate resolves an activity into. */\nexport type GateOutcome = 'done' | 'failed'\n\n/**\n * Resolve an activity into a satisfied gate's {@link GateOutcome}, attributed\n * to the gate's system actor ({@link gateActor}) rather than any human. The\n * single home for the \"a resolution gate fired → flip the activity, stamped as\n * the gate\" idiom — every gate-driven flip (the auto-resolve sweep, on-activate\n * resolution, ancestor propagation) routes here so the actor attribution can't\n * drift across paths.\n */\nexport function applyGateOutcome(args: {\n entry: ActivityEntry\n history: HistoryEntry[]\n stage: StageName\n /** The operation's clock reading (the caller's `ctx.now`). */\n at: string\n outcome: GateOutcome\n}): void {\n applyActivityStatusChange({\n entry: args.entry,\n history: args.history,\n stage: args.stage,\n to: args.outcome,\n at: args.at,\n actor: gateActor(args.outcome),\n })\n}\n\n/**\n * The activity's effective completion gate — explicit `completeWhen`, or the\n * implicit {@link SUBWORKFLOWS_ALL_DONE} default on a spawning activity (the\n * dominant case costs zero syntax, and a zero-row fan-out resolves\n * vacuously instead of hanging).\n */\nexport function effectiveCompleteWhen(activity: Activity): string | undefined {\n return (\n activity.completeWhen ??\n (activity.subworkflows !== undefined ? SUBWORKFLOWS_ALL_DONE : undefined)\n )\n}\n\n/**\n * Evaluate an activity's resolution gate over the activity-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,\n activity,\n vars,\n}: {\n ctx: EngineContext\n activity: Activity\n vars: Record<string, unknown>\n}): Promise<GateOutcome | undefined> {\n const scope = {activityName: activity.name, vars}\n if (\n activity.failWhen !== undefined &&\n (await ctxEvaluateCondition({ctx, condition: activity.failWhen, opts: scope}))\n ) {\n return 'failed'\n }\n const completeWhen = effectiveCompleteWhen(activity)\n if (\n completeWhen !== undefined &&\n (await ctxEvaluateCondition({ctx, condition: completeWhen, opts: scope}))\n ) {\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,\n mutation,\n activity,\n sub,\n actor,\n}: {\n ctx: EngineContext\n mutation: MutableInstance\n activity: Activity\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 activity \"${activity.name}\" of ${ctx.instance._id}. ` +\n `Ancestor chain: ${chain}`,\n )\n }\n\n const now = ctx.now\n const definition = await resolveDefinitionRef({\n client: ctx.client,\n ref: sub.definition,\n tag: ctx.instance.tag,\n })\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}, activity ${activity.name})`,\n )\n }\n\n const parentScope = await ctxConditionParams(ctx, {\n activityName: activity.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 initialFields = await projectRowFields({\n ctx,\n sub,\n childDefinition: 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 initialFields,\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 projectRowFields} 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.fields)[0]?.id\n const client = clientForDiscovery({\n defaultClient: ctx.client,\n clientForGdr: ctx.clientForGdr,\n subjectGdrUri: routingUri,\n })\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 * `initialFields`. The CHILD's field declarations dictate each entry's kind:\n * `with` supplies values for the child's `input`-sourced entries by name;\n * naming an entry the child doesn't declare fails loud.\n */\nasync function projectRowFields({\n ctx,\n sub,\n childDefinition,\n parentScope,\n row,\n discoveryResource,\n}: {\n ctx: EngineContext\n sub: Subworkflows\n childDefinition: WorkflowDefinition\n parentScope: Record<string, unknown>\n row: unknown\n discoveryResource: WorkflowResource | undefined\n}): Promise<InitialFieldValue[]> {\n const out: InitialFieldValue[] = []\n for (const [name, groq] of Object.entries(sub.with ?? {})) {\n const declared = (childDefinition.fields ?? []).find((e) => e.name === name)\n if (declared === undefined) {\n throw new Error(\n `subworkflows.with[\"${name}\"]: subworkflow \"${childDefinition.name}\" declares no field entry \"${name}\"`,\n )\n }\n const raw = await runGroq({groq, params: {...parentScope, row}, snapshot: ctx.snapshot})\n const value = canonicaliseSpawnValue({\n kind: declared.type,\n value: raw,\n cx: {\n parentResource: ctx.instance.workflowResource,\n discoveryResource,\n entryName: name,\n childName: childDefinition.name,\n },\n })\n if (value === null || value === undefined) continue\n out.push({\n type: declared.type as InitialFieldValue['type'],\n name,\n value: value as InitialFieldValue['value'],\n } as InitialFieldValue)\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,\n sub,\n parentScope,\n}: {\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, params: parentScope, snapshot: 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({\n kind,\n value,\n cx,\n}: {\n kind: FieldKind\n value: unknown\n cx: SpawnRefContext\n}): 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 // A canonical URI passes through (a projected `@<alias>:` was already\n // expanded to one at deploy). A bare id roots at the parent resource — but\n // under foreign discovery that's a mis-route, so 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,\n ref,\n tag,\n}: {\n client: WorkflowClient\n ref: {name: string; version?: number | 'latest' | undefined}\n tag: string\n}): Promise<DeployedDefinition | 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<DeployedDefinition | 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: DeployedDefinition\n initialFields: InitialFieldValue[]\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, initialFields, 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 // `childDocId` is the bare `_id`; its GDR URI form (`childUri`) is what the\n // parent's `activityEntry.spawnedInstances[]` and the child's own\n // `ancestors[]` reference.\n const childDocId = instanceDocId(childTag)\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 fields declarations against the\n // projected `initialFields`. The child's own fields[] declarations dictate\n // which entry names/kinds exist; the projection just fills the\n // `input`-sourced ones. Query and working-memory entries resolve per their\n // own `initialValue`.\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 // A child's workflow-scope query-sourced fields can have their lake result\n // discarded; those rows seed the child instance's history below.\n const fieldDiscards: HistoryEntry[] = []\n const childFields = await resolveDeclaredFields({\n entryDefs: definition.fields,\n initialFields,\n ctx: {\n client,\n now,\n selfId: childDocId,\n tag: childTag,\n workflowResource,\n definitionName: definition.name,\n ...(inheritedPerspective !== undefined ? {perspective: inheritedPerspective} : {}),\n recordDiscard: recordFieldDiscards({target: fieldDiscards, scope: 'workflow', at: now}),\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 = derivePerspectiveFromFields(childFields) ?? 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 pinnedContentHash: definition.contentHash,\n definition,\n fields: childFields,\n effectsContext: effectsContextEntries,\n ancestors,\n perspective: childPerspective,\n initialStage: definition.initialStage,\n actor,\n ...(fieldDiscards.length > 0 ? {extraHistory: fieldDiscards} : {}),\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 an activity'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) => toBareId(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","import type {ConditionOutcome} from '../core/eval.ts'\nimport {selfGdr} from '../core/refs.ts'\nimport type {Stage, Activity} 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 {ActivityName} from '../types/ids.ts'\nimport type {ActivityEntry} from '../types/instance-state.ts'\nimport {\n ctxEvaluateConditionOutcome,\n type EngineContext,\n findStage,\n loadCallContext,\n resolveActivityFieldEntries,\n} from './context.ts'\nimport {queueEffects} from './effects.ts'\nimport {applyActivityStatusChange, recordFieldDiscards} from './history-entries.ts'\nimport {\n findCurrentActivities,\n findActivityInCurrentStage,\n type MutableInstance,\n persist,\n requireMutationActivityEntry,\n startMutation,\n} from './mutation.ts'\nimport {runOps} from './ops.ts'\nimport type {EngineCallOptions, InvokeResult} from './results.ts'\nimport {\n applyGateOutcome,\n effectiveCompleteWhen,\n evaluateResolutionGate,\n spawnSubworkflows,\n subworkflowRows,\n} from './spawn.ts'\nimport {engineSystemActor} from './system-actor.ts'\n\n/**\n * Manually activate a `pending` activity — the explicit path for\n * `activation: \"manual\"` activities (the default: an activity never activates\n * silently). No-op if the activity is already active or done.\n */\nexport async function invokeActivity(args: {\n client: WorkflowClient\n instanceId: string\n activity: ActivityName\n options?: EngineCallOptions\n}): Promise<InvokeResult> {\n const {client, instanceId, activity: activityName, options} = args\n const ctx = await loadCallContext({client, instanceId, options})\n return commitInvoke({ctx, activityName, actor: options?.actor})\n}\n\nasync function commitInvoke({\n ctx,\n activityName,\n actor,\n}: {\n ctx: EngineContext\n activityName: ActivityName\n actor: Actor | undefined\n}): Promise<InvokeResult> {\n const {activity} = findActivityInCurrentStage(ctx, activityName)\n const entry = findCurrentActivities(ctx.instance).find((t) => t.name === activityName)\n if (entry === undefined) {\n throw new Error(\n `Activity \"${activityName}\" has no status entry on instance ${ctx.instance._id}`,\n )\n }\n if (entry.status !== 'pending') {\n return {invoked: false, activity: activityName}\n }\n\n const mutation = startMutation(ctx.instance)\n const mutEntry = requireMutationActivityEntry(mutation, activityName)\n await activateActivity({ctx, mutation, activity, entry: mutEntry, actor})\n await persist(ctx, mutation)\n return {invoked: true, activity: activityName}\n}\n\n/**\n * Activation — the activity's lifecycle moment. The full payload runs here:\n * activity-scoped fields resolves, the activity'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 * activity-context scope (including `$subworkflows`), and the MACHINE-STEP rule\n * closes the loop — an activity 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 activateActivity({\n ctx,\n mutation,\n activity,\n entry,\n actor,\n}: {\n ctx: EngineContext\n mutation: MutableInstance\n activity: Activity\n entry: ActivityEntry\n actor: Actor | undefined\n}): Promise<void> {\n // One clock reading for the whole activation so startedAt, any\n // auto-resolve flip, activityActivated, and spawn stamps agree on the time.\n const now = ctx.now\n entry.status = 'active'\n entry.startedAt = now\n if (activity.fields !== undefined && activity.fields.length > 0) {\n const stage = findStage(ctx.definition, mutation.currentStage)\n entry.fields = await resolveActivityFieldEntries({\n client: ctx.client,\n instance: ctx.instance,\n stage,\n activity,\n now,\n recordDiscard: recordFieldDiscards({target: mutation.history, scope: 'activity', at: now}),\n })\n }\n\n await runOps({\n ops: activity.ops,\n mutation,\n stage: mutation.currentStage,\n origin: {activity: activity.name},\n params: {},\n actor,\n self: selfGdr(ctx.instance),\n now,\n })\n\n mutation.history.push({\n _key: randomKey(),\n _type: 'activityActivated',\n at: now,\n stage: mutation.currentStage,\n activity: activity.name,\n ...(actor !== undefined ? {actor} : {}),\n })\n\n await queueEffects({\n ctx,\n mutation,\n effects: activity.effects,\n origin: {kind: 'activity', name: activity.name},\n actor,\n opts: {\n activityName: activity.name,\n },\n })\n\n let pendingChildren: {_id: string; stage: string; status: 'active'}[] | undefined\n if (activity.subworkflows !== undefined) {\n const createsBefore = mutation.pendingCreates.length\n const refs = await spawnSubworkflows({\n ctx,\n mutation,\n activity,\n sub: activity.subworkflows,\n actor,\n })\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 activity: activity.name,\n instanceRef: ref,\n })\n }\n }\n\n if (\n await autoResolveOnActivate({\n ctx,\n mutation,\n activity,\n entry,\n now,\n ...(pendingChildren !== undefined ? {pendingChildren} : {}),\n })\n )\n return\n resolveMachineStep({mutation, activity, entry, now})\n}\n\n/**\n * Run the activity's resolution gate ({@link evaluateResolutionGate}) at\n * activation, immediately resolving the activity with the gate's system actor\n * when it fires. Returns true when the activity resolved so the caller skips\n * the machine-step check.\n */\nasync function autoResolveOnActivate({\n ctx,\n mutation,\n activity,\n entry,\n now,\n pendingChildren,\n}: {\n ctx: EngineContext\n mutation: MutableInstance\n activity: Activity\n entry: ActivityEntry\n now: string\n pendingChildren?: {_id: string; stage: string; status: 'active'}[]\n}): Promise<boolean> {\n if (activity.failWhen === undefined && effectiveCompleteWhen(activity) === undefined) return false\n const vars =\n pendingChildren !== undefined\n ? {subworkflows: pendingChildren}\n : await activityConditionVars(ctx, entry)\n const outcome = await evaluateResolutionGate({ctx, activity, vars})\n if (outcome === undefined) return false\n applyGateOutcome({\n entry,\n history: mutation.history,\n stage: mutation.currentStage,\n at: now,\n outcome,\n })\n return true\n}\n\n/**\n * The `$subworkflows` rows for an activity's conditions — hydrated from the\n * spawned instances so `count($subworkflows[status == 'done'])` works.\n */\nexport async function activityConditionVars(\n ctx: EngineContext,\n entry: ActivityEntry,\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 * An activity 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 activity list where a container hook would have fired\n * invisibly. (A `subworkflows` activity without `completeWhen` is NOT a machine\n * step: the default all-done gate applies via the cascade.)\n */\nfunction resolveMachineStep({\n mutation,\n activity,\n entry,\n now,\n}: {\n mutation: MutableInstance\n activity: Activity\n entry: ActivityEntry\n now: string\n}): void {\n const waitsForActor = activity.actions !== undefined && activity.actions.length > 0\n const waitsForCondition =\n activity.completeWhen !== undefined || activity.subworkflows !== undefined\n if (waitsForActor || waitsForCondition) return\n applyActivityStatusChange({\n entry,\n history: mutation.history,\n stage: mutation.currentStage,\n to: 'done',\n at: now,\n actor: engineSystemActor('machineStep'),\n })\n}\n\n/**\n * Build the stage's activity entries at enter: an activity whose `filter` is a definite\n * `false` against the stage's entry fields is `skipped` (conditional enter —\n * different activities 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 activity 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 ActivityEntry.filterEvaluation} so the\n * audit trail tells \"genuinely below threshold\" apart from \"couldn't read it\".\n */\nexport async function buildStageActivities(\n ctx: EngineContext,\n stage: Stage,\n): Promise<ActivityEntry[]> {\n const entries: ActivityEntry[] = []\n for (const activity of stage.activities ?? []) {\n const outcome = await ctxEvaluateConditionOutcome({\n ctx,\n condition: activity.filter,\n opts: {activityName: activity.name},\n })\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: activity.name,\n status: inScope ? 'pending' : 'skipped',\n ...(activity.filter !== undefined\n ? {filterEvaluation: buildFilterEvaluation({at: ctx.now, filter: activity.filter, outcome})}\n : {}),\n })\n }\n return entries\n}\n\n/**\n * The audit record for an activity'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* an\n * activity that \"should\" have skipped is sitting in scope.\n */\nfunction buildFilterEvaluation({\n at,\n filter,\n outcome,\n}: {\n at: string\n filter: string\n outcome: ConditionOutcome\n}): NonNullable<ActivityEntry['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). Activity 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 {activateActivity, buildStageActivities} from './activities.ts'\nimport {\n ctxEvaluateConditionOutcome,\n type EngineContext,\n findStage,\n loadCallContext,\n resolveStageFieldEntries,\n} from './context.ts'\nimport {queueEffects} from './effects.ts'\nimport {recordFieldDiscards, 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'\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\"` activities, 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 loadCallContext({client, instanceId, options})\n return commitSetStage({ctx, targetStage, reason, actor: 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 activities (`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,\n mutation,\n nextStage,\n actor,\n at,\n entryKey,\n}: {\n ctx: EngineContext\n mutation: MutableInstance\n nextStage: Stage\n actor: Actor | undefined\n at: string\n /** Pre-minted `_key` for the new entry — a transition mints it before its\n * effects queue so those effects can carry the entry they belong to. */\n entryKey?: string\n}): Promise<void> {\n mutation.currentStage = nextStage.name\n const nextStageEntry: StageEntry = {\n _key: entryKey ?? randomKey(),\n name: nextStage.name,\n enteredAt: at,\n fields: await resolveStageFieldEntries({\n client: ctx.client,\n instance: ctx.instance,\n stage: nextStage,\n now: at,\n recordDiscard: recordFieldDiscards({target: mutation.history, scope: 'stage', at}),\n }),\n activities: await buildStageActivities(ctx, nextStage),\n }\n mutation.stages.push(nextStageEntry)\n\n for (const activity of nextStage.activities ?? []) {\n if (activity.activation !== 'auto') continue\n const entry = nextStageEntry.activities.find((t) => t.name === activity.name)\n if (entry && entry.status === 'pending') {\n await activateActivity({ctx, mutation, activity, 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,\n targetStage,\n reason,\n actor,\n}: {\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({\n ctx,\n mutation,\n exitedStage: currentStage.name,\n enteredStage: nextStage.name,\n })\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 keeps its locks. (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,\n mutation,\n exitedStage,\n enteredStage,\n}: {\n ctx: EngineContext\n mutation: MutableInstance\n exitedStage: StageName\n enteredStage: StageName\n}): Promise<void> {\n await persistThenDeploy({\n ctx,\n mutation,\n deploy: () =>\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 // Field-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 await 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 // A transition's effects belong to the stage entry the transition\n // produces (they queue before it exists), so its `_key` is minted here\n // and shared with `enterStage`.\n const nextEntryKey = randomKey()\n await queueEffects({\n ctx,\n mutation,\n effects: transition.effects,\n origin: {\n kind: 'transition',\n name: transition.name,\n },\n actor,\n opts: {stageEntryKey: nextEntryKey},\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, entryKey: nextEntryKey})\n\n await persistStageMove({\n ctx,\n mutation,\n exitedStage: currentStage.name,\n enteredStage: nextStage.name,\n })\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, condition: 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, toBareId} from '../core/refs.ts'\nimport type {LoadedDoc} from '../core/snapshot.ts'\nimport type {Stage, Activity, 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 {HistoryEntry} from '../types/history.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 {activateActivity, buildStageActivities, activityConditionVars} from './activities.ts'\nimport {\n buildEngineContext,\n type EngineContext,\n findStage,\n loadContext,\n resolveStageFieldEntries,\n} from './context.ts'\nimport {deployOrRollback} from './guard-commit.ts'\nimport {recordFieldDiscards} from './history-entries.ts'\nimport {currentActivities, findCurrentActivities, persist, startMutation} from './mutation.ts'\nimport {CascadeLimitError, type EngineCallOptions, type TransitionResult} from './results.ts'\nimport {\n applyGateOutcome,\n effectiveCompleteWhen,\n evaluateResolutionGate,\n type GateOutcome,\n} from './spawn.ts'\nimport {commitTransition} from './stages.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) | undefined\n clock?: Clock | undefined\n overlay?: ReadonlyMap<string, LoadedDoc> | undefined\n}): Promise<TransitionResult> {\n const {client, instanceId, options, clientForGdr, clock, overlay} = args\n const ctx = await loadContext({\n client,\n instanceId,\n options: {\n ...(clientForGdr ? {clientForGdr} : {}),\n ...(clock ? {clock} : {}),\n ...(overlay ? {overlay} : {}),\n },\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// activateActivity. Exported so api.ts doesn't reimplement them.\n\n/** Common arguments for a cascade step over one instance: its client + id, the\n * acting identity, and optional cross-resource routing / injected clock. */\ninterface CascadeStepArgs {\n client: WorkflowClient\n instanceId: string\n actor: Actor | undefined\n clientForGdr?: ((parsed: ParsedGdr) => WorkflowClient) | undefined\n clock?: Clock | undefined\n}\n\n/**\n * Build the initial stage entry + auto-activate its `activation: \"auto\"`\n * activities 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 activities.\n */\nexport async function primeInitialStage({\n client,\n instanceId,\n actor,\n clientForGdr,\n clock,\n}: CascadeStepArgs): 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 // Initial-stage stage-scope fields can be query-sourced; a discarded result\n // is appended to history alongside the stage entry in the same patch.\n const discards: HistoryEntry[] = []\n const initialStageEntry: StageEntry = {\n _key: randomKey(),\n name: stage.name,\n enteredAt: now,\n fields: await resolveStageFieldEntries({\n client,\n instance,\n stage,\n now,\n recordDiscard: recordFieldDiscards({target: discards, scope: 'stage', at: now}),\n }),\n activities: await buildStageActivities(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 ...(discards.length > 0 ? {history: [...instance.history, ...discards]} : {}),\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 autoActivatePrimedActivities({\n client,\n instanceId,\n definition,\n stage,\n actor,\n clientForGdr,\n clock,\n })\n}\n\n/**\n * After the initial stage entry is persisted, re-load and activate the\n * `activation: \"auto\"` activities. Each activation reloads + persists\n * independently so subworkflow fan-outs + auto-resolution see committed\n * state.\n */\nasync function autoActivatePrimedActivities({\n client,\n instanceId,\n definition,\n stage,\n actor,\n clientForGdr,\n clock,\n}: {\n client: WorkflowClient\n instanceId: string\n definition: WorkflowDefinition\n stage: Stage\n actor: Actor | undefined\n clientForGdr?: ((parsed: ParsedGdr) => WorkflowClient) | undefined\n clock?: Clock | undefined\n}): Promise<void> {\n const resolvedClientForGdr = clientForGdr ?? (() => client)\n for (const activity of stage.activities ?? []) {\n if (activity.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 = currentActivities(mutation).find((t) => t.name === activity.name)\n if (mutEntry && mutEntry.status === 'pending') {\n await activateActivity({ctx: updatedCtx, mutation, activity, entry: 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 activity 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 activity. 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 = {activity: Activity; outcome: GateOutcome}\n\n/** For each active gated activity, run {@link evaluateResolutionGate} over the\n * activity-context scope and collect the outcome. */\nasync function gatherAutoResolveCandidates(\n ctx: EngineContext,\n activities: Activity[],\n): Promise<AutoResolveCandidate[]> {\n const currentActivitiesList = findCurrentActivities(ctx.instance)\n const candidates: AutoResolveCandidate[] = []\n for (const activity of activities) {\n const entry = currentActivitiesList.find((e) => e.name === activity.name)\n if (entry?.status !== 'active') continue\n const outcome = await evaluateResolutionGate({\n ctx,\n activity,\n vars: await activityConditionVars(ctx, entry),\n })\n if (outcome !== undefined) candidates.push({activity, outcome})\n }\n return candidates\n}\n\nasync function resolveCompleteWhen({\n client,\n instanceId,\n clientForGdr,\n clock,\n overlay,\n}: {\n client: WorkflowClient\n instanceId: string\n clientForGdr?: ((parsed: ParsedGdr) => WorkflowClient) | undefined\n clock?: Clock | undefined\n overlay?: ReadonlyMap<string, LoadedDoc> | undefined\n}): Promise<number> {\n const ctx = await loadContext({\n client,\n instanceId,\n options: {\n ...(clientForGdr ? {clientForGdr} : {}),\n ...(clock ? {clock} : {}),\n ...(overlay ? {overlay} : {}),\n },\n })\n const stage = findStage(ctx.definition, ctx.instance.currentStage)\n const gatedActivities = (stage.activities ?? []).filter(\n (t) => effectiveCompleteWhen(t) !== undefined || t.failWhen !== undefined,\n )\n if (gatedActivities.length === 0) return 0\n\n const candidates = await gatherAutoResolveCandidates(ctx, gatedActivities)\n if (candidates.length === 0) return 0\n\n const mutation = startMutation(ctx.instance)\n let count = 0\n for (const {activity, outcome} of candidates) {\n const mutEntry = currentActivities(mutation).find((t) => t.name === activity.name)\n if (mutEntry === undefined || mutEntry.status !== 'active') continue\n applyGateOutcome({\n entry: mutEntry,\n history: mutation.history,\n stage: stage.name,\n at: ctx.now,\n 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 activities before each transition pass so a gate that became\n * satisfied can immediately unblock an `$allActivitiesDone`-style condition.\n */\nexport async function cascadeAutoTransitions({\n client,\n instanceId,\n actor,\n clientForGdr,\n clock,\n overlay,\n}: CascadeStepArgs & {overlay?: ReadonlyMap<string, LoadedDoc> | undefined}): 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 activity in case its completion gate is now satisfied. If a parent\n * activity 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 activity: Activity\n outcome: GateOutcome\n}\n\n/** The parent whose spawning activity this child belongs to, when that activity'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 * activity, activity already resolved, gate not yet met). */\nasync function findResolvedParentSpawn({\n client,\n child,\n clientForGdr,\n clock,\n}: {\n client: WorkflowClient\n child: WorkflowInstance\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient\n clock?: Clock | undefined\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>(toBareId(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 activity 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 parentCurrentActivities = findCurrentActivities(parent)\n const activity = (stage.activities ?? []).find((t) => {\n if (t.subworkflows === undefined) return false\n const entry = parentCurrentActivities.find((e) => e.name === t.name)\n return entry?.spawnedInstances?.some((r) => toBareId(r.id) === child._id) ?? false\n })\n if (activity?.subworkflows === undefined) return undefined\n\n const entry = parentCurrentActivities.find((e) => e.name === activity.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({\n ctx,\n activity,\n vars: await activityConditionVars(ctx, entry),\n })\n if (outcome === undefined) return undefined\n return {parent, definition, stage, activity, outcome}\n}\n\nexport async function propagateToAncestors({\n client,\n instanceId,\n actor,\n clientForGdr,\n clock,\n}: CascadeStepArgs): 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({\n client,\n child: instance,\n clientForGdr: resolvedClientForGdr,\n clock,\n })\n if (found === undefined) return\n const {parent, definition, stage, activity, outcome} = found\n\n // Flip the parent's activity and persist. The flip is the spawning activity'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 = currentActivities(mutation).find((e) => e.name === activity.name)\n if (mutEntry === undefined) return\n applyGateOutcome({\n entry: mutEntry,\n history: mutation.history,\n stage: stage.name,\n at: ctx.now,\n 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 activity.\n await cascadeAutoTransitions({client, instanceId: parent._id, actor, clientForGdr, clock})\n\n // Recurse: propagate from the parent upward.\n await propagateToAncestors({client, instanceId: 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 advisory authorization read: 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: the rendered `$can` stays\n * undefined (conditions referencing it fail closed; nothing else is\n * gated engine-side) and the real Sanity write boundary still\n * enforces. Actor-fetch failure is fatal — the engine refuses to\n * 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'\nimport {ContractViolationError} from './types/errors.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` / `ValueExpr.actor` —\n * caller-asserted advisory provenance (see {@link Actor}), never an\n * authenticated principal. `grants` (when present) feed the advisory\n * `$can.*` params action conditions can read; there is no engine-side\n * permission verdict. When grants are absent the rendered `$can` is\n * undefined — conditions referencing it fail closed, everything else\n * is ungated engine-side — and the real Sanity write boundary takes\n * 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 acting 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 rendered `$can` stays undefined).\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 ContractViolationError(\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({\n overrideGrants,\n grantsFromPath: args.grantsFromPath,\n client,\n requestFn,\n })\n\n const [actor, grants] = await Promise.all([actorPromise, grantsPromise])\n if (actor === undefined) {\n throw new ContractViolationError(\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,\n grantsFromPath,\n client,\n requestFn,\n}: {\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)\n return cachedGrants({client, requestFn, resourcePath: grantsFromPath})\n return Promise.resolve(undefined)\n}\n\nfunction cachedGrants({\n client,\n requestFn,\n resourcePath,\n}: {\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: 'person',\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}\"; the advisory $can params stay ` +\n `undefined (conditions referencing $can fail closed; the lake still enforces writes). ` +\n `Original error: ${err instanceof Error ? err.message : String(err)}`,\n )\n return undefined\n }\n}\n","/**\n * Activity classification — pure, advisory mapping from an activity's SHAPE to its\n * {@link ActivityKind}, and from a firing {@link Actor} to its {@link DriverKind}.\n *\n * `kind` classifies an activity by its executor (BPMN-aligned) so tooling can render\n * it as what it is; it never affects gating or how an activity resolves. When a\n * definition omits `kind`, {@link deriveActivityKind} computes it from the fields\n * the activity already carries, so existing definitions need no edits and the UI\n * gets a kind regardless.\n */\n\nimport type {Activity} from './define/schema.ts'\nimport {isEngineActor} from './engine/system-actor.ts'\nimport type {Actor} from './types/actor.ts'\nimport type {DriverKind, ActivityKind} from './types/enums.ts'\n\nfunction hasItems(arr: readonly unknown[] | undefined): boolean {\n return arr !== undefined && arr.length > 0\n}\n\n/**\n * Classify an activity from its shape, in precedence order: an activity a person acts on\n * (`actions`) is `user`; otherwise an automated effect step is `service`;\n * otherwise an activity that waits on a condition (`completeWhen` or a `subworkflows`\n * fan-out) is `receive`; otherwise an inline machine step is `script`.\n *\n * Never returns `manual` — off-system work reads identically to a `user` or\n * `receive` activity by shape, so it is only ever an EXPLICIT {@link Activity.kind}.\n */\nexport function deriveActivityKind(activity: Activity): ActivityKind {\n if (hasItems(activity.actions)) return 'user'\n if (hasItems(activity.effects)) return 'service'\n if (activity.completeWhen !== undefined || activity.subworkflows !== undefined) return 'receive'\n return 'script'\n}\n\n/** The effective kind of an activity: the explicitly declared {@link Activity.kind}, or\n * the shape-derived default when omitted. */\nexport function activityKind(activity: Activity): ActivityKind {\n return activity.kind ?? deriveActivityKind(activity)\n}\n\n/**\n * Classify the actor that drove an action for the audit-trail glyph. `person`\n * and `agent` pass through from {@link Actor.kind}; a `system` actor is the\n * `engine` itself ({@link isEngineActor}) or otherwise an external `service`.\n *\n * Advisory and only as trustworthy as the {@link Actor} it reads — actor\n * identity is itself advisory in this engine (the lake/token is authoritative),\n * so this is a best-effort glyph, never an authorization signal.\n */\nexport function driverKind(actor: Actor): DriverKind {\n if (actor.kind === 'person' || actor.kind === 'agent') return actor.kind\n // `system` — plus anything out-of-vocabulary from an untyped caller, so the\n // persisted glyph always lands inside DRIVER_KINDS.\n return isEngineActor(actor) ? 'engine' : 'service'\n}\n","/**\n * Editable fields — the shared resolution behind the generic edit seam. The one\n * place that answers \"which declared fields 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 `editField`\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: editability is DECLARED per field (default off);\n * `scope` is the editable *window* (where the field is declared — workflow /\n * stage / activity); a stage may only TIGHTEN a field via conjunction; everything\n * here is ADVISORY; and provenance is read straight off the `opApplied`\n * history the op path already stamps.\n */\n\nimport type {\n Editable,\n Stage,\n FieldEntry,\n StoredFieldRef,\n WorkflowDefinition,\n} from '../define/schema.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {FieldScope} from '../types/enums.ts'\nimport type {EditFieldDeniedReason, MutationGuardDenial} from '../types/evaluation.ts'\nimport type {ResolvedFieldEntry, FieldKind} from '../types/field-values.ts'\nimport type {ActivityName} from '../types/ids.ts'\nimport {findCurrentActivityEntry, findOpenStageEntry} from '../types/instance-state.ts'\nimport type {WorkflowInstance} from '../types/instance.ts'\nimport {andConditions} from './conditions.ts'\n\n/**\n * Effective editability of a field in a stage: the field'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 * (field 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 field located in a stage's scope, with its effective editability. */\nexport interface ResolvedFieldSite {\n scope: FieldScope\n /** Present iff `scope === \"activity\"` — the activity whose fields[] holds the entry. */\n activity?: ActivityName\n name: string\n type: FieldKind\n title?: string\n /** The stored reference the op path targets. */\n ref: StoredFieldRef\n /** Baseline AND the stage override — `undefined` means not editable here. */\n effective: Editable | undefined\n}\n\ninterface FieldSite {\n scope: FieldScope\n activity?: ActivityName\n entry: FieldEntry\n}\n\n/** Every declared field reachable for editing in `stage`: workflow-scope,\n * this stage's scope, and this stage's activities' scope. */\nfunction fieldSites(definition: WorkflowDefinition, stage: Stage): FieldSite[] {\n const sites: FieldSite[] = []\n for (const entry of definition.fields ?? []) sites.push({scope: 'workflow', entry})\n for (const entry of stage.fields ?? []) sites.push({scope: 'stage', entry})\n for (const activity of stage.activities ?? []) {\n for (const entry of activity.fields ?? [])\n sites.push({scope: 'activity', activity: activity.name, entry})\n }\n return sites\n}\n\nfunction resolveFieldSite(site: FieldSite, stage: Stage): ResolvedFieldSite {\n return {\n scope: site.scope,\n ...(site.activity !== undefined ? {activity: site.activity} : {}),\n name: site.entry.name,\n type: site.entry.type,\n ...(site.entry.title !== undefined ? {title: site.entry.title} : {}),\n ref: {scope: site.scope, field: site.entry.name},\n effective: effectiveEditable(site.entry.editable, stage.editable?.[site.entry.name]),\n }\n}\n\n/** The fields a stage declares as editable (baseline `editable` set), each with\n * its effective editability after the stage's tighten-override. */\nexport function editableFieldsInStage(\n definition: WorkflowDefinition,\n stage: Stage,\n): ResolvedFieldSite[] {\n return fieldSites(definition, stage)\n .filter((site) => site.entry.editable !== undefined)\n .map((site) => resolveFieldSite(site, stage))\n}\n\n/** An edit-target descriptor (`{scope?, field, activity?}`) addressing this field.\n * An explicit `activity` requires an activity-scope match; an explicit `scope` must\n * match; a bare name matches any scope (the caller disambiguates lexically). */\nexport function editTargetMatches(\n site: {scope: FieldScope; name: string; activity?: string},\n target: {scope?: FieldScope; field: string; activity?: string},\n): boolean {\n if (site.name !== target.field) return false\n if (target.activity !== undefined)\n return site.scope === 'activity' && site.activity === target.activity\n if (target.scope !== undefined) return site.scope === target.scope\n return true\n}\n\n/** Lexical precedence for an ambiguous bare-name match: nearest scope wins,\n * activity before stage before workflow (mirrors `$fields` shadowing). */\nexport const SCOPE_PRECEDENCE: Record<FieldScope, number> = {activity: 0, stage: 1, workflow: 2}\n\n/** Resolve a single edit target by name (+ optional explicit scope / activity).\n * Scope inference, when omitted: an explicit `activity` ⇒ activity scope; otherwise\n * the nearest declaring scope, stage before workflow (mirrors `$fields` reads).\n * Returns `undefined` when no declared field matches. */\nexport function resolveEditTarget(args: {\n definition: WorkflowDefinition\n stage: Stage\n target: {scope?: FieldScope; field: string; activity?: string}\n}): ResolvedFieldSite | undefined {\n const {definition, stage, target} = args\n const found = fieldSites(definition, stage)\n .filter((site) =>\n editTargetMatches(\n {\n scope: site.scope,\n name: site.entry.name,\n ...(site.activity !== undefined ? {activity: site.activity} : {}),\n },\n target,\n ),\n )\n .sort((a, b) => SCOPE_PRECEDENCE[a.scope] - SCOPE_PRECEDENCE[b.scope])[0]\n return found ? resolveFieldSite(found, stage) : undefined\n}\n\n/** Whether a field's scope window is currently open for editing, and a reason\n * string when it isn't. Workflow/stage fields are open while the instance is\n * live; an activity-scope field is open only while its activity is `active`. */\nexport function fieldWindowOpen(\n instance: WorkflowInstance,\n site: {scope: FieldScope; activity?: ActivityName},\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 (site.scope !== 'activity') return {open: true}\n const status = findCurrentActivityEntry(instance, site.activity)?.status\n if (status === 'active') return {open: true}\n return {open: false, detail: `activity \"${site.activity}\" is ${status ?? 'not active'}`}\n}\n\n/** The current resolved value of a field, read from the instance's runtime\n * fields[] at the field's scope. `undefined` when the field hasn't been resolved\n * yet (e.g. an activity-scope field before its activity activated). */\nexport function readFieldValue(\n instance: WorkflowInstance,\n site: {scope: FieldScope; activity?: ActivityName; name: string},\n): unknown {\n return fieldEntryHost(instance, site)?.find((e) => e.name === site.name)?.value\n}\n\nfunction fieldEntryHost(\n instance: WorkflowInstance,\n site: {scope: FieldScope; activity?: ActivityName},\n): ResolvedFieldEntry[] | undefined {\n if (site.scope === 'workflow') return instance.fields\n const stageEntry = findOpenStageEntry(instance)\n if (site.scope === 'stage') return stageEntry?.fields\n return stageEntry?.activities.find((t) => t.name === site.activity)?.fields\n}\n\n/**\n * Per-field provenance, read off the audit trail: the actor and time of the\n * latest `opApplied` history entry that targeted this field. The op path stamps\n * every field write, so this is the single source of truth — no denormalised\n * copy on the entry. Returns empty when the field was never written.\n */\nexport function fieldProvenance(\n instance: WorkflowInstance,\n ref: StoredFieldRef,\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.field !== ref.field) 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 deployed guard denying → 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 field now.\n *\n * Generic over the guard verdict the caller holds: a caller that passes no\n * guard denial (the engine's commit re-gate) statically gets back only the\n * {@link EditFieldDeniedReason} arms.\n */\nexport function editDisabledReason<G extends MutationGuardDenial | undefined>(args: {\n effective: Editable | undefined\n instance: WorkflowInstance\n window: {open: boolean; detail?: string}\n guardDenial: G\n predicateSatisfied: boolean\n}): EditFieldDeniedReason | G | 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`, `$fields`, …) — authoring\n * sugar like `roles` desugared into it at define time. Everything this\n * module evaluates is advisory UX; the hard gate is the lake ACL on the\n * documents. `$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 {activityKind} from './activity-kind.ts'\nimport type {EngineScopeArgs} from './api/types.ts'\nimport {type Clocked, wallClock} from './clock.ts'\nimport {\n editableFieldsInStage,\n editDisabledReason,\n readFieldValue,\n type ResolvedFieldSite,\n fieldProvenance,\n fieldWindowOpen,\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, scopedFieldOverlay} from './core/params.ts'\nimport type {ParsedGdr} from './core/refs.ts'\nimport type {HydratedSnapshot} from './core/snapshot.ts'\nimport type {Action, RoleAliases, Stage, Activity, 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 {deniedGuardRefs, type Grant, type MutationGuardDoc} from './types/authorization.ts'\nimport {\n DOCUMENT_VALUE_PERMISSIONS,\n isTerminalActivityStatus,\n type ActivityStatus,\n} from './types/enums.ts'\nimport type {\n ActionEvaluation,\n DisabledReason,\n EditableFieldEvaluation,\n MutationGuardDenial,\n StageEvaluation,\n ActivityEvaluation,\n TransitionEvaluation,\n WorkflowEvaluation,\n} from './types/evaluation.ts'\nimport {findOpenStageEntry, type ActivityEntry} from './types/instance-state.ts'\nimport {parseDefinitionSnapshot, type WorkflowInstance} from './types/instance.ts'\n\nexport interface EvaluateArgs {\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\nexport async function evaluateInstance(\n args: Clocked<EvaluateArgs & EngineScopeArgs>,\n): 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 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 in this\n * projection — the engine's verb paths load live guards and re-check at\n * commit time ({@link evaluateInstance} fetches them itself).\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: verdicts are\n * advisory, not 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 currentActivityEntries = findOpenStageEntry(instance)?.activities ?? []\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, guards: args.guards})\n\n const activityEvaluations: ActivityEvaluation[] = []\n for (const activity of stage.activities ?? []) {\n activityEvaluations.push(\n await evaluateActivity({\n activity,\n statusEntry: currentActivityEntries.find((t) => t.name === activity.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 activities: activityEvaluations,\n transitions: transitionEvaluations,\n }\n\n const pendingOnYou = activityEvaluations.filter((t) => t.pendingOnActor)\n const canInteract = activityEvaluations.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 editableFields = await evaluateEditableFields({\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 editableFields,\n }\n}\n\ninterface EvaluateEditableFieldsArgs {\n instance: WorkflowInstance\n definition: WorkflowDefinition\n stage: Stage\n actor: Actor\n snapshot: HydratedSnapshot\n /** The projection's base rendered scope (workflow/stage fields evaluate here). */\n scope: Record<string, unknown>\n /** Shared instance-write guard verdict, precomputed once per evaluation. */\n guardDenial: MutationGuardDenial | undefined\n}\n\n/**\n * Project every declared-editable field 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 field's own scope — an activity-scope field\n * sees its activity's `$assigned` and lexical `$fields` overlay, exactly as that\n * activity's actions do.\n */\nasync function evaluateEditableFields(\n args: EvaluateEditableFieldsArgs,\n): Promise<EditableFieldEvaluation[]> {\n const {instance, definition, stage, actor, snapshot, scope, guardDenial} = args\n const fields: EditableFieldEvaluation[] = []\n for (const site of editableFieldsInStage(definition, stage)) {\n const window = fieldWindowOpen(instance, site)\n const predicateSatisfied = await editPredicateSatisfied({\n site,\n window,\n guardDenial,\n instance,\n snapshot,\n scope,\n actor,\n roleAliases: definition.roleAliases,\n })\n const reason = editDisabledReason({\n effective: site.effective,\n instance,\n window,\n guardDenial,\n predicateSatisfied,\n })\n const value = readFieldValue(instance, site)\n fields.push({\n scope: site.scope,\n ...(site.activity !== undefined ? {activity: site.activity} : {}),\n name: site.name,\n type: site.type,\n ...(site.title !== undefined ? {title: site.title} : {}),\n value,\n editable: reason === undefined,\n ...(reason !== undefined ? {disabledReason: reason} : {}),\n ...fieldProvenance(instance, site.ref),\n })\n }\n return fields\n}\n\n/**\n * Whether the field'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 site: ResolvedFieldSite\n window: {open: boolean}\n guardDenial: MutationGuardDenial | undefined\n instance: WorkflowInstance\n snapshot: HydratedSnapshot\n scope: Record<string, unknown>\n actor: Actor\n roleAliases: RoleAliases | undefined\n}): Promise<boolean> {\n const {site, window, guardDenial, instance, snapshot, scope, actor, roleAliases} = args\n if (!window.open || guardDenial !== undefined) return false\n if (site.effective === true) return true\n const params =\n site.scope === 'activity' && site.activity !== undefined\n ? activityScopeFor({\n scope,\n instance,\n snapshot,\n actor,\n activityName: site.activity,\n roleAliases,\n })\n : scope\n return evaluateCondition({condition: site.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-activity\n * vars (`$assigned`, the lexical `$fields` 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,\n actor,\n grants,\n}: {\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 EvaluateActivityArgs {\n activity: Activity\n statusEntry: ActivityEntry | 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 an activity: the projection's base scope with the activity's\n * lexical `$fields` overlay layered on and `$assigned` set for this actor.\n * Shared by activity-action evaluation and editable activity-field evaluation so both\n * read identically.\n */\nfunction activityScopeFor(args: {\n scope: Record<string, unknown>\n instance: WorkflowInstance\n snapshot: HydratedSnapshot\n actor: Actor\n activityName: string\n roleAliases: RoleAliases | undefined\n}): Record<string, unknown> {\n const {scope, instance, snapshot, actor, activityName, roleAliases} = args\n return {\n ...scope,\n fields: {\n ...(scope.fields as Record<string, unknown>),\n ...scopedFieldOverlay({instance, snapshot, activityName}),\n },\n assigned: assignedFor({instance, activityName, actor, roleAliases}),\n }\n}\n\nasync function evaluateActivity(args: EvaluateActivityArgs): Promise<ActivityEvaluation> {\n const {\n activity,\n statusEntry,\n instance,\n actor,\n snapshot,\n scope,\n roleAliases,\n stageHasExits,\n guardDenial,\n } = args\n const status: ActivityStatus = statusEntry?.status ?? 'pending'\n const activityScope = activityScopeFor({\n scope,\n instance,\n snapshot,\n actor,\n activityName: activity.name,\n roleAliases,\n })\n const assigned = activityScope.assigned === true\n\n // Readiness is an activity-level fact (requirements are declared on the activity), 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: activity.requirements,\n snapshot,\n params: activityScope,\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 activity.actions ?? []) {\n actions.push(\n await evaluateAction({\n action,\n status,\n instance,\n snapshot,\n activityScope,\n stageHasExits,\n guardDenial,\n requirementsReason,\n }),\n )\n }\n\n return {\n activity,\n status,\n kind: activityKind(activity),\n // \"pending on actor\" treats both `pending` and `active` as waiting on\n // the assignee — pending activities just haven't been activated yet, but\n // they're still inbox items. The inbox reads the assignees-kind field\n // entry BY KIND (who-data is fields).\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: ActivityStatus\n instance: WorkflowInstance\n snapshot: HydratedSnapshot\n activityScope: Record<string, unknown>\n stageHasExits: boolean\n guardDenial: DisabledReason | undefined\n /** Shared activity-readiness verdict, precomputed once per activity. */\n requirementsReason: DisabledReason | undefined\n}\n\nasync function evaluateAction(args: EvaluateActionArgs): Promise<ActionEvaluation> {\n const {\n action,\n status,\n instance,\n snapshot,\n activityScope,\n stageHasExits,\n guardDenial,\n requirementsReason,\n } = args\n\n // First failing gate wins, ordered most- to least-fundamental: lifecycle\n // (activity/instance/stage state), then the guard pre-flight (a denied instance\n // write dooms every action), then activity 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: activityScope,\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 count against 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,\n actor,\n guards,\n}: {\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 {kind: 'mutation-guard-denied', denied: deniedGuardRefs(denied)}\n}\n\nfunction lifecycleReason({\n instance,\n status,\n stageHasExits,\n}: {\n instance: WorkflowInstance\n status: ActivityStatus\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 (isTerminalActivityStatus(status)) {\n return {kind: 'activity-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","/**\n * Shell-side instance-list query, one builder for both read styles — the\n * engine's one-shot fetch (`instancesForDocument`) and the reactive adapters'\n * live subscriptions feed the same `{query, params}`, the same\n * stateless/reactive split as {@link instanceGuardQuery}.\n */\n\nimport {extractDocumentId, isGdrUri, type GdrUri} from './core/refs.ts'\nimport {tagScopeFilter, validateTag} from './tags.ts'\nimport type {CompiledQuery} from './types/client.ts'\nimport {ContractViolationError} from './types/errors.ts'\nimport {WORKFLOW_INSTANCE_TYPE} from './types/instance.ts'\n\n/**\n * Narrows an instance-list read. All conditions AND together; an empty\n * filter means \"every in-flight instance in the engine's resource\".\n */\nexport interface InstancesQueryFilter {\n /**\n * Only instances that may reference this document (resource-qualified GDR\n * URI). This is a lake-side PREFILTER — a deliberate superset that also\n * matches exited-stage refs; narrow the fetched rows to the exact reactive\n * watch-set with {@link instanceWatchesDocument}.\n */\n document?: GdrUri\n /** Version-less definition `name` the instances were started from. */\n definition?: string\n /** Current stage name. */\n stage?: string\n /** Include completed/aborted instances (default: in-flight only). */\n includeCompleted?: boolean\n}\n\n// True when a field-entry value is the doc (doc.ref / release.ref, whose\n// value is a GDR) or contains it (doc.refs, whose value is a GDR array).\n// Evaluated against workflow-scope `fields` and each stage's `fields`, so\n// the two arms can't drift.\nconst FIELD_REFS_DOC = `count(fields[value.id == $document]) > 0 || count(fields[$document in value[].id]) > 0`\n\n// The activity-scope arm of the same check, nested like the stage arm — a\n// flattened `stages[].activities[].fields` traversal is unsound in groq-js\n// (an activity without `fields` contributes a null element the filter\n// counts), so each activity's fields are filtered in their own scope.\nconst ACTIVITY_REFS_DOC = `count(stages[count(activities[${FIELD_REFS_DOC}]) > 0]) > 0`\n\n/**\n * The instance-list GROQ for a {@link InstancesQueryFilter}, ordered by\n * `startedAt` ascending. Adapters subscribe to it; {@link workflow.query}\n * -style one-shot reads fetch it — both see the same rows.\n */\nexport function instancesQuery(args: {tag: string; filter?: InstancesQueryFilter}): CompiledQuery {\n const {tag, filter = {}} = args\n validateTag(tag)\n\n const conditions = [`_type == \"${WORKFLOW_INSTANCE_TYPE}\"`, tagScopeFilter()]\n const params: Record<string, string> = {tag}\n\n if (filter.includeCompleted !== true) conditions.push('!defined(completedAt)')\n if (filter.definition !== undefined) {\n conditions.push('definition == $definition')\n params['definition'] = filter.definition\n }\n if (filter.stage !== undefined) {\n conditions.push('currentStage == $stage')\n params['stage'] = filter.stage\n }\n if (filter.document !== undefined) {\n if (!isGdrUri(filter.document)) {\n throw new ContractViolationError(\n `instancesQuery: \"document\" must be a resource-qualified GDR URI ` +\n `(e.g. \"dataset:project:dataset:doc-id\"); got: ${JSON.stringify(filter.document)}`,\n )\n }\n conditions.push(\n `(_id == $bareId || $document in ancestors[].id || ${FIELD_REFS_DOC} || count(stages[${FIELD_REFS_DOC}]) > 0 || ${ACTIVITY_REFS_DOC})`,\n )\n params['document'] = filter.document\n params['bareId'] = extractDocumentId(filter.document)\n }\n\n return {query: `*[${conditions.join(' && ')}] | order(startedAt asc)`, params}\n}\n","import type {SanityDocument} from '@sanity/types'\n\nimport {mapJsonStrings} from '../core/json.ts'\nimport {\n definitionDocId,\n gdrResourcePrefix,\n isGdrUri,\n RESOURCE_ALIAS_NAME_SOURCE,\n validateResourceAliasName,\n type ResourceAliases,\n type WorkflowResource,\n} 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'\nimport {DefinitionNotFoundError} from '../types/errors.ts'\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,\n definitions,\n tag,\n}: {\n client: WorkflowClient\n definitions: WorkflowDefinition[]\n tag: string\n}): Promise<WorkflowDefinition[]> {\n // One definition per name in a batch — names, not versions, identify a batch\n // member now. A logical ref resolves to a batch member by name; an explicit\n // version pins an already-deployed one instead. Two definitions sharing a\n // name is therefore ambiguous (no version to tell them apart) — reject it.\n const byName = new Map<string, WorkflowDefinition>()\n for (const def of definitions) {\n if (byName.has(def.name)) {\n throw new Error(\n `workflow.deployDefinitions: duplicate definition name \"${def.name}\" in batch — ` +\n `names identify a batch member (versions are deploy-assigned, not authored)`,\n )\n }\n byName.set(def.name, def)\n }\n const findInBatch = (ref: LogicalRef) => findRefInBatch(byName, ref)\n\n await assertCrossBatchRefsDeployed({client, definitions, ctx: {tag, findInBatch}})\n\n return topoSortDefinitions(definitions, {findInBatch})\n}\n\nexport interface LogicalRef {\n name: string\n version?: number | 'latest'\n}\n\n/** Resolve a logical ref to a batch member. A ref with no version (or\n * `latest`) matches by name; an explicit numeric version pins an\n * already-deployed version, never a batch member, so it never resolves here. */\nfunction findRefInBatch(\n byName: Map<string, WorkflowDefinition>,\n ref: LogicalRef,\n): WorkflowDefinition | undefined {\n if (typeof ref.version === 'number') return undefined\n return byName.get(ref.name)\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,\n definitions,\n ctx,\n}: {\n client: WorkflowClient\n definitions: WorkflowDefinition[]\n ctx: {\n tag: string\n findInBatch: (ref: LogicalRef) => WorkflowDefinition | undefined\n }\n}): Promise<void> {\n const missing: {from: string; ref: string}[] = []\n for (const def of definitions) {\n for (const ref of refsOf(def)) {\n if (ctx.findInBatch(ref) !== undefined) continue // satisfied within batch\n const label = await resolveDeployedRefLabel({client, ref, tag: ctx.tag})\n if (label !== undefined) missing.push({from: def.name, 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,\n ref,\n tag,\n}: {\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 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 if (visited.has(def.name)) return\n if (visiting.has(def.name)) {\n throw new Error(`workflow.deployDefinitions: dependency cycle involving \"${def.name}\"`)\n }\n visiting.add(def.name)\n for (const ref of refsOf(def)) {\n const child = ctx.findInBatch(ref)\n if (child !== undefined) visit(child)\n }\n visiting.delete(def.name)\n visited.add(def.name)\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 activity of stage.activities ?? []) {\n const ref = activity.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 * Content fingerprint of an authored definition: the canonical JSON of its\n * content, hashed. Stamped on the deployed document ({@link DeployedDefinition})\n * and pinned on every instance, so a redeploy of identical content is a no-op\n * and a definition that drifted from what an instance pinned is detectable.\n *\n * Advisory, like every engine check (the lake is the only enforcement point):\n * FNV-1a is a fast, deterministic, dependency-free, isomorphic digest — enough\n * to detect honest change and drift, not a tamper-proof seal. Kept synchronous\n * so the pure planning path ({@link planDefinitionDeploy}) needs no `await`.\n */\nexport function hashDefinitionContent(def: WorkflowDefinition): string {\n const canonical = stableStringify(def)\n let hash = 0xcbf29ce484222325n\n for (let i = 0; i < canonical.length; i++) {\n hash ^= BigInt(canonical.charCodeAt(i))\n hash = (hash * 0x100000001b3n) & 0xffffffffffffffffn\n }\n return hash.toString(16).padStart(16, '0')\n}\n\n/** The latest deployed version of a definition, as far as deploy planning\n * cares: its version number and (when present) the fingerprint it was\n * stamped with. A pre-fingerprint document has no `contentHash` — it then\n * always reads as changed, so the first redeploy after upgrade mints a fresh\n * version. */\nexport interface LatestDeployed {\n version: number\n contentHash?: string\n}\n\nexport interface DeployPlan {\n /** `unchanged` ⇒ identical content already deployed as the latest version;\n * `create` ⇒ a fresh version would be written. Deploy NEVER patches. */\n status: 'create' | 'unchanged'\n version: number\n contentHash: string\n docId: string\n /** The document deploy would write — meaningful only when `status` is `create`.\n * Carries `_id`/`_type` so it drops straight into a `client.create`. */\n document: {_id: string; _type: string} & Record<string, unknown>\n}\n\n/**\n * Decide what deploying one authored definition does, given the latest version\n * already deployed under its name. Content-addressed and create-only: the\n * incoming content's hash decides. Identical to the latest ⇒ no-op; any\n * difference ⇒ the next version (`latest + 1`, or `1` when none is deployed).\n * Neither `version` nor `contentHash` is authored — both are stamped here.\n *\n * The comparison is against the LATEST version only, not the full history:\n * re-deploying content byte-identical to an *older* version mints a new version\n * rather than matching it — history is linear and immutable, never rewound.\n *\n * Resource-alias expansion ({@link expandResourceAliases}) runs here, before the\n * fingerprint, so both callers hash physical content. Shared by\n * {@link deployDefinitions} (which acts on the plan) and the diff tooling (which\n * renders it), so deploy and `definition diff` can never drift — including on\n * whether expansion ran.\n */\nexport function planDefinitionDeploy({\n def,\n latest,\n target,\n}: {\n def: WorkflowDefinition\n latest: LatestDeployed | undefined\n target: {tag: string; workflowResource: WorkflowResource; resourceAliases?: ResourceAliases}\n}): DeployPlan {\n const expanded = expandResourceAliases(def, target.resourceAliases)\n const contentHash = hashDefinitionContent(expanded)\n const unchanged = latest !== undefined && latest.contentHash === contentHash\n const version = unchanged ? latest.version : (latest?.version ?? 0) + 1\n const docId = definitionDocId({\n tag: target.tag,\n definition: expanded.name,\n version,\n })\n const document = {\n ...expanded,\n _id: docId,\n _type: WORKFLOW_DEFINITION_TYPE,\n tag: target.tag,\n version,\n contentHash,\n }\n return {status: unchanged ? 'unchanged' : 'create', version, contentHash, docId, document}\n}\n\nconst RESOURCE_ALIAS_REF_RE = new RegExp(`@(${RESOURCE_ALIAS_NAME_SOURCE}):`, 'g')\nconst STANDALONE_RESOURCE_ALIAS_RE = new RegExp(`^@${RESOURCE_ALIAS_NAME_SOURCE}:`)\n\n/**\n * Human-prose definition fields. A `@word:` here is text, not a resource-alias\n * reference, so expanding it would corrupt the prose (or, when the word isn't a\n * bound alias, wrongly fail the deploy). Every other string position can hold a\n * reference, so expansion skips only these.\n *\n * Keyed by property name, since these are the only conventionally-prose fields\n * in the schema. A reference deliberately placed under a key literally named\n * `title`/`description` (e.g. a `doc.ref` field named \"title\") would be skipped —\n * but those names are prose by convention and never hold references, and an\n * unexpanded alias fails loudly when read, never silently against a wrong\n * resource.\n */\nconst PROSE_KEYS = new Set(['title', 'description'])\n\n/**\n * Expand every `@<alias>:` reference in a definition to the physical GDR prefix\n * its alias binds to, returning a definition that carries only physical\n * references. Fails closed — naming the definition + alias — when a referenced\n * alias isn't bound: the check that stops a portable definition from deploying\n * against the wrong (or no) resource.\n *\n * Runs at deploy (inside {@link planDefinitionDeploy}), BEFORE the content\n * fingerprint, so a deployed definition never carries a logical alias. The\n * stored references are physical, and a rebind (same source, a different alias\n * map) surfaces as changed content — a new version, never a silent shift in what\n * the workflow reads. A no-op when the definition references no aliases.\n *\n * Rewrites string VALUES only (via the shared {@link mapJsonStrings} deep-walk),\n * skipping the prose fields in {@link PROSE_KEYS}. A reference that stands alone\n * (the whole value is `@<alias>:<id>`, e.g. a literal `doc.ref`) must expand to a\n * well-formed GDR — a malformed one (`@content:a:b`, an empty id) is rejected\n * here rather than failing when an instance later reads it.\n */\nexport function expandResourceAliases(\n definition: WorkflowDefinition,\n resourceAliases: ResourceAliases | undefined,\n): WorkflowDefinition {\n assertResourceAliasNamesValid(resourceAliases)\n const map = resourceAliases ?? {}\n return mapJsonStrings(definition, (value, key) =>\n key !== undefined && PROSE_KEYS.has(key)\n ? value\n : expandAliasString({value, map, definitionName: definition.name}),\n ) as WorkflowDefinition\n}\n\n/**\n * Expand the `@<alias>:` prefixes in one string. A standalone reference (the\n * string starts with `@<alias>:`) must yield a valid GDR; inside GROQ the alias\n * is only a prefix on a runtime-built id, so just the prefix is rewritten. GROQ\n * never starts with `@<alias>:` — its `@` self-reference is `@.`/`@[` — so the\n * leading-`@<alias>:` test reliably distinguishes the two.\n */\nfunction expandAliasString({\n value,\n map,\n definitionName,\n}: {\n value: string\n map: ResourceAliases\n definitionName: string\n}): string {\n const expanded = value.replace(RESOURCE_ALIAS_REF_RE, (_match, alias: string) => {\n // `Object.hasOwn`, not `map[alias]`: an alias like `constructor` matches the\n // grammar but isn't an own key, so a direct index would read a truthy value\n // off the prototype chain and skip the fail-closed branch.\n if (!Object.hasOwn(map, alias)) {\n throw new Error(\n `workflow.deployDefinitions: definition \"${definitionName}\" references unbound resource ` +\n `alias \"@${alias}\". Bind it in the deploy target's resource map, or remove the reference.`,\n )\n }\n return gdrResourcePrefix(map[alias]!)\n })\n if (expanded === value) return value\n if (STANDALONE_RESOURCE_ALIAS_RE.test(value) && !isGdrUri(expanded)) {\n throw new Error(\n `workflow.deployDefinitions: definition \"${definitionName}\" reference \"${value}\" expands to ` +\n `the malformed GDR \"${expanded}\". A resource alias reference must be \"@<alias>:<documentId>\" ` +\n `with a single document id.`,\n )\n }\n return expanded\n}\n\n/**\n * Reject a malformed resource-alias name in the binding map before it's used: a\n * key the `@<alias>:` scan could never match (e.g. uppercase) would be a\n * silently dead binding, so fail loud instead.\n */\nfunction assertResourceAliasNamesValid(resourceAliases: ResourceAliases | undefined): void {\n for (const name of Object.keys(resourceAliases ?? {})) {\n validateResourceAliasName(name)\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,\n definition,\n version,\n tag,\n}: {\n client: WorkflowClient\n definition: string\n version: number | undefined\n tag: string\n}): Promise<DeployedDefinition> {\n if (version !== undefined) {\n const doc = await client.fetch<DeployedDefinition | null>(definitionLookupGroq(true), {\n definition,\n version,\n tag,\n })\n if (!doc) {\n throw new DefinitionNotFoundError({definition, version})\n }\n return doc\n }\n const latest = await loadLatestDeployed({client, definition, tag})\n if (!latest) {\n throw new DefinitionNotFoundError({definition})\n }\n return latest\n}\n\n/**\n * The latest deployed version of a definition visible to `tag`, or undefined\n * when none is deployed. The non-throwing counterpart of {@link loadDefinition}\n * — deploy planning treats \"nothing deployed yet\" as a normal `create`, not an\n * error. Returns the full document so callers can also render the prior shape.\n */\nexport async function loadLatestDeployed({\n client,\n definition,\n tag,\n}: {\n client: Pick<WorkflowClient, 'fetch'>\n definition: string\n tag: string\n}): Promise<DeployedDefinition | undefined> {\n const doc = await client.fetch<DeployedDefinition | null>(definitionLookupGroq(false), {\n definition,\n tag,\n })\n return doc ?? undefined\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 */\nasync function loadDefinitionVersions({\n client,\n definition,\n tag,\n}: {\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/**\n * {@link loadDefinitionVersions}, but throws {@link DefinitionNotFoundError}\n * when nothing is deployed for `definition` under `tag` — the same error\n * {@link loadDefinition} throws, so the two can't drift. The shared guard for\n * the verbs that require at least one version (delete, definition-level\n * guard housekeeping).\n */\nexport async function loadDefinitionVersionsOrThrow({\n client,\n definition,\n tag,\n}: {\n client: WorkflowClient\n definition: string\n tag: string\n}): Promise<DeployedDefinition[]> {\n const versions = await loadDefinitionVersions({client, definition, tag})\n if (versions.length === 0) {\n throw new DefinitionNotFoundError({definition})\n }\n return versions\n}\n\n/** A definition as fetched back from the lake. The document carries `_id` plus\n * the deploy-stamped envelope the authored {@link WorkflowDefinition} never\n * had: the assigned `version` and the content fingerprint it was minted from\n * ({@link hashDefinitionContent}). A pre-fingerprint document may lack\n * `contentHash` at runtime — see {@link LatestDeployed}. */\nexport type DeployedDefinition = WorkflowDefinition & {\n _id: string\n tag?: string\n version: number\n /** Optional: a document deployed before content-addressing has none — see\n * {@link LatestDeployed}. Every version this engine deploys carries one. */\n contentHash?: string\n}\n","import {retractStageGuards} from '../guards-lifecycle.ts'\nimport {randomKey} from '../keys.ts'\nimport type {Actor} from '../types/actor.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {StageName} from '../types/ids.ts'\nimport {findOpenStageEntry} from '../types/instance-state.ts'\nimport {type EngineContext, findStage, loadCallContext} 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), activity 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 loadCallContext({client, instanceId, options})\n return commitAbort({ctx, reason, actor: options?.actor})\n}\n\nasync function commitAbort({\n ctx,\n reason,\n actor,\n}: {\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","// 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, Activity, Transition, WorkflowDefinition} from '../define/schema.ts'\nimport type {Actor} from './actor.ts'\nimport type {DeniedGuardRef} from './authorization.ts'\nimport type {FieldScope, ActivityKind, ActivityStatus, TerminalActivityStatus} from './enums.ts'\nimport {WorkflowError} from './errors.ts'\nimport type {FieldKind} from './field-values.ts'\nimport type {ActionName, StageName, ActivityName} from './ids.ts'\nimport type {WorkflowInstance} from './instance.ts'\n\n/**\n * Why an action is disabled for this actor right now — the read-side verdict.\n *\n * Verdict↔exception mapping (what `fireAction` throws when the verdict says\n * no): the `mutation-guard-denied` arm escalates to\n * {@link MutationGuardDeniedError} — the one guard-denial error, shared by\n * every verb; every other arm is thrown as {@link ActionDisabledError}\n * carrying the verdict as `reason`. The edit seam mirrors this: see\n * {@link EditDisabledReason} and {@link EditFieldDeniedError}.\n */\nexport type DisabledReason =\n | {\n /**\n * The action's condition evaluated falsy for this actor — the ONE\n * engine-side gate (advisory, like every engine check). Sugar like\n * `roles` desugared into this condition, so a role miss surfaces\n * here too.\n */\n kind: 'filter-failed'\n filter: string\n detail?: string\n }\n | {\n kind: 'activity-not-active'\n status: TerminalActivityStatus\n }\n | {kind: 'stage-terminal'; stage: StageName}\n | {\n /**\n * A deployed mutation guard denies the instance write every action\n * commit performs. Advisory pre-flight — the engine's optimistic\n * evaluation; `denied` is the same {@link DeniedGuardRef} shape the\n * thrown {@link MutationGuardDeniedError} carries.\n */\n kind: 'mutation-guard-denied'\n denied: DeniedGuardRef[]\n }\n | {kind: 'instance-completed'; completedAt: string}\n | {\n /**\n * The activity's declared {@link Activity.requirements} aren't all satisfied —\n * the readiness axis. The activity 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\n/** The `mutation-guard-denied` verdict arm, shared verbatim by\n * {@link DisabledReason} and {@link EditDisabledReason}. */\nexport type MutationGuardDenial = Extract<DisabledReason, {kind: 'mutation-guard-denied'}>\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 field can't be edited by this actor right now — the edit-seam\n * twin of {@link DisabledReason}. First failing gate wins: the field must be\n * declared editable, its scope window open, no deployed guard denying the\n * instance 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 field's scope window is closed: an activity-scope field whose activity isn't\n * active, or otherwise out of its editable window. */\n kind: 'edit-window-closed'\n detail: string\n }\n | {\n /** The field'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 | MutationGuardDenial\n\n/**\n * One declared-editable field 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 field-component work).\n */\nexport interface EditableFieldEvaluation {\n scope: FieldScope\n /** Present iff `scope === \"activity\"`. */\n activity?: ActivityName\n name: string\n type: FieldKind\n title?: string\n /** Current resolved value; `undefined` until the field is first resolved. */\n value: unknown\n /** Whether THIS actor may edit the field right now (window + predicate + guard). */\n editable: boolean\n /** Present iff `editable === false`. */\n disabledReason?: EditDisabledReason\n /** Actor who last wrote the field (latest `opApplied`); absent if never written. */\n setBy?: Actor\n /** When the field was last written (ISO); absent if never written. */\n setAt?: string\n}\n\nexport interface ActivityEvaluation {\n activity: Activity\n status: ActivityStatus\n /**\n * The activity's effective {@link ActivityKind} — the explicit {@link Activity.kind}, or\n * the shape-derived default when omitted. Advisory: a label so a consumer can\n * render each activity as what it is (`user` / `service` / `script` / `manual` / `receive`).\n */\n kind: ActivityKind\n /** Whether this activity is the current actor's responsibility right now. */\n pendingOnActor: boolean\n /**\n * The activity's unmet {@link Activity.requirements}, by name — present iff at least\n * one is unmet. The activity's own readiness summary: a consumer can explain why\n * the whole activity 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 activities: ActivityEvaluation[]\n transitions: TransitionEvaluation[]\n}\n\nexport interface WorkflowEvaluation {\n instance: WorkflowInstance\n definition: WorkflowDefinition\n actor: Actor\n currentStage: StageEvaluation\n /** Active activities whose assignees-kind field entry matches the actor. */\n pendingOnYou: ActivityEvaluation[]\n /** True if at least one action on any active activity is allowed. */\n canInteract: boolean\n /**\n * Declared-editable fields in the current scope (workflow + current stage +\n * its activities), 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 fields.\n */\n editableFields: EditableFieldEvaluation[]\n}\n\n/** The verdicts {@link ActionDisabledError} can carry — every {@link DisabledReason}\n * except `mutation-guard-denied`, which escalates to {@link MutationGuardDeniedError}. */\nexport type ActionDisabledReason = Exclude<DisabledReason, {kind: 'mutation-guard-denied'}>\n\n/** The verdicts {@link EditFieldDeniedError} can carry — every {@link EditDisabledReason}\n * except `mutation-guard-denied`, which escalates to {@link MutationGuardDeniedError}. */\nexport type EditFieldDeniedReason = Exclude<EditDisabledReason, {kind: 'mutation-guard-denied'}>\n\n/**\n * Thrown by `fireAction` when the requested action's verdict is\n * `allowed: false` for any reason other than a guard denial (that one is\n * {@link MutationGuardDeniedError} across all verbs). Carries the structured\n * verdict so UIs render the same reason they would have shown on the\n * disabled control, instead of parsing a string.\n */\nexport class ActionDisabledError extends WorkflowError<'action-disabled'> {\n readonly reason: ActionDisabledReason\n readonly activity: ActivityName\n readonly action: ActionName\n\n constructor(args: {activity: ActivityName; action: ActionName; reason: ActionDisabledReason}) {\n super(\n 'action-disabled',\n formatDisabledReason({activity: args.activity, action: args.action, reason: args.reason}),\n )\n this.name = 'ActionDisabledError'\n this.reason = args.reason\n this.activity = args.activity\n this.action = args.action\n }\n}\n\ntype DisabledReasonDetail = {\n [K in ActionDisabledReason['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 'activity-not-active': (r) => `activity status is \"${r.status}\"`,\n 'stage-terminal': (r) => `stage \"${r.stage}\" is terminal`,\n 'instance-completed': (r) => `instance completed at ${r.completedAt}`,\n 'requirements-unmet': (r) => `unmet requirement(s): ${r.unmetRequirements.join(', ')}`,\n}\n\nfunction formatDisabledReason({\n activity,\n action,\n reason,\n}: {\n activity: ActivityName\n action: ActionName\n reason: ActionDisabledReason\n}): string {\n const detail = (disabledReasonDetail[reason.kind] as (r: ActionDisabledReason) => string)(reason)\n return `Action \"${activity}:${action}\" is not allowed: ${detail}`\n}\n\n/** Edit-seam twin of {@link ActionDisabledError}: thrown by `editField` when\n * the field can't be edited by the caller — except a guard denial, which is\n * {@link MutationGuardDeniedError} across all verbs. Carries the structured reason. */\nexport class EditFieldDeniedError extends WorkflowError<'edit-field-denied'> {\n readonly reason: EditFieldDeniedReason\n readonly target: {scope: FieldScope; field: string; activity?: string}\n\n constructor(args: {\n target: {scope: FieldScope; field: string; activity?: string}\n reason: EditFieldDeniedReason\n }) {\n super('edit-field-denied', formatEditDisabledReason(args.target, args.reason))\n this.name = 'EditFieldDeniedError'\n this.reason = args.reason\n this.target = args.target\n }\n}\n\ntype EditDisabledReasonDetail = {\n [K in EditFieldDeniedReason['kind']]: (reason: Extract<EditDisabledReason, {kind: K}>) => string\n}\n\nconst editDisabledReasonDetail: EditDisabledReasonDetail = {\n 'not-editable': () => 'field 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}\n\nfunction formatEditDisabledReason(\n target: {scope: FieldScope; field: string; activity?: string},\n reason: EditFieldDeniedReason,\n): string {\n const detail = (editDisabledReasonDetail[reason.kind] as (r: EditFieldDeniedReason) => string)(\n reason,\n )\n const where = target.activity !== undefined ? `${target.activity}.${target.field}` : target.field\n return `Field \"${target.scope}:${where}\" is not editable: ${detail}`\n}\n","import {driverKind} from '../activity-kind.ts'\nimport {selfGdr} from '../core/refs.ts'\nimport type {Action, Stage, Activity} from '../define/schema.ts'\nimport {advisoryCan} from '../evaluate.ts'\nimport {randomKey} from '../keys.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport {type ActivityStatus, isTerminalActivityStatus} from '../types/enums.ts'\nimport {ContractViolationError} from '../types/errors.ts'\nimport {ActionDisabledError} from '../types/evaluation.ts'\nimport type {ActivityName} from '../types/ids.ts'\nimport {ctxEvaluateCondition, type EngineContext, retryOnRevisionConflict} from './context.ts'\nimport {queueEffects} from './effects.ts'\nimport {\n findCurrentActivities,\n findActivityInCurrentStage,\n requireMutationActivityEntry,\n startMutation,\n} from './mutation.ts'\nimport {isFieldOp, runOps, validateActionParams} from './ops.ts'\nimport {persistThenMaybeRefresh} from './persist-deploy.ts'\nimport {\n type ActionResult,\n CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS,\n ConcurrentFireActionError,\n type EngineCallOptions,\n} from './results.ts'\n\n/**\n * Fire an action against an active activity. The action's whole behaviour is\n * its ops + effects — activity 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`, `$fields`, …). Hard enforcement lives outside\n * the engine; everything checked 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 activity\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 activity the winning writer already completed\n * fails with the normal \"activity must be active\" error rather than retrying.\n */\nexport async function fireAction(args: {\n client: WorkflowClient\n instanceId: string\n activity: ActivityName\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, activity, action, params, options} = args\n return retryOnRevisionConflict({\n client,\n instanceId,\n options,\n commit: (ctx) =>\n commitAction({\n ctx,\n activityName: activity,\n actionName: action,\n callerParams: params,\n options,\n }),\n onExhausted: () =>\n new ConcurrentFireActionError({\n instanceId,\n activity,\n action,\n attempts: CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS,\n }),\n })\n}\n\n/**\n * Resolve and gate an action fire: locate the activity + action in the\n * current stage, evaluate the action's condition with the caller bound\n * (`$actor` / `$assigned`), require the live activity entry to be `active`,\n * and validate caller params. Throws on any failure so no mutation begins.\n */\nasync function resolveActionCommit({\n ctx,\n activityName,\n actionName,\n callerParams,\n options,\n}: {\n ctx: EngineContext\n activityName: ActivityName\n actionName: string\n callerParams: Record<string, unknown> | undefined\n options: EngineCallOptions | undefined\n}): Promise<{stage: Stage; activity: Activity; action: Action; params: Record<string, unknown>}> {\n const actor = options?.actor\n const {stage, activity} = findActivityInCurrentStage(ctx, activityName)\n const action = (activity.actions ?? []).find((a) => a.name === actionName)\n if (action === undefined) {\n throw new ContractViolationError(\n `Action \"${actionName}\" not declared on activity \"${activityName}\"`,\n )\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 if (action.filter !== undefined) {\n const can =\n options?.grants !== undefined && actor !== undefined\n ? await advisoryCan({instance: ctx.instance, actor, grants: options.grants})\n : undefined\n const filterOk = await ctxEvaluateCondition({\n ctx,\n condition: action.filter,\n opts: {\n activityName,\n ...(actor !== undefined ? {actor} : {}),\n ...(can !== undefined ? {vars: {can}} : {}),\n },\n })\n if (!filterOk) {\n // The commit re-check of the soft-gate's `filter-failed` verdict — a\n // caller racing a state change sees the same typed error either way.\n throw new ActionDisabledError({\n activity: activityName,\n action: actionName,\n reason: {kind: 'filter-failed', filter: action.filter, detail: 'commit re-check'},\n })\n }\n }\n\n const entry = findCurrentActivities(ctx.instance).find((t) => t.name === activityName)\n if (entry === undefined || entry.status !== 'active') {\n throw notActiveAtCommit({activityName, actionName, status: entry?.status})\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, activityName, callerParams})\n return {stage, activity, action, params}\n}\n\n/**\n * The commit re-check of the soft-gate's `activity-not-active` verdict. A\n * terminal status is caller-reachable (the activity resolved between evaluate\n * and commit) and gets the same typed error the soft-gate throws; `pending` /\n * missing are internal invariants — the public verb auto-invokes pending\n * activities and rejects undeclared ones before this point — so they stay a\n * plain invariant `Error`.\n */\nfunction notActiveAtCommit(args: {\n activityName: ActivityName\n actionName: string\n status: ActivityStatus | undefined\n}): Error {\n const {activityName, actionName, status} = args\n if (status !== undefined && isTerminalActivityStatus(status)) {\n return new ActionDisabledError({\n activity: activityName,\n action: actionName,\n reason: {kind: 'activity-not-active', status},\n })\n }\n return new Error(\n `Activity \"${activityName}\" must be active to fire action \"${actionName}\"; status is ${status ?? 'missing'}`,\n )\n}\n\nasync function commitAction({\n ctx,\n activityName,\n actionName,\n callerParams,\n options,\n}: {\n ctx: EngineContext\n activityName: ActivityName\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 activityName,\n actionName,\n callerParams,\n options,\n })\n\n const mutation = startMutation(ctx.instance)\n const mutEntry = requireMutationActivityEntry(mutation, activityName)\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 activity: activityName,\n action: actionName,\n ...(actor !== undefined ? {actor, driverKind: driverKind(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. Activity 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: {activity: activityName, 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({\n ctx,\n mutation,\n effects: action.effects,\n origin: {kind: 'action', name: actionName},\n actor,\n opts: {callerParams: params, activityName},\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 field op ran). A\n // failed refresh rolls the commit back rather than leaving guards stale.\n await persistThenMaybeRefresh({\n ctx,\n mutation,\n stageName: stage.name,\n didChangeState: ranOps.some(isFieldOp),\n })\n\n return {\n fired: true,\n activity: activityName,\n action: actionName,\n ...(newStatus !== undefined ? {newStatus} : {}),\n ...(ranOps.length > 0 ? {ranOps} : {}),\n }\n}\n","import {\n editDisabledReason,\n resolveEditTarget,\n type ResolvedFieldSite,\n fieldWindowOpen,\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 {FieldScope} from '../types/enums.ts'\nimport {ContractViolationError} from '../types/errors.ts'\nimport {EditFieldDeniedError} from '../types/evaluation.ts'\nimport {\n ctxEvaluateCondition,\n type EngineContext,\n findStage,\n retryOnRevisionConflict,\n} from './context.ts'\nimport {startMutation} from './mutation.ts'\nimport {isFieldOp, runOps} from './ops.ts'\nimport {persistThenMaybeRefresh} from './persist-deploy.ts'\nimport {\n CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS,\n ConcurrentEditFieldError,\n type EditFieldResult,\n type EngineCallOptions,\n} from './results.ts'\n\n/**\n * The generic edit seam. `editField` writes a declared-editable\n * field 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 `field.*` op through the shared op path (so it stamps `opApplied`\n * provenance + history), gates on the field'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 field's\n * effective `editable` predicate over the rendered scope.\n */\nexport type EditMode = 'set' | 'append' | 'unset'\n\nexport interface EditFieldTarget {\n /** Omit to resolve lexically (activity field if `activity` set, else stage then workflow). */\n scope?: FieldScope\n field: string\n /** Required to address an activity-scope field. */\n activity?: 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 field — throws immediately, before any mutation.\n */\nexport async function editField(args: {\n client: WorkflowClient\n instanceId: string\n target: EditFieldTarget\n mode?: EditMode\n value?: unknown\n options?: EngineCallOptions\n}): Promise<EditFieldResult> {\n const {client, instanceId, target, mode = 'set', value, options} = args\n return retryOnRevisionConflict({\n client,\n instanceId,\n options,\n commit: (ctx) => commitEdit({ctx, target, mode, value, options}),\n onExhausted: () =>\n new ConcurrentEditFieldError({\n instanceId,\n target: labelTarget(target),\n attempts: CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS,\n }),\n })\n}\n\nasync function commitEdit({\n ctx,\n target,\n mode,\n value,\n options,\n}: {\n ctx: EngineContext\n target: EditFieldTarget\n mode: EditMode\n value: unknown\n options: EngineCallOptions | undefined\n}): Promise<EditFieldResult> {\n const actor = options?.actor\n const stage = findStage(ctx.definition, ctx.instance.currentStage)\n const site = resolveEditTarget({definition: ctx.definition, stage, target})\n if (site === undefined) {\n throw new ContractViolationError(\n `No field \"${describeTarget(target)}\" resolves in current stage \"${stage.name}\" of ${ctx.definition.name}`,\n )\n }\n await assertFieldEditable({ctx, site, options})\n\n const op = buildEditOp({site, mode, value})\n const mutation = startMutation(ctx.instance)\n const ranOps = await runOps({\n ops: [op],\n mutation,\n stage: stage.name,\n origin: {\n edit: true,\n ...(site.scope === 'activity' && site.activity !== undefined\n ? {activity: site.activity}\n : {}),\n },\n params: {},\n actor,\n self: selfGdr(ctx.instance),\n now: ctx.now,\n })\n\n // An edit can change a field 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 persistThenMaybeRefresh({\n ctx,\n mutation,\n stageName: stage.name,\n didChangeState: ranOps.some(isFieldOp),\n })\n\n return {\n edited: true,\n target: fieldTarget(site),\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 EditFieldDeniedError} 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 assertFieldEditable({\n ctx,\n site,\n options,\n}: {\n ctx: EngineContext\n site: ResolvedFieldSite\n options: EngineCallOptions | undefined\n}): Promise<void> {\n const actor = options?.actor\n const window = fieldWindowOpen(ctx.instance, site)\n const can =\n options?.grants !== undefined && actor !== undefined\n ? await advisoryCan({instance: ctx.instance, actor, grants: options.grants})\n : undefined\n const predicateSatisfied =\n window.open && site.effective !== true && site.effective !== undefined\n ? await ctxEvaluateCondition({\n ctx,\n condition: site.effective,\n opts: {\n ...(site.activity !== undefined ? {activityName: site.activity} : {}),\n ...(actor !== undefined ? {actor} : {}),\n ...(can !== undefined ? {vars: {can}} : {}),\n },\n })\n : site.effective === true\n const reason = editDisabledReason({\n effective: site.effective,\n instance: ctx.instance,\n window,\n guardDenial: undefined,\n predicateSatisfied,\n })\n if (reason !== undefined) throw new EditFieldDeniedError({target: fieldTarget(site), reason})\n}\n\nfunction buildEditOp({\n site,\n mode,\n value,\n}: {\n site: ResolvedFieldSite\n mode: EditMode\n value: unknown\n}): Op {\n if (mode === 'unset') return {type: 'field.unset', target: site.ref}\n if (value === undefined) {\n throw new ContractViolationError(\n `editField mode \"${mode}\" requires a value for field \"${site.name}\"`,\n )\n }\n return {\n type: mode === 'append' ? 'field.append' : 'field.set',\n target: site.ref,\n value: {type: 'literal', value},\n }\n}\n\nfunction fieldTarget(site: ResolvedFieldSite): {\n scope: FieldScope\n field: string\n activity?: string\n} {\n return {\n scope: site.scope,\n field: site.name,\n ...(site.activity !== undefined ? {activity: site.activity} : {}),\n }\n}\n\nfunction labelTarget(target: EditFieldTarget): {\n scope: FieldScope\n field: string\n activity?: string\n} {\n return {\n scope: target.scope ?? (target.activity !== undefined ? 'activity' : 'workflow'),\n field: target.field,\n ...(target.activity !== undefined ? {activity: target.activity} : {}),\n }\n}\n\nfunction describeTarget(target: EditFieldTarget): string {\n const where = target.activity !== undefined ? `${target.activity}.${target.field}` : target.field\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 {invokeActivity as engineInvokeActivity} from '../engine/activities.ts'\nimport {cascadeAutoTransitions, propagateToAncestors} from '../engine/cascade.ts'\nimport {editField as engineEditField, type EditMode, type EditFieldTarget} from '../engine/edit.ts'\nimport type {EngineCallOptions, OpAppliedSummary} from '../engine/results.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, MutationGuardDeniedError} from '../types/authorization.ts'\nimport type {WorkflowClient} from '../types/client.ts'\nimport type {EffectsContextEntry} from '../types/effects.ts'\nimport {\n ActionDisabledError,\n EditFieldDeniedError,\n type MutationGuardDenial,\n type WorkflowEvaluation,\n} from '../types/evaluation.ts'\nimport {findCurrentActivityEntry} from '../types/instance-state.ts'\nimport type {WorkflowInstance} from '../types/instance.ts'\nimport type {OperationResult, 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,\n instanceId,\n actor,\n clientForGdr,\n clock,\n overlay,\n}: {\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 !== undefined ? {clientForGdr} : {}),\n ...(clock !== undefined ? {clock} : {}),\n ...(overlay !== undefined ? {overlay} : {}),\n })\n await propagateToAncestors({\n client,\n instanceId,\n actor,\n ...(clientForGdr !== undefined ? {clientForGdr} : {}),\n ...(clock !== undefined ? {clock} : {}),\n })\n return count\n}\n\n/**\n * Assemble the {@link EngineCallOptions} an operation hands to an engine verb:\n * the actor (omitted when undefined so a `$can`-gated condition stays unbound\n * rather than seeing a stamped-but-empty actor), plus the operation's shared\n * clock and cross-resource router. Distinct from `buildEngineCallOptions`,\n * which binds the actor unconditionally and also carries grants.\n */\nexport function engineOptionsForActor({\n actor,\n clock,\n clientForGdr,\n}: {\n actor: Actor | undefined\n clock: Clock\n clientForGdr: (parsed: ParsedGdr) => WorkflowClient\n}): EngineCallOptions {\n return {...(actor !== undefined ? {actor} : {}), clock, clientForGdr}\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: engineOptionsForActor({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`, `editField`):\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 OperationResult}. 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<OperationResult> {\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({\n client,\n instanceId,\n actor: args.actor,\n clientForGdr: args.clientForGdr,\n clock: args.clock,\n })\n return {\n instance: await reload({client, instanceId, tag}),\n cascaded,\n changed: true,\n ...(ranOps !== undefined ? {ranOps} : {}),\n }\n}\n\n/**\n * Escalate a `mutation-guard-denied` verdict to the ONE guard-denial error:\n * whatever verb the denial surfaced on, the caller catches\n * {@link MutationGuardDeniedError} for the instance-doc `update` the commit\n * would have performed.\n */\nfunction guardDeniedError(\n instanceId: string,\n reason: MutationGuardDenial,\n): MutationGuardDeniedError {\n return new MutationGuardDeniedError({\n documentId: instanceId,\n action: 'update',\n denied: reason.denied,\n })\n}\n\n/**\n * Soft-gate before any action write: throw {@link MutationGuardDeniedError}\n * when a deployed mutation guard denies the commit's instance write,\n * otherwise {@link ActionDisabledError} if the evaluation says the action is\n * disabled. Real enforcement lives in the lake; this surfaces a structured\n * `reason` to the caller first.\n */\nexport function assertActionAllowed({\n evaluation,\n activity,\n action,\n}: {\n evaluation: WorkflowEvaluation\n activity: string\n action: string\n}): void {\n const actionEval = evaluation.currentStage.activities\n .find((t) => t.activity.name === activity)\n ?.actions.find((a) => a.action.name === action)\n if (actionEval?.allowed === false && actionEval.disabledReason) {\n const reason = actionEval.disabledReason\n if (reason.kind === 'mutation-guard-denied') {\n throw guardDeniedError(evaluation.instance._id, reason)\n }\n throw new ActionDisabledError({activity, action, reason})\n }\n}\n\n/**\n * Soft-gate before an edit write: throw {@link MutationGuardDeniedError} when\n * a deployed mutation guard denies the commit's instance write, otherwise\n * {@link EditFieldDeniedError} if the projection says the targeted field can't\n * be edited by the caller. Mirrors {@link assertActionAllowed} — real\n * enforcement lives in the lake; this surfaces a structured reason first.\n * Silent when no projected field matches (the field is undeclared / not\n * editable): the engine commit raises the precise error.\n */\nexport function assertEditAllowed(evaluation: WorkflowEvaluation, target: EditFieldTarget): void {\n const field = evaluation.editableFields\n .filter((s) => editTargetMatches(s, target))\n .sort((a, b) => SCOPE_PRECEDENCE[a.scope] - SCOPE_PRECEDENCE[b.scope])[0]\n if (field !== undefined && !field.editable && field.disabledReason !== undefined) {\n const reason = field.disabledReason\n if (reason.kind === 'mutation-guard-denied') {\n throw guardDeniedError(evaluation.instance._id, reason)\n }\n throw new EditFieldDeniedError({\n target: {\n scope: field.scope,\n field: field.name,\n ...(field.activity !== undefined ? {activity: field.activity} : {}),\n },\n reason,\n })\n }\n}\n\n/**\n * Edit a declared-editable field 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: EditFieldTarget\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 engineEditField>>['ranOps']> {\n const {client, instance, target, mode, value, actor, grants, clock, clientForGdr} = args\n const result = await engineEditField({\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 activity if it's still pending, then fire the action. Both the\n * `pending` check ({@link findCurrentActivityEntry}) 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 activity: 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, activity, action, params, actor, grants, clock, clientForGdr} = args\n const options = buildEngineCallOptions({actor, grants, clock, clientForGdr})\n const pending = findCurrentActivityEntry(instance, activity)?.status === 'pending'\n if (pending) {\n await engineInvokeActivity({client, instanceId: instance._id, activity, options})\n }\n const result = await engineFireAction({\n client,\n instanceId: instance._id,\n activity,\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 * (`activity.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 {DefinitionInUseError, DefinitionNotFoundError} from '../types/errors.ts'\nimport {WORKFLOW_INSTANCE_TYPE} from '../types/instance.ts'\nimport {type DeployedDefinition, loadDefinitionVersionsOrThrow, refsOf} from './deploy.ts'\nimport {abortAndPropagate, resolveOperationContext} from './operations.ts'\nimport type {DeleteDefinitionArgs, DeleteDefinitionResult, EngineScopeArgs} 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 & EngineScopeArgs>,\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 loadDefinitionVersionsOrThrow({client, definition, tag})\n const targets = version === undefined ? versions : versions.filter((d) => d.version === version)\n if (targets.length === 0) {\n // Only reachable with an explicit unknown `version`: with none, targets\n // is the non-empty list loadDefinitionVersionsOrThrow just returned.\n throw new DefinitionNotFoundError({\n definition,\n ...(version !== undefined ? {version} : {}),\n })\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 DefinitionInUseError({\n definition,\n blockedBy: {reason: 'non-terminal-instances', instanceIds},\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,\n tag,\n definition,\n targets,\n lastVersionGoes,\n}: {\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 throw new DefinitionInUseError({\n definition,\n blockedBy: {\n reason: 'spawn-referrers',\n referrers: referrers.map((d) => ({definition: d.name, version: d.version})),\n },\n })\n }\n}\n\n/** Ids of in-flight instances the delete must abort (or refuse over). */\nasync function nonTerminalInstanceIds({\n client,\n tag,\n definition,\n version,\n}: {\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","/**\n * The workflow API — one coherent SDK surface.\n *\n * The write path is a small set of verbs:\n *\n * - **`deployDefinitions`** — once at deploy time. Persists definitions,\n * immutable and content-addressed.\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 activities. Runtimes fire actions on activities in response\n * to webhooks, timer firings, etc. External signals funnel through\n * this; nothing else.\n * - **`editField`** — direct edit of a declared-editable field,\n * through the one generic edit seam instead of a bespoke action per\n * field.\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 — and optionally `ops` (the state half of the effect):\n * `field.*` applied to the instance in the same commit.\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 * Around those: admin overrides (`setStage`, `abortInstance`,\n * `deleteDefinition`), pure reads (evaluation and diagnosis, instance\n * and child lookups, guard and pending-effect listings, scoped GROQ),\n * and the `permissions` helpers. Each member's own doc is the\n * contract; this list is orientation, not an inventory.\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 an activity whose action\n * resolves it `done` and writes a cancellation field, plus an\n * auto-transition filtered on that field (cancelling is a decision, not a\n * failure). Same audit trail as everything else; same mechanism.\n * - No `setContext`. `effectsContext` is set at start, then mutated\n * only by completed effects' `outputs`. External signals belong on\n * activities (via `fireAction`) or in the lake (as document mutations\n * that filters can read).\n * - No `invokeActivity`. Activities auto-activate on stage entry. Editor's first\n * `fireAction` against a pending activity auto-invokes it before\n * applying the action.\n *\n * What filters can read:\n *\n * - Activity state on the instance (`*[_id == $self][0].stages[id == $stage && !defined(exitedAt)][0].activities[...]`)\n * - Document content in the lake (`*[_type == \"...\" && ...]`)\n * - Reserved params: {@link FILTER_SCOPE_VARS} — the caller-free subset of\n * the {@link CONDITION_VARS} inventory.\n *\n * What filters must NOT read:\n *\n * - `effectsContext` (the `$effects` var). That field is for effect handler\n * params only; observe a drained effect through `$effectStatus` instead.\n *\n * The boundary keeps each thing doing one job: activities are workflow state,\n * the lake is content state, effectsContext is handler fuel.\n */\n\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 {\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 {recordFieldDiscards} from '../engine/history-entries.ts'\nimport {setStage as engineSetStage} from '../engine/stages.ts'\nimport {type EvaluateArgs, evaluateInstance} from '../evaluate.ts'\nimport {derivePerspectiveFromFields, resolveDeclaredFields} from '../field-resolution.ts'\nimport {\n guardsForDefinition as queryGuardsForDefinition,\n guardsForInstance as queryGuardsForInstance,\n verdictGuardsForInstance,\n} from '../guards-query.ts'\nimport {buildInstanceBase, reload} from '../instance.ts'\nimport {instancesQuery} from '../instances-query.ts'\nimport {instanceDocId, 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 {instanceWatchesDocument} from '../subscription-documents.ts'\nimport {tagScopeFilter, validateTag} from '../tags.ts'\nimport type {MutationGuardDoc} from '../types/authorization.ts'\nimport {SYNC_COMMIT} from '../types/client.ts'\nimport type {PendingEffect} from '../types/effects.ts'\nimport {ContractViolationError} from '../types/errors.ts'\nimport type {WorkflowEvaluation} from '../types/evaluation.ts'\nimport type {HistoryEntry} from '../types/history.ts'\nimport {findCurrentActivityEntry} from '../types/instance-state.ts'\nimport {type WorkflowInstance} from '../types/instance.ts'\nimport {deleteDefinition as deleteDefinitionInternal} from './delete-definition.ts'\nimport {\n loadDefinition,\n loadDefinitionVersionsOrThrow,\n loadLatestDeployed,\n planDefinitionDeploy,\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 engineOptionsForActor,\n resolveOperationContext,\n toEffectsContextEntries,\n} from './operations.ts'\nimport type {\n AbortInstanceArgs,\n ChildrenArgs,\n CompleteEffectArgs,\n DeleteDefinitionArgs,\n DeleteDefinitionResult,\n DeployDefinitionResult,\n DeployDefinitionsArgs,\n DeployDefinitionsResult,\n EditFieldArgs,\n EngineScopeArgs,\n FindPendingEffectsArgs,\n FireActionArgs,\n GuardsForDefinitionArgs,\n InstanceRefArgs,\n InstancesForDocumentArgs,\n OperationArgs,\n OperationResult,\n QueryArgs,\n QueryInScopeArgs,\n SetStageArgs,\n StartInstanceArgs,\n} from './types.ts'\nimport {validateDefinition} from './validate.ts'\n\n/**\n * The workflow verbs, bound as one object — write path, admin\n * overrides, pure reads, and permission helpers. The module doc above\n * describes the model.\n */\nexport const workflow = {\n /**\n * Deploy a set of workflow definitions as one call. Definitions are\n * immutable and content-addressed: the author writes no version, and each\n * deploy compares a definition's content fingerprint to the latest version\n * already deployed under its name. Identical content is a no-op\n * (`unchanged`); any change mints the next version (`created`) — deploy\n * never patches a deployed version, so a definition can't change out from\n * under the instances pinned to it. `startInstance` picks the highest\n * version by default. The engine figures out the dependency order itself\n * (children before parents that spawn them via `subworkflows.definition`)\n * and reports a per-definition outcome (`created` / `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 (\n args: DeployDefinitionsArgs & EngineScopeArgs,\n ): Promise<DeployDefinitionsResult> => {\n const {client, tag, workflowResource, resourceAliases, definitions} = args\n validateTag(tag)\n\n // 1. Validate each definition's GROQ + structural invariants. Fail fast,\n // before we touch the lake.\n definitions.forEach(validateDefinition)\n\n // 2. Build the dependency graph and topologically sort\n // (children-before-parents). Also rejects a batch with duplicate\n // names — without an authored version, a name is the batch identity.\n // Spawn refs are by definition name, unaffected by alias expansion, so\n // the authored definitions sort the same as their expanded form.\n const ordered = await sortByDependencies({client, definitions, tag})\n\n // 3. Content-addressed, create-only deploy. planDefinitionDeploy expands\n // `@<alias>:` references to physical GDRs (failing closed on an unbound\n // alias) before fingerprinting, so the deployed, fingerprinted definition\n // holds physical references, never a logical alias — and a `definition\n // diff` lines up exactly. For each definition compare its content\n // fingerprint to the latest deployed version: identical ⇒ no-op; any\n // change ⇒ create the next version. Deploy NEVER patches a deployed\n // version — that would mutate the definition out from under instances\n // pinned to it. Every create lands in one transaction; a colliding `_id`\n // (a concurrent deploy minted the same version) fails the whole batch\n // rather than clobbering.\n const results: DeployDefinitionResult[] = []\n const tx = client.transaction()\n let hasWrites = false\n for (const def of ordered) {\n const latest = await loadLatestDeployed({client, definition: def.name, tag})\n const plan = planDefinitionDeploy({\n def,\n latest,\n target: {\n tag,\n workflowResource,\n ...(resourceAliases !== undefined ? {resourceAliases} : {}),\n },\n })\n if (plan.status === 'unchanged') {\n results.push({name: def.name, version: plan.version, status: 'unchanged'})\n continue\n }\n tx.create(plan.document)\n hasWrites = true\n results.push({name: def.name, version: plan.version, status: 'created'})\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 & EngineScopeArgs>,\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 activityStatus, queues onEnter\n * effects, auto-activates activities). Then cascades auto-transitions\n * until stable. Starting always changes state (`changed: true`) —\n * `cascaded` reports how far the new instance auto-advanced.\n */\n startInstance: async (\n args: Clocked<StartInstanceArgs & EngineScopeArgs>,\n ): Promise<OperationResult> => {\n const {\n client,\n tag,\n workflowResource,\n definition: definitionName,\n version,\n initialFields,\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, definition: definitionName, version, tag})\n const id = instanceId ?? instanceDocId(tag)\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 field entries resolve in declaration order. Later\n // entries can read earlier ones via `$fields.<name>` in their GROQ.\n // There's no privileged entry name — `$fields` exposes every\n // declared entry keyed by its author-chosen name.\n // Workflow-scope query-sourced fields can have their lake result discarded;\n // collect those audit rows to seed the new instance's history below.\n const fieldDiscards: HistoryEntry[] = []\n const resolvedFields = await resolveDeclaredFields({\n entryDefs: definition.fields ?? [],\n initialFields: initialFields ?? [],\n ctx: {\n client,\n now,\n selfId: id,\n tag,\n workflowResource,\n definitionName: definition.name,\n ...(perspective !== undefined ? {perspective} : {}),\n recordDiscard: recordFieldDiscards({target: fieldDiscards, scope: 'workflow', at: now}),\n },\n randomKey,\n })\n\n // Perspective resolution: an explicit `perspective` arg wins;\n // otherwise derive it from a populated `release.ref` field entry. This is\n // what makes a release-targeting workflow self-describing — the\n // caller fills the field entry and the engine figures out the read\n // perspective, rather than every caller having to pass it.\n const effectivePerspective = perspective ?? derivePerspectiveFromFields(resolvedFields)\n\n const base = buildInstanceBase({\n id,\n now,\n tag,\n workflowResource,\n definitionName: definition.name,\n pinnedVersion: definition.version,\n pinnedContentHash: definition.contentHash,\n definition,\n fields: resolvedFields,\n effectsContext: effectsContextEntries,\n ancestors: ancestors ?? [],\n perspective: effectivePerspective,\n initialStage: definition.initialStage,\n actor,\n ...(fieldDiscards.length > 0 ? {extraHistory: fieldDiscards} : {}),\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, instanceId: id, actor, clientForGdr, clock})\n const cascaded = await cascade({client, instanceId: id, actor, clientForGdr, clock})\n\n return {instance: await reload({client, instanceId: id, tag}), cascaded, changed: true}\n },\n\n /**\n * Fire an action against an activity. If the activity 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 & EngineScopeArgs>): Promise<OperationResult> => {\n const {\n client,\n tag,\n workflowResource,\n instanceId,\n activity,\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 activityEntry = findCurrentActivityEntry(before, activity)\n if (activityEntry === undefined && idempotent === true) {\n return {instance: before, cascaded: 0, changed: 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, activity, action})\n return applyAction({\n client,\n instance,\n activity,\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 field 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 field's declared\n * editability (the same projection a UI renders), applies the edit as a\n * `field.*` 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.\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 editField: async (args: Clocked<EditFieldArgs & EngineScopeArgs>): Promise<OperationResult> => {\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. Any `ops` the handler returned (`field.*`) are\n * validated and applied to the instance in the same commit, through the\n * same op applier an action's field ops use. Cascades after. A completion\n * always changes state (the effect drains + history is appended), so\n * `changed` is always `true` — a bad `effectKey`/status throws instead.\n */\n completeEffect: async (\n args: Clocked<CompleteEffectArgs & EngineScopeArgs>,\n ): Promise<OperationResult> => {\n const {client, tag, instanceId, effectKey, status, outputs, ops, detail, error, durationMs} =\n 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 ...(ops !== undefined ? {ops} : {}),\n ...(detail !== undefined ? {detail} : {}),\n ...(error !== undefined ? {error} : {}),\n ...(durationMs !== undefined ? {durationMs} : {}),\n options: engineOptionsForActor({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 changed: 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 an activity 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. `changed` reports\n * whether the nudge wrote anything: a fired transition, but also a\n * persisted activity-gate flip (`completeWhen`/`failWhen`) that didn't\n * unlock a transition yet — so it's derived from the instance's `_rev`,\n * not from `cascaded` alone.\n */\n tick: async (args: Clocked<OperationArgs & EngineScopeArgs>): Promise<OperationResult> => {\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 const instance = await reload({client, instanceId, tag})\n return {\n instance,\n cascaded,\n changed: instance._rev !== current._rev,\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. `changed: false`\n * means the move was a no-op (already at the target / terminal).\n */\n setStage: async (args: Clocked<SetStageArgs & EngineScopeArgs>): Promise<OperationResult> => {\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: engineOptionsForActor({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 changed: 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, so\n * `cascaded` is always `0`; ancestor movement is reported on the\n * ancestors, not here). `changed: false` means the instance was\n * already terminal.\n */\n abortInstance: async (\n args: Clocked<AbortInstanceArgs & EngineScopeArgs>,\n ): Promise<OperationResult> => {\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 changed = await abortAndPropagate({\n client,\n instanceId,\n reason,\n actor,\n clientForGdr,\n clock,\n })\n return {\n instance: await reload({client, instanceId, tag}),\n cascaded: 0,\n changed,\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: InstanceRefArgs & EngineScopeArgs): Promise<WorkflowInstance> => {\n const {client, tag, instanceId} = args\n validateTag(tag)\n return reload({client, instanceId, tag})\n },\n\n guardsForInstance: async (\n args: InstanceRefArgs & EngineScopeArgs,\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 (\n args: GuardsForDefinitionArgs & EngineScopeArgs,\n ): Promise<MutationGuardDoc[]> => {\n const {client, tag, workflowResource, definition, resourceClients} = args\n validateTag(tag)\n const definitions = await loadDefinitionVersionsOrThrow({client, definition, tag})\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: QueryArgs & EngineScopeArgs): 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 ContractViolationError(\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's instance-derived vars ({@link FILTER_SCOPE_VARS}) are\n * auto-bound — ids in GDR URI form to match 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<QueryInScopeArgs & EngineScopeArgs>,\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: InstanceRefArgs & EngineScopeArgs): Promise<PendingEffect[]> => {\n const inst = await reload({client: args.client, instanceId: args.instanceId, tag: 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 (\n args: FindPendingEffectsArgs & EngineScopeArgs,\n ): Promise<PendingEffect[]> => {\n const inst = await reload({client: args.client, instanceId: args.instanceId, tag: 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 & EngineScopeArgs>): 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 & EngineScopeArgs>): 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 * activities' actions. Returns the evaluation alongside the actions so a\n * consumer can read the instance/stage context. Pure read.\n */\n availableActions: async (\n args: Clocked<EvaluateArgs & EngineScopeArgs>,\n ): Promise<AvailableActionsResult> => {\n const evaluation = await evaluateInstance(args)\n return {evaluation, actions: availableActions(evaluation.currentStage.activities)}\n },\n\n /**\n * Materialised spawned children of a parent instance.\n *\n * Walks `history` for `spawned` events — the durable\n * record. (The per-activity `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 `activity` to restrict to a single spawning activity on the parent.\n */\n children: async (args: ChildrenArgs & EngineScopeArgs): Promise<WorkflowInstance[]> => {\n const {client, tag, instanceId, activity} = 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) => activity === undefined || h.activity === activity)\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 * Every in-flight instance whose reactive watch-set includes `document` —\n * the reverse of {@link subscriptionDocumentsForInstance}.\n *\n * For a non-reactive, content-change-driven runtime (a Sanity Function, an\n * Inngest/durable worker, any server) that holds no instances in memory: a\n * document changed; which instances should it `tick`? The watch-set covers\n * the instance itself, its ancestors, and the docs named by\n * `doc.ref` / `doc.refs` / `release.ref` field entries on the workflow scope\n * **and the current stage** — so a hand-rolled GROQ over `fields[]` gets it\n * subtly wrong (misses stage-scope refs, `release.ref`, ancestors).\n *\n * A coarse GROQ prefilter narrows candidates server-side (in-flight,\n * tag-scoped, mentioning the doc anywhere in state); the authoritative match\n * is {@link instanceWatchesDocument}, derived from `collectWatchRefs`, so the\n * reverse stays in lockstep with the forward set and honours the\n * open-stage-only rule the prefilter deliberately over-approximates.\n *\n * Single-resource: instances always live in the engine's own resource, so\n * this reads one client (unlike {@link guardsForInstance}, whose guard docs\n * are scattered across the watched resources). \"Routed by resource\" applies\n * to the **subject**: a cross-dataset doc is matched by its full,\n * resource-qualified GDR URI, never its bare id, so an instance watching\n * `dataset:A:ds:doc` is not matched by a change to `dataset:B:ds:doc`.\n *\n * `document` must be a resource-qualified GDR URI; a bare id is rejected\n * (it can't be resource-routed and would silently mismatch). Sorted by\n * `startedAt` ascending.\n */\n instancesForDocument: async (\n args: InstancesForDocumentArgs & EngineScopeArgs,\n ): Promise<WorkflowInstance[]> => {\n const {client, tag, document} = args\n const {query, params} = instancesQuery({tag, filter: {document}})\n const candidates = await client.fetch<WorkflowInstance[]>(query, params)\n return candidates.filter((instance) => instanceWatchesDocument(instance, document))\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. Deliberately namespace-only (not mirrored on\n * `Engine`): pure helpers that need none of the engine's pinned scope.\n */\n permissions: {\n matchesFilter: permMatchesFilter,\n grantsPermissionOn: permGrantsPermissionOn,\n fetchGrants: permFetchGrants,\n },\n}\n","import type {WorkflowAccessOverride} from '../access.ts'\nimport type {\n GdrUri,\n GlobalDocumentReference,\n ParsedGdr,\n ResourceAliases,\n WorkflowResource,\n} from '../core/refs.ts'\nimport type {FieldOp, WorkflowDefinition} from '../define/schema.ts'\nimport type {EditMode, EditFieldTarget} from '../engine/edit.ts'\nimport type {OpAppliedSummary} from '../engine/results.ts'\nimport type {WorkflowClient, WorkflowPerspective} from '../types/client.ts'\nimport type {PendingEffect} from '../types/effects.ts'\nimport {WorkflowError} from '../types/errors.ts'\nimport type {InitialFieldValue} from '../types/field-values.ts'\nimport type {WorkflowInstance} from '../types/instance.ts'\n\n// Public API surface\n//\n// Every verb's args type is the shape the `Engine` methods take — the scope\n// `createEngine` pins (client / tag / workflowResource / resourceClients) is\n// factored out into {@link EngineScopeArgs}. The raw `workflow.*` namespace\n// takes `<Verb>Args & EngineScopeArgs`, carrying that scope per call.\n\n/**\n * The engine-scope bindings pinned once by `createEngine` and carried\n * explicitly on every raw `workflow.*` call. `Engine` methods never take\n * these — they were supplied at construction.\n */\nexport interface EngineScopeArgs {\n client: WorkflowClient\n /** Engine-scope environment partition — required. See {@link validateTag} + `tags.ts`. */\n tag: string\n /**\n * The Sanity resource the engine's own data lives in. Used to mint\n * GDR URIs for every doc the engine writes (definitions, instances,\n * ancestor refs). Mirrors `@sanity/client`'s `ClientConfigResource`.\n */\n workflowResource: WorkflowResource\n /**\n * Optional routing for cross-resource reads (subject + ancestor docs that\n * live in a different Sanity resource than the workflow). Called with a\n * parsed GDR; return a client for that resource, or undefined to fall back\n * to `client`. Engine-scope configuration — see `CreateEngineArgs`.\n */\n resourceClients?: ResourceClientResolver\n}\n\nexport interface DeployDefinitionsArgs {\n /**\n * Resource-alias bindings for this deploy (alias name → physical resource).\n * Every `@<alias>:` reference in a definition is expanded to its bound\n * physical resource at deploy, so the deployed definition holds only physical\n * references. Deploy fails closed when a definition references an alias this\n * map doesn't bind. Omit for single-resource workflows (definitions that\n * reference no aliases).\n */\n resourceAliases?: ResourceAliases\n definitions: WorkflowDefinition[]\n}\n\nexport interface DeployDefinitionResult {\n /** The definition's `name`. */\n name: string\n /** The deploy-assigned version this deploy created or matched. */\n version: number\n status: 'created' | 'unchanged'\n}\n\nexport interface DeleteDefinitionArgs {\n /** The definition's `name` — delete addresses the workflow, not a doc id. */\n definition: string\n /** Delete only this deployed version. Default: every deployed version. */\n version?: number\n /**\n * Abort every non-terminal instance pinned to the targeted versions\n * before deleting. Instances are ONLY aborted — instance documents are\n * never deleted; they stay in the lake as the audit record. Without\n * this flag the delete refuses when such instances exist.\n */\n cascade?: boolean\n /** Free-text reason stamped on each cascade-abort history entry. */\n reason?: string\n /** Optional access-state override — see `StartInstanceArgs.access`. */\n access?: WorkflowAccessOverride\n /** URL path for grant resolution — see `StartInstanceArgs.grantsFromPath`. */\n grantsFromPath?: string\n}\n\nexport interface DeleteDefinitionResult {\n /** The definition's `name`. */\n name: string\n /** Versions actually removed, newest first. */\n deletedVersions: number[]\n /** Instances hard-stopped by `cascade`, in abort order. Empty without it. */\n abortedInstanceIds: string[]\n /**\n * Orphaned guard docs removed across the definition's statically-named\n * datasources. Only populated when the LAST version goes — guard docs\n * are stamped with the version-less `name`, so they stay while any\n * version remains deployed.\n */\n deletedGuardCount: number\n}\n\nexport interface DeployDefinitionsResult {\n /** Per-definition outcome, ordered by the resolved deploy order (children first). */\n results: DeployDefinitionResult[]\n}\n\nexport interface StartInstanceArgs {\n /** The definition's `name` — which deployed workflow to instantiate. */\n definition: string\n /** Optional explicit version. Defaults to the highest deployed version. */\n version?: number\n /**\n * Initial values for `input`-sourced field entries declared on the\n * workflow definition. Each value is a\n * typed `InitialFieldValue` whose `type` + `name` must match an entry\n * on `definition.fields[]`. Entries not present here resolve to their\n * default (null for scalars, [] for arrays, or the entry's own\n * `initialValue` resolution for query/working-memory entries).\n *\n * To start an instance \"about\" a specific document, declare a\n * `{ type: \"doc.ref\", name: \"subject\", initialValue: { type: \"input\" } }`\n * entry on the workflow and pass\n * `{ type: \"doc.ref\", name: \"subject\", value: { id, type } }` here.\n * Conditions then read it as `$fields.subject`.\n */\n initialFields?: InitialFieldValue[]\n ancestors?: GlobalDocumentReference[]\n /**\n * Stable named params for effect handlers, set at start time. The\n * runtime resolves effect bindings against these to materialise\n * handler params at queue time. **Not read by transition filters.**\n */\n effectsContext?: Record<string, string | number | boolean | GlobalDocumentReference>\n /** Caller-supplied id; auto-generated otherwise. */\n instanceId?: string\n /**\n * Optional access-state override. By default the engine resolves\n * `(actor, grants)` from the supplied client's token:\n *\n * - `actor` ← `client.request({ url: \"/users/me\" })`\n * - `grants` ← `client.request({ url: grantsFromPath })` (when path supplied)\n *\n * Pass `access` to override either or both — the test bench does\n * this with its `ALL_ACCESS` default, admin tooling can do it for\n * impersonation flows. If neither the explicit override nor a\n * token-bearing client is available, the engine throws rather than\n * fabricating an identity.\n */\n access?: WorkflowAccessOverride\n /**\n * URL path on the supplied client where the engine fetches the\n * actor's ACL grants when `access.grants` isn't supplied. Grants\n * feed the advisory `$can.*` params action conditions can read;\n * omitting this leaves the rendered `$can` undefined (conditions\n * referencing it fail closed, nothing else is gated engine-side —\n * the real Sanity write boundary still enforces).\n *\n * Canvas-style: `/canvases/<resourceId>/acl`.\n * Project/dataset: `/projects/<id>/datasets/<ds>/acl`.\n */\n grantsFromPath?: string\n /**\n * Optional read-side perspective for this instance. Threaded into\n * field-entry query resolution and spawn `forEach.groq` discovery so\n * a workflow can scope its reads to a Content Release stack. Child\n * instances inherit the parent's perspective on spawn.\n *\n * Pass `[releaseName]` for a workflow whose subject is a release;\n * pass `[releaseName, \"drafts\"]` to also include drafts; omit for\n * the engine's default (no perspective override = `\"raw\"` on the\n * test client).\n */\n perspective?: WorkflowPerspective\n}\n\nexport interface OperationArgs {\n instanceId: string\n /**\n * Optional access-state override. See `StartInstanceArgs.access`\n * for the resolution contract.\n */\n access?: WorkflowAccessOverride\n /**\n * URL path for grant resolution — see `StartInstanceArgs.grantsFromPath`.\n */\n grantsFromPath?: string\n idempotencyKey?: string\n}\n\nexport interface FireActionArgs extends OperationArgs {\n activity: string\n action: string\n /**\n * Caller-supplied params for the action. Validated against\n * `Action.params[]` before commit; missing/required mismatch throws\n * `ActionParamsInvalidError`. Resolved values feed `ValueExpr.param`\n * lookups in ops and effect bindings.\n */\n params?: Record<string, unknown>\n /**\n * If true, no-op (instead of throwing) when the activity is missing from\n * the current stage's `activityStatus` — typically because the workflow\n * has already advanced past it. Useful for drive scripts and\n * at-least-once delivery semantics: the second call returns the\n * unchanged instance with `changed: false` rather than blowing up.\n */\n idempotent?: boolean\n}\n\nexport interface CompleteEffectArgs extends OperationArgs {\n /** The `_key` of the pending effect being reported on. */\n effectKey: string\n status: 'done' | 'failed'\n /**\n * Named values produced by the effect. If supplied, these are merged\n * into `effectsContext` (replace-by-key) and become available to\n * downstream effect bindings on the same instance.\n */\n outputs?: Record<string, string | number | boolean | GlobalDocumentReference>\n /**\n * The state half of the effect: `field.*` ops to apply in the completion\n * commit, computed from the effect's real result (e.g. a `field.set` of a\n * created doc's ref, or the screened outcome an activity/stage gate then reads).\n * Run through the same op applier as an action's field ops — a target must\n * resolve in the current open stage and its value must match the field's kind;\n * workflow- and stage-scope targets only. Deliberately NOT `status.set`: an\n * effect is outside the activity's awaiting, so it reports its result as field\n * state and lets the gate decide the activity/stage outcome — it never flips an\n * activity status itself (same boundary a transition draws). Only valid with\n * `status: 'done'` (a failed completion carries no ops). Not actor-gated.\n */\n ops?: FieldOp[]\n detail?: string\n error?: {message: string; stack?: string}\n durationMs?: number\n}\n\nexport interface EditFieldArgs extends OperationArgs {\n /**\n * Which declared-editable field to write. Omit `scope` to resolve lexically\n * (a `activity` implies activity scope; otherwise the nearest declaring scope, stage\n * before workflow). `activity` is required to address an activity-scope field.\n */\n target: EditFieldTarget\n /**\n * How to write: `set` replaces the value (reassign / reschedule), `append`\n * adds a row to an array field (a running log / todo list), `unset` clears it.\n * Default `set`.\n */\n mode?: EditMode\n /**\n * The new value (for `set`) or row (for `append`), as plain JSON matching the\n * field's kind. Validated against the field kind in the op path; omit for\n * `unset`.\n */\n value?: unknown\n}\n\nexport interface SetStageArgs extends OperationArgs {\n /** Stage id to force the instance into. */\n targetStage: string\n /** Free-text reason — surfaces on history entries for audit. */\n reason?: string\n /**\n * Initial values for field entries on the target stage, in the same shape as\n * `startInstance.initialFields`; reserved for the stage-field work.\n */\n initialFields?: InitialFieldValue[]\n}\n\nexport interface AbortInstanceArgs extends OperationArgs {\n /** Free-text reason — surfaces on the `workflow.history.aborted` entry for audit. */\n reason?: string\n}\n\n/** Args for the verbs that address an instance without further input. */\nexport interface InstanceRefArgs {\n instanceId: string\n}\n\nexport interface ChildrenArgs extends InstanceRefArgs {\n /** Restrict to children spawned by this activity on the parent. */\n activity?: string\n}\n\nexport interface GuardsForDefinitionArgs {\n /** The definition's `name`. */\n definition: string\n}\n\nexport interface InstancesForDocumentArgs {\n /** A resource-qualified GDR URI; a bare id is rejected. */\n document: GdrUri\n}\n\nexport interface QueryArgs {\n groq: string\n params?: Record<string, unknown>\n}\n\nexport interface QueryInScopeArgs extends InstanceRefArgs, QueryArgs {}\n\nexport interface FindPendingEffectsArgs extends InstanceRefArgs {\n /** Filter on claim presence. */\n claimed?: boolean\n /** Restrict to specific effect names. */\n names?: string[]\n}\n\nexport interface DrainEffectsArgs extends InstanceRefArgs {\n /** Override the drainer's identity (e.g. impersonate a real user whose\n * grants the dispatch should respect). Defaults to a\n * `{ kind: \"system\", id: \"engine.drainEffects\" }` actor. */\n access?: WorkflowAccessOverride\n}\n\nexport interface SessionArgs {\n /** The instance document to bind — typically the consumer's live-store value. */\n instance: WorkflowInstance\n /** Optional access-state override — see `StartInstanceArgs.access`. */\n access?: WorkflowAccessOverride | undefined\n /** URL path for grant resolution — see `StartInstanceArgs.grantsFromPath`. */\n grantsFromPath?: string | undefined\n}\n\nexport type {OpAppliedSummary} from '../engine/results.ts'\n\n/**\n * What a state-changing verb reports back. Every mutating verb —\n * `startInstance`, `fireAction`, `editField`, `completeEffect`, `tick`,\n * `setStage`, `abortInstance` — returns this one shape, on the namespace,\n * the `Engine`, and the reactive session alike.\n */\nexport interface OperationResult {\n /** The instance after the operation + all cascading auto-transitions. */\n instance: WorkflowInstance\n /** Number of auto-transitions that fired during the cascade. */\n cascaded: number\n /**\n * Whether this call changed the instance's workflow state. `false` means\n * the call succeeded but was a no-op: an idempotent re-fire of an already\n * resolved activity, a `tick` that wrote nothing, a `setStage` already at\n * the target, an abort of an already-terminal instance. Failures throw —\n * `changed: false` never signals an error.\n */\n changed: boolean\n /** Engine primitives (`workflow.op.field.*` / `status.set`) that ran\n * during the action commit. Surfaced for caller-side assertions and\n * audit. */\n ranOps?: OpAppliedSummary[]\n}\n\n/**\n * External effect handler — invoked at drain time with the resolved\n * `params` and a context. Returning `outputs` upserts them into\n * `effectsContext` (replace-by-key) so downstream effects can bind.\n * Returning `ops` applies the state half of the effect in the completion\n * commit — `field.*` computed from the real result, run through the same op\n * applier as an action's field ops (so a created doc's ref enters `$fields`, or\n * a screened outcome lands in a field the activity/stage gate reads). Effects\n * report results as field state, never by flipping an activity status, so `ops`\n * excludes `status.set`. Throwing marks the effect as failed (and returns no\n * `ops`).\n */\nexport type EffectHandler = (\n params: Record<string, unknown>,\n ctx: {\n /** The engine's own client — bound to the workflow resource the\n * instance lives in. Use it for same-resource subjects; for a\n * cross-resource subject, route through {@link clientFor} instead. */\n client: WorkflowClient\n /**\n * Resolve the client bound to a subject doc's own resource. A handler\n * patches the SUBJECT (which may live in a different Sanity resource\n * than the instance — split-dataset GDR deploys); the drainer's\n * `completeEffect` writes the INSTANCE through {@link client}. One\n * client can't address both, so a handler that patches a foreign\n * subject must route its write here.\n *\n * Pass the subject's GDR — the URI a binding like `$fields.subject._id`\n * resolves to (the hydrated doc's `_id`), or a full\n * {@link GlobalDocumentReference}. Returns the resolver's client for\n * that resource, falling back to {@link client} when the engine has no\n * `resourceClients` mapping for it. Throws if `ref` isn't a GDR — a\n * bare id can't be routed, so failing loud beats silently patching the\n * wrong dataset.\n */\n clientFor: (ref: GdrUri | GlobalDocumentReference) => WorkflowClient\n instanceId: string\n effectKey: string\n log: (message: string, extra?: Record<string, unknown>) => void\n },\n) => Promise<{\n outputs?: Record<string, string | number | boolean | GlobalDocumentReference>\n ops?: FieldOp[]\n} | void>\n\nexport interface MissingHandlerDeployInfo {\n phase: 'deploy'\n name: string\n locations: string[]\n definitionId: string\n}\nexport interface MissingHandlerDrainInfo {\n phase: 'drain'\n name: string\n effectKey: string\n instanceId: string\n}\nexport type MissingHandlerInfo = MissingHandlerDeployInfo | MissingHandlerDrainInfo\n\n/**\n * The `missingHandler: 'fail'` policy tripped: an effect names a handler the\n * runtime never registered. `info` carries the phase-specific location\n * (deploy verification vs a drain attempt) so the runtime that opted into\n * failing can report exactly which handler is missing where.\n */\nexport class MissingHandlerError extends WorkflowError<'missing-effect-handler'> {\n readonly info: MissingHandlerInfo\n\n constructor(args: {info: MissingHandlerInfo}) {\n super('missing-effect-handler', missingHandlerMessage(args.info))\n this.name = 'MissingHandlerError'\n this.info = args.info\n }\n}\n\nfunction missingHandlerMessage(info: MissingHandlerInfo): string {\n if (info.phase === 'deploy') {\n return `verifyDeployedDefinitions: missing handler for \"${info.name}\" referenced by ${info.definitionId} at ${info.locations.join(', ')}`\n }\n return `drainEffects: no handler registered for \"${info.name}\" (effectKey=${info.effectKey}, instanceId=${info.instanceId})`\n}\n\nexport type MissingHandlerPolicy =\n | 'fail'\n | 'skip'\n | ((info: MissingHandlerInfo) => void | Promise<void>)\n\nexport interface EngineLogger {\n info: (message: string, extra?: Record<string, unknown>) => void\n warn: (message: string, extra?: Record<string, unknown>) => void\n error: (message: string, extra?: Record<string, unknown>) => void\n}\nexport type LoggerFactory = (name: string) => EngineLogger\n\n/**\n * Resolver for cross-resource reads. The engine has ONE `client` bound\n * to its own resource (where definition / instance\n * docs live). When the engine reads a doc in a different resource —\n * a subject in a project dataset while the workflow lives in canvas,\n * say — it consults this resolver with the parsed GDR. Return `undefined`\n * to fall back to the engine's default client.\n *\n * The resolver receives the parsed pieces, not the raw URI, so it can\n * pattern-match on scheme + resource id without re-parsing.\n */\nexport type ResourceClientResolver = (parsed: ParsedGdr) => WorkflowClient | undefined\n\nexport interface DrainEffectsResult {\n drained: PendingEffect[]\n failed: PendingEffect[]\n skipped: PendingEffect[]\n}\n\nexport interface VerifyDeployedDefinitionsResult {\n /** Definitions seen, ordered by `name` asc, `version` asc. */\n definitions: {name: string; version: number; _id: string}[]\n /** Effect names referenced by any deployed definition without a\n * registered handler — one entry per (name, definitionId) tuple. */\n missing: {name: string; definitionId: string; locations: string[]}[]\n}\n","import type {WorkflowAccessOverride} from '../access.ts'\nimport {\n parseGdr,\n type GdrUri,\n type GlobalDocumentReference,\n type WorkflowResource,\n} from '../core/refs.ts'\nimport {\n WORKFLOW_DEFINITION_TYPE,\n type Effect,\n type FieldOp,\n type WorkflowDefinition,\n} from '../define/schema.ts'\nimport {isRevisionConflict} from '../engine/results.ts'\nimport {engineSystemActor} from '../engine/system-actor.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 {buildClientForGdr} from './operations.ts'\nimport {\n type DrainEffectsResult,\n type EffectHandler,\n type EngineLogger,\n type LoggerFactory,\n type MissingHandlerDeployInfo,\n MissingHandlerError,\n type MissingHandlerInfo,\n type MissingHandlerPolicy,\n type ResourceClientResolver,\n type 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({policy: missingHandler, info, log})\n if (verdict === 'fail') {\n throw new MissingHandlerError({info})\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.activities ?? []) {\n visitEffects(t.effects, `stage[${stage.name}].activity[${t.name}].effects`)\n for (const a of t.actions ?? []) {\n visitEffects(\n a.effects,\n `stage[${stage.name}].activity[${t.name}].action[${a.name}].effects`,\n )\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 // Routes a handler's cross-resource subject write to the right client.\n // A split-dataset deploy keeps the instance in the engine's resource\n // (where completeEffect writes) while the subject lives in another;\n // `buildClientForGdr` falls back to the engine client for unmapped\n // resources, and `parseGdr` throws on a bare id so a handler that hands\n // one over fails loud instead of silently patching the wrong dataset.\n const routeGdr = buildClientForGdr(client, resourceClients)\n const clientFor = (ref: GdrUri | GlobalDocumentReference): WorkflowClient =>\n routeGdr(parseGdr(typeof ref === 'string' ? ref : ref.id))\n const drainerActor: Actor = args.access?.actor ?? engineSystemActor('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({\n client,\n instance: before,\n effectKey: candidate._key,\n drainerActor,\n })\n if (!claimed) continue // 409 — re-read and retry a fresh candidate.\n\n const {outputs, ops, dispatchError} = await dispatchEffect({\n handler,\n candidate,\n ctx: {\n client,\n clientFor,\n instanceId,\n logger,\n },\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 ops,\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 ops: FieldOp[] | undefined\n dispatchError: {message: string; stack?: string} | undefined\n}): Promise<void> {\n const {outputs, ops, 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 ...(ops !== undefined ? {ops} : {}),\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,\n candidate,\n instanceId,\n log,\n}: {\n missingHandler: MissingHandlerPolicy\n candidate: PendingEffect\n instanceId: string\n log: EngineLogger\n}): Promise<void> {\n const policyResult = await applyMissingHandler({\n policy: missingHandler,\n info: {phase: 'drain', name: candidate.name, effectKey: candidate._key, instanceId},\n log,\n })\n if (policyResult === 'fail') {\n throw new MissingHandlerError({\n info: {phase: 'drain', name: candidate.name, effectKey: candidate._key, 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,\n instance,\n effectKey,\n drainerActor,\n}: {\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` + completion `ops`, or shaping a\n * thrown error into the `{message, stack?}` envelope `completeEffect` expects.\n * A throw is failure, so a failed dispatch carries neither outputs nor ops. */\nasync function dispatchEffect({\n handler,\n candidate,\n ctx,\n}: {\n handler: EffectHandler\n candidate: PendingEffect\n ctx: {\n client: WorkflowClient\n clientFor: (ref: GdrUri | GlobalDocumentReference) => WorkflowClient\n instanceId: string\n logger: LoggerFactory\n }\n}): Promise<{\n outputs?: Record<string, string | number | boolean | GlobalDocumentReference>\n ops?: FieldOp[]\n dispatchError?: {message: string; stack?: string}\n}> {\n try {\n const result = await handler(candidate.params, {\n client: ctx.client,\n clientFor: ctx.clientFor,\n instanceId: ctx.instanceId,\n effectKey: candidate._key,\n log: (message, extra) => ctx.logger(`effect.${candidate.name}`).info(message, extra),\n })\n return {\n ...(result?.outputs !== undefined ? {outputs: result.outputs} : {}),\n ...(result?.ops !== undefined ? {ops: result.ops} : {}),\n }\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,\n info,\n log,\n}: {\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.session({instance})`. 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 — but only a **strictly newer**\n * one (by `_updatedAt`): the session reloads its own commits, so a store\n * echo that lags behind a committed reload must not regress the held\n * 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 under `ifRevisionId`, after\n * the engine's guard pre-flight; a conflict surfaces (no internal retry).\n * The instance reloads its own writes; 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, EditFieldTarget} 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 {OperationResult, 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 self-doc updates the held instance only when\n * its `_updatedAt` is strictly newer — an older or timestamp-equal echo is\n * ignored. 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<OperationResult>\n /** Fire an action against an activity, gated on the held content, then cascade. */\n fireAction(args: {\n activity: string\n action: string\n params?: Record<string, unknown>\n }): Promise<OperationResult>\n /** Edit a declared-editable field against the held content (the generic edit\n * seam), gated on the held projection, then cascade. */\n editField(args: {\n target: EditFieldTarget\n mode?: EditMode\n value?: unknown\n }): Promise<OperationResult>\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 const candidate = asHeldInstance(owned.doc)\n // Newest-wins for the self-doc only (parsed `_updatedAt`): the session\n // reloads its own commits, so a lagging store echo must not regress the\n // held instance — an equal stamp keeps the held copy, since only a\n // strictly newer one proves an advance. Content stays last-write-wins.\n if (Date.parse(candidate._updatedAt) > Date.parse(instance._updatedAt)) {\n instance = candidate\n }\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 operation result. Shared by the\n // intent verbs that always change state (`fireAction` / `editField`); `tick`\n // reports `changed` from the cascade count, so it builds its own result.\n const settleAfterApply = async ({\n actor,\n held,\n ranOps,\n }: {\n actor: Actor\n held: ReadonlyMap<string, LoadedDoc>\n ranOps: OperationResult['ranOps']\n }): Promise<OperationResult> => {\n const cascaded = await cascade({\n client,\n instanceId: instance._id,\n actor,\n clientForGdr,\n ...(clock !== undefined ? {clock} : {}),\n overlay: held,\n })\n instance = await reload({client, instanceId: instance._id, tag})\n return {instance, cascaded, changed: 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<OperationResult>,\n ): Promise<OperationResult> => {\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 // `changed` compares lake revisions around the cascade (a fresh read,\n // not the held instance — the held copy may lag the lake) so a\n // persisted gate flip that didn't unlock a transition still reports.\n const before = await reload({client, instanceId: instance._id, tag})\n const cascaded = await cascade({\n client,\n instanceId: instance._id,\n actor,\n clientForGdr,\n ...(clock !== undefined ? {clock} : {}),\n overlay: held,\n })\n instance = await reload({client, instanceId: instance._id, tag})\n return {instance, cascaded, changed: instance._rev !== before._rev}\n })\n },\n\n fireAction({activity, 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({evaluation: await evaluateWith(held, heldGuards), activity, 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 activity,\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 editField({target, mode, value}) {\n return commit(async (actor, held) => {\n // Soft-gate on the held projection — the same editable-field verdict the\n // UI rendered (a non-editable field 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 // The recency gate orders self-docs by `_updatedAt` — an unparseable stamp\n // would silently disable it, so fail hard like every other malformed shape.\n if (typeof candidate._updatedAt !== 'string' || Number.isNaN(Date.parse(candidate._updatedAt))) {\n throw new Error(`update: self-doc ${doc._id} has no parseable _updatedAt`)\n }\n return doc as WorkflowInstance\n}\n","import 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} 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 {WorkflowEvaluation} from '../types/evaluation.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 DrainEffectsArgs,\n DrainEffectsResult,\n EditFieldArgs,\n EffectHandler,\n AbortInstanceArgs,\n ChildrenArgs,\n DeleteDefinitionArgs,\n DeleteDefinitionResult,\n EngineLogger,\n FindPendingEffectsArgs,\n FireActionArgs,\n GuardsForDefinitionArgs,\n InstanceRefArgs,\n InstancesForDocumentArgs,\n LoggerFactory,\n MissingHandlerPolicy,\n OperationArgs,\n OperationResult,\n QueryArgs,\n QueryInScopeArgs,\n EngineScopeArgs,\n SessionArgs,\n SetStageArgs,\n StartInstanceArgs,\n VerifyDeployedDefinitionsResult,\n} from './types.ts'\nimport {workflow} from './workflow.ts'\n\n// createEngine factory.\n//\n// Pre-binds the {@link EngineScopeArgs} scope — `client`, `tag`,\n// `workflowResource`, `resourceClients` (and optional `effectHandlers`,\n// `missingHandler`, `loggerFactory`, `clock`) — so callers don't repeat\n// them on every call. The verbs mirror the `workflow.*` namespace; the\n// namespace stays for callers that want the raw, unbound functions.\n\n/**\n * The {@link EngineScopeArgs} scope pinned at construction, plus the\n * engine-only extras (`effectHandlers` / `missingHandler` / `loggerFactory`\n * feed `drainEffects` + `verifyDeployedDefinitions`). The `tag` partition is\n * required and never defaulted — the engine enforces nothing, so the\n * partition is the only thing keeping reads and writes off the wrong\n * environment.\n */\nexport interface CreateEngineArgs extends EngineScopeArgs {\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\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: DeployDefinitionsArgs) => Promise<DeployDefinitionsResult>\n startInstance: (args: StartInstanceArgs) => Promise<OperationResult>\n fireAction: (args: FireActionArgs) => Promise<OperationResult>\n /** Edit a declared-editable field directly (the generic edit seam):\n * reassign / reschedule / claim-by-hand / append-to-log, then cascade. */\n editField: (args: EditFieldArgs) => Promise<OperationResult>\n completeEffect: (args: CompleteEffectArgs) => Promise<OperationResult>\n tick: (args: OperationArgs) => Promise<OperationResult>\n /** Project the instance from an actor's perspective — per-action verdicts\n * with structured disabled reasons. Pure read. */\n evaluate: (args: EvaluateArgs) => Promise<WorkflowEvaluation>\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: 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: EvaluateArgs) => Promise<AvailableActionsResult>\n\n /** Admin override — bypass filters/transitions and force the stage. */\n setStage: (args: SetStageArgs) => Promise<OperationResult>\n /** Admin override — hard-stop an in-flight instance where it stands. */\n abortInstance: (args: AbortInstanceArgs) => Promise<OperationResult>\n /** Admin override — remove a deployed definition (instances are only ever aborted, never deleted). */\n deleteDefinition: (args: DeleteDefinitionArgs) => Promise<DeleteDefinitionResult>\n /** Fetch a workflow instance by id. */\n getInstance: (args: InstanceRefArgs) => 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` field 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: InstanceRefArgs) => 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 session: (args: SessionArgs) => 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: InstanceRefArgs) => 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 field entries, unioned over all deployed versions.\n * Needs no live instance. Guards whose resource is only known per-instance\n * (input/runtime-sourced entries) are not reachable here — use\n * {@link Engine.guardsForInstance}. For housekeeping. Takes the\n * definition's `name`. */\n guardsForDefinition: (args: GuardsForDefinitionArgs) => Promise<MutationGuardDoc[]>\n /** Spawned children of a parent instance, optionally filtered by the\n * spawning activity. Sorted by `startedAt` asc. */\n children: (args: ChildrenArgs) => Promise<WorkflowInstance[]>\n /** The reverse of {@link Engine.subscriptionDocumentsForInstance}: every\n * in-flight instance whose watch-set includes `document` (a resource-qualified\n * GDR URI). For a non-reactive, content-change-driven runtime deciding which\n * instances a changed doc should `tick`. Matches the same ref set the forward\n * watch-set uses (self, ancestors, current-stage `doc.ref`/`doc.refs`/`release.ref`)\n * via the shared `collectWatchRefs`. Sorted by `startedAt` asc. */\n instancesForDocument: (args: InstancesForDocumentArgs) => Promise<WorkflowInstance[]>\n /** GROQ query against the engine's workflow resource. `$tag`\n * is bound for tag-scoped filtering. */\n query: <T = unknown>(args: QueryArgs) => 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's\n * instance-derived vars ({@link FILTER_SCOPE_VARS}) are bound, ids in\n * GDR URI form to match the snapshot's keying. */\n queryInScope: <T = unknown>(args: QueryInScopeArgs) => Promise<T>\n /** List every pending effect on an instance. */\n listPendingEffects: (args: InstanceRefArgs) => Promise<PendingEffect[]>\n /** Filter pending effects by claimed status and/or effect names. */\n findPendingEffects: (args: FindPendingEffectsArgs) => 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: DrainEffectsArgs) => 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 `workflow.*` verbs minus the {@link EngineScopeArgs}\n * scope (client / tag / workflowResource / resourceClients), which is\n * pinned at construction. The `tag` is required — see {@link validateTag}\n * for the accepted shape.\n *\n * Parity with the namespace is exact, with these deliberate exceptions:\n *\n * - Engine-only: {@link Engine.session} and\n * {@link Engine.subscriptionDocumentsForInstance} (need the pinned\n * binding), {@link Engine.drainEffects} and\n * {@link Engine.verifyDeployedDefinitions} (need the construction-time\n * `effectHandlers` / `missingHandler` / `loggerFactory`).\n * - Namespace-only: `workflow.permissions` — pure grant helpers that need\n * no engine scope.\n *\n * Effect handlers + missingHandler feed {@link Engine.drainEffects}\n * (dispatch of unclaimed pending effects) and\n * {@link Engine.verifyDeployedDefinitions} (the startup audit of\n * deployed effect names). They don't change `fireAction` / `tick` /\n * `completeEffect` — the runtime still decides when to drain and\n * reports outcomes 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 // Rehydrate a verb's args with the pinned scope (+ the engine clock).\n // Spread order makes the pinned scope non-overridable per call.\n const withScope = <A extends object>(rest: A) => ({\n ...rest,\n client,\n tag,\n workflowResource,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n ...(clock !== undefined ? {clock} : {}),\n })\n\n return {\n client,\n tag,\n workflowResource,\n effectHandlers,\n missingHandler,\n logger,\n deployDefinitions: (rest) => workflow.deployDefinitions(withScope(rest)),\n startInstance: (rest) => workflow.startInstance(withScope(rest)),\n fireAction: (rest) => workflow.fireAction(withScope(rest)),\n editField: (rest) => workflow.editField(withScope(rest)),\n completeEffect: (rest) => workflow.completeEffect(withScope(rest)),\n tick: (rest) => workflow.tick(withScope(rest)),\n evaluate: (rest) => workflow.evaluate(withScope(rest)),\n diagnose: (rest) => workflow.diagnose(withScope(rest)),\n availableActions: (rest) => workflow.availableActions(withScope(rest)),\n\n setStage: (rest) => workflow.setStage(withScope(rest)),\n abortInstance: (rest) => workflow.abortInstance(withScope(rest)),\n deleteDefinition: (rest) => workflow.deleteDefinition(withScope(rest)),\n getInstance: (rest) => workflow.getInstance(withScope(rest)),\n subscriptionDocumentsForInstance: (rest) =>\n workflow.getInstance(withScope(rest)).then(subscriptionDocumentsForInstance),\n session: ({instance, access, grantsFromPath}) =>\n createInstanceSession({\n client,\n tag,\n instance,\n ...(resourceClients !== undefined ? {resourceClients} : {}),\n ...(clock !== undefined ? {clock} : {}),\n ...(access !== undefined ? {access} : {}),\n ...(grantsFromPath !== undefined ? {grantsFromPath} : {}),\n }),\n guardsForInstance: (rest) => workflow.guardsForInstance(withScope(rest)),\n guardsForDefinition: (rest) => workflow.guardsForDefinition(withScope(rest)),\n children: (rest) => workflow.children(withScope(rest)),\n instancesForDocument: (rest) => workflow.instancesForDocument(withScope(rest)),\n query: (rest) => workflow.query(withScope(rest)),\n queryInScope: (rest) => workflow.queryInScope(withScope(rest)),\n listPendingEffects: (rest) => workflow.listPendingEffects(withScope(rest)),\n findPendingEffects: (rest) => workflow.findPendingEffects(withScope(rest)),\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 the latest deployed\n// version of its name as create / unchanged, reusing the engine's own\n// content-addressed deploy planner so a diff lines up exactly with what\n// `deployDefinitions` would do (never a re-derivation). Pure reasoning:\n// callers own the fetch and render the result.\n\nimport {\n loadLatestDeployed,\n planDefinitionDeploy,\n stripSystemFields,\n type LatestDeployed,\n} from './api/deploy.ts'\nimport type {ResourceAliases, WorkflowResource} from './core/refs.ts'\nimport 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, the\n * workflow resource it belongs to, and the resource-alias bindings to expand\n * references against. Structurally what `deployDefinitions` receives, minus the\n * definitions themselves — carrying `resourceAliases` here is what keeps a diff\n * fingerprinting the same physical content `deployDefinitions` would. */\nexport interface DeployTarget {\n tag: string\n workflowResource: WorkflowResource\n resourceAliases?: ResourceAliases\n}\n\nexport interface DiffEntry {\n name: string\n /** The version this deploy WOULD write, or the matched version when unchanged. */\n version: number\n status: 'create' | 'unchanged'\n docId: string\n /** The document deploy would write — including the stamped `version` and\n * `contentHash`. */\n expected: Record<string, unknown>\n /** The latest deployed document, system fields stripped — the prior shape to\n * diff against. Absent when nothing is deployed yet. */\n existing?: Record<string, unknown>\n}\n\n/**\n * Compare one local definition against the latest deployed version of its\n * name (or its absence), classifying it via the engine's own content-addressed\n * planner ({@link planDefinitionDeploy}). Create-only: a content change is a\n * NEW version, never an in-place update — so there is no `update` verdict.\n * Pure — the caller owns the fetch.\n */\nexport function diffEntry({\n def,\n latestRaw,\n target,\n}: {\n def: WorkflowDefinition\n latestRaw: Record<string, unknown> | undefined\n target: DeployTarget\n}): DiffEntry {\n const plan = planDefinitionDeploy({def, latest: asLatest(latestRaw), target})\n const existing = latestRaw ? stripSystemFields(latestRaw) : undefined\n return {\n name: def.name,\n version: plan.version,\n status: plan.status,\n docId: plan.docId,\n expected: plan.document,\n ...(existing !== undefined ? {existing} : {}),\n }\n}\n\n/** Narrow a fetched document to the `{version, contentHash}` the planner reads.\n * Fetched docs are cast (never parsed), so read both fields defensively — a\n * pre-fingerprint document has no `contentHash` and reads as changed. */\nfunction asLatest(raw: Record<string, unknown> | undefined): LatestDeployed | undefined {\n if (raw === undefined) return undefined\n const version = typeof raw.version === 'number' ? raw.version : 0\n return {version, ...(typeof raw.contentHash === 'string' ? {contentHash: raw.contentHash} : {})}\n}\n\n/** Compare each definition against the latest deployed version of its name. */\nexport async function computeDiffEntries({\n client,\n defs,\n target,\n}: {\n client: Pick<WorkflowClient, 'fetch'>\n defs: WorkflowDefinition[]\n target: DeployTarget\n}): Promise<DiffEntry[]> {\n const entries: DiffEntry[] = []\n for (const def of defs) {\n const latest = await loadLatestDeployed({client, definition: def.name, tag: target.tag})\n entries.push(diffEntry({def, latestRaw: latest, target}))\n }\n return entries\n}\n","/**\n * Display metadata for the discriminator literals the engine persists\n * (history entries, field-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 {DriverKind, ActivityKind} from './types/enums.ts'\nimport type {FieldKind} from './types/field-values.ts'\nimport type {HistoryEntry} from './types/history.ts'\nimport {WORKFLOW_INSTANCE_TYPE} from './types/instance.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 activityActivated: {\n title: 'Activity activated',\n description: 'An activity flipped from `pending` to `active` and its onEnter effects queued.',\n },\n activityStatusChanged: {\n title: 'Activity status changed',\n description: \"An action or op flipped an activity's status (active → done / skipped / failed).\",\n },\n actionFired: {\n title: 'Action fired',\n description:\n 'An action was invoked against an activity — 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: \"An activity'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 field-mutation op (field.set / field.append / status.set / etc.) ran during an action commit.',\n },\n fieldQueryDiscarded: {\n title: 'Query result discarded',\n description:\n \"A query-sourced field's GROQ result didn't fit the field's declared kind, so it was discarded and the field fell back to its default.\",\n },\n} satisfies Record<HistoryEntry['_type'], DisplayMetadata>\n\n/**\n * Field-entry `_type` discriminators. The entry's kind defines what\n * shape `value` takes (single GDR vs array, scalar vs notes log).\n */\nexport const FIELD_KIND_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 string: {\n title: 'String value',\n description: 'Free-form single-line string entry.',\n },\n text: {\n title: 'Text value',\n description: 'Free-form multiline string entry.',\n },\n number: {\n title: 'Number value',\n description: 'Numeric entry.',\n },\n boolean: {\n title: 'Boolean value',\n description: 'True/false entry.',\n },\n date: {\n title: 'Date value',\n description: 'Date-only (YYYY-MM-DD) entry, no time component.',\n },\n datetime: {\n title: 'Date / time value',\n description: 'ISO-8601 timestamp entry.',\n },\n url: {\n title: 'URL value',\n description: 'Validated URL entry.',\n },\n actor: {\n title: 'Actor value',\n description: 'A typed (person|agent|system) actor identity — a concrete principal.',\n },\n assignee: {\n title: 'Assignee',\n description: 'A single typed (user|role) assignee — who is expected/responsible.',\n },\n assignees: {\n title: 'Assignees',\n description: 'Ordered list of typed (user|role) assignees.',\n },\n object: {\n title: 'Object',\n description: 'An object with named sub-fields; the value is keyed by sub-field name.',\n },\n array: {\n title: 'Array',\n description:\n 'An array of objects shaped by the declared `of` sub-fields; ops add/update/remove rows.',\n },\n} satisfies Record<FieldKind, DisplayMetadata>\n\n/**\n * Op `type` discriminators — the stored mutation primitives.\n */\nexport const OP_DISPLAY = {\n 'field.set': {\n title: 'Set field entry',\n description: \"Overwrite a field entry's value with a resolved value expression.\",\n },\n 'field.unset': {\n title: 'Unset field entry',\n description: 'Reset a field entry to its default (null for scalars, [] for array kinds).',\n },\n 'field.append': {\n title: 'Append to field entry',\n description: 'Push a resolved item onto an array-kind entry (array, assignees, doc.refs).',\n },\n 'field.updateWhere': {\n title: 'Update matching rows',\n description: 'Merge fields into rows of an array-kind entry that match the `where` condition.',\n },\n 'field.removeWhere': {\n title: 'Remove matching rows',\n description: 'Drop rows of an array-kind entry that match the `where` condition.',\n },\n 'status.set': {\n title: 'Set activity status',\n description:\n \"Flip an activity'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 fields.',\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 * Activity-kind labels — the per-kind renderer's heading + tooltip. Kept OUT of\n * the combined {@link DISPLAY} map: kinds are a classification axis a consumer\n * looks up deliberately, not a `_type`, and `\"service\"` collides with the\n * same-named {@link DRIVER_KIND_DISPLAY} key.\n */\nexport const ACTIVITY_KIND_DISPLAY = {\n user: {\n title: 'User activity',\n description: 'A person acts via the app — renders action buttons ranked by outcome.',\n },\n service: {\n title: 'Service activity',\n description: 'An automated system or effect does the work — renders effect drain status.',\n },\n script: {\n title: 'Script activity',\n description: 'The engine runs a step inline and resolves on activation — an audit row.',\n },\n manual: {\n title: 'Manual activity',\n description:\n 'Work done off-system, acknowledged by a person or verified by a predicate — renders an instruction card with a deep-link.',\n },\n receive: {\n title: 'Receive activity',\n description:\n 'No actor; the engine waits on a condition — renders \"waiting until …\", no buttons.',\n },\n} satisfies Record<ActivityKind, DisplayMetadata>\n\n/**\n * Driver-kind labels — the actor glyph for \"who fired this action\", recorded\n * on the `actionFired` history entry. Standalone for the same reason as\n * {@link ACTIVITY_KIND_DISPLAY}.\n */\nexport const DRIVER_KIND_DISPLAY = {\n person: {title: 'Person', description: 'A human fired this action.'},\n agent: {title: 'Agent', description: 'An AI agent fired this action.'},\n service: {title: 'Service', description: 'An external system or Function fired this action.'},\n engine: {\n title: 'Engine',\n description: 'The workflow engine itself drove this — a gate, machine step, or housekeeping.',\n },\n} satisfies Record<DriverKind, DisplayMetadata>\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 ...FIELD_KIND_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":["parse","evaluate","v","currentActivities","selfGdr","actorFulfillsRole","toBareId","gdrFromResource","isTerminalActivityStatus","WorkflowError","StoredFieldOpSchema","formatIssues","validateFieldValue","validateFieldAppendItem","parseGroq","isGuardReadExpr","FIELD_READ","EFFECTS_READ","isGdrUri","parseGdr","resourceFromParsed","gdrRef","isGdr","tryParseGdr","doc","randomKey","isBareSeedId","toPhysicalGdr","checkFieldValue","ContractViolationError","InstanceNotFoundError","EffectNotFoundError","WORKFLOW_DEFINITION_TYPE","tagScopeFilter","resourceFromGdrUri","sameResource","andConditions","validateTag","DOCUMENT_VALUE_PERMISSIONS","extractDocumentId","definitionDocId","RESOURCE_ALIAS_NAME_SOURCE","gdrResourcePrefix","validateResourceAliasName","DefinitionNotFoundError","engineAbortInstance","engineEditField","engineInvokeActivity","engineFireAction","cascade","DefinitionInUseError","deleteDefinitionInternal","engineCompleteEffect","engineSetStage","queryGuardsForInstance","queryGuardsForDefinition","evaluateGroq"],"mappings":"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"}
|