@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.cjs","sources":["../../src/core/conditions.ts","../../src/core/roles.ts","../../src/types/enums.ts","../../src/define/schema.ts"],"sourcesContent":["/**\n * Shared GROQ condition composition. The one place that knows how the engine\n * ANDs partial conditions into a single predicate string — reused by the\n * define-time filter desugar (`roles` + `filter` + claim no-steal) and the\n * runtime editability resolution (slot baseline AND stage tighten-override).\n * Keeping it in one spot means the parenthesisation can't drift between the two.\n */\n\n/**\n * AND the supplied conditions into one GROQ predicate, dropping `undefined`\n * parts. Returns `undefined` when nothing remains (vacuously satisfied — the\n * caller's \"no gate\" case), the lone part verbatim when only one survives, and\n * each part parenthesised + `&&`-joined otherwise so operator precedence can't\n * change a part's meaning.\n */\nexport function andConditions(parts: readonly (string | undefined)[]): string | undefined {\n const present = parts.filter((p): p is string => p !== undefined)\n if (present.length === 0) return undefined\n if (present.length === 1) return present[0]\n return present.map((p) => `(${p})`).join(' && ')\n}\n","/**\n * Role-alias expansion — the pure rule behind the \"can be fulfilled by\" map.\n * One definition of \"which roles satisfy a required role\", shared by the two\n * sites that match an actor against required roles: the `roles` gate (baked\n * into GROQ at desugar) and `$assigned` (resolved at runtime). Keeping it in\n * one place is what lets the baked gate and the runtime check agree.\n */\n\nimport type {RoleAliases} from '../define/schema.ts'\n\n/**\n * The universal-fulfiller key as authors write it: roles listed under `\"*\"`\n * fulfill ANY required role. Rewritten to {@link UNIVERSAL_ROLE_ALIAS_KEY}\n * before the definition is stored — see {@link normalizeRoleAliases}.\n */\nconst AUTHORED_UNIVERSAL_ROLE_ALIAS_KEY = '*'\n\n/**\n * The stored spelling of the universal-fulfiller key. A deployed definition\n * persists `roleAliases` as structured document fields, and the Content Lake\n * rejects any attribute name that isn't `^\\$?[a-zA-Z0-9_-]+$` — so the authored\n * `\"*\"` ({@link AUTHORED_UNIVERSAL_ROLE_ALIAS_KEY}) cannot be a key on disk. The\n * `$` prefix is lake-legal and can't collide with a deployment role name.\n */\nexport const UNIVERSAL_ROLE_ALIAS_KEY = '$all'\n\n/**\n * Rewrite the authored universal key `\"*\"` to the lake-safe\n * {@link UNIVERSAL_ROLE_ALIAS_KEY} so the stored (and thus deployed) definition\n * carries no attribute name the Content Lake rejects. Per-role keys pass\n * through untouched. Define-time validation rejects an authored key in the\n * reserved `$` namespace, so the input never already carries the stored\n * universal key — this is a straight rename, not a merge. Pure — returns a new\n * map, or the input unchanged when there's no `\"*\"` to rewrite.\n */\nexport function normalizeRoleAliases(aliases: RoleAliases | undefined): RoleAliases | undefined {\n if (aliases === undefined || !(AUTHORED_UNIVERSAL_ROLE_ALIAS_KEY in aliases)) return aliases\n const {[AUTHORED_UNIVERSAL_ROLE_ALIAS_KEY]: universal, ...perRole} = aliases\n return {...perRole, [UNIVERSAL_ROLE_ALIAS_KEY]: universal}\n}\n\n/**\n * Widen a set of REQUIRED roles to every role that fulfills them: each\n * required role itself, plus its declared fulfillers, plus the universal\n * fulfillers under {@link UNIVERSAL_ROLE_ALIAS_KEY}. The actor's own roles are\n * never touched — only the accepted set grows. Reads the stored (normalised)\n * alias map, so the universal key is the lake-safe spelling, not `\"*\"`.\n *\n * Deterministic (declaration order, first occurrence wins) so the baked gate\n * and golden snapshots stay stable. Expansion is one level, not transitive: a\n * fulfiller that is itself an alias key is not followed.\n */\nexport function expandRequiredRoles(\n required: readonly string[],\n aliases: RoleAliases | undefined,\n): string[] {\n if (aliases === undefined) return [...required]\n const out = new Set<string>()\n for (const role of required) {\n out.add(role)\n for (const fulfiller of aliases[role] ?? []) out.add(fulfiller)\n }\n for (const fulfiller of aliases[UNIVERSAL_ROLE_ALIAS_KEY] ?? []) out.add(fulfiller)\n return [...out]\n}\n\n/**\n * Does the actor hold a role that fulfills `required` (a single required\n * role, e.g. an `assignees` entry's role)? The runtime twin of the baked\n * {@link expandRequiredRoles} gate, for `$assigned`.\n */\nexport function actorFulfillsRole(\n actorRoles: readonly string[] | undefined,\n required: string,\n aliases: RoleAliases | undefined,\n): boolean {\n if (actorRoles === undefined || actorRoles.length === 0) return false\n const accepted = new Set(expandRequiredRoles([required], aliases))\n return actorRoles.some((role) => accepted.has(role))\n}\n","/**\n * Leaf enums — the const arrays (and their derived union types) that both\n * the authoring schema and the engine address by name.\n *\n * This module imports nothing. It is the schema-free foundation that\n * `../define/schema.ts` reads its value constants from, which is what keeps\n * the type model and the valibot schema free of an import cycle: the value edge\n * `schema.ts → enums.ts` terminates here.\n */\n\n// Activity status — used by instance state. The authored action `status:` sugar\n// (and the `status.set` op it desugars to) is constrained to the terminal\n// subset below.\nexport const ACTIVITY_STATUSES = ['pending', 'active', 'done', 'skipped', 'failed'] as const\nexport type ActivityStatus = (typeof ACTIVITY_STATUSES)[number]\n\n// The statuses an activity can be resolved INTO — what `status.set` accepts and\n// what stops blocking the `$allActivitiesDone` gate family.\nexport const TERMINAL_ACTIVITY_STATUSES = ['done', 'skipped', 'failed'] as const\nexport type TerminalActivityStatus = (typeof TERMINAL_ACTIVITY_STATUSES)[number]\n\nexport function isTerminalActivityStatus(status: ActivityStatus): status is TerminalActivityStatus {\n return (TERMINAL_ACTIVITY_STATUSES as readonly ActivityStatus[]).includes(status)\n}\n\n// The three field scopes a field entry can live in. Authoring (`ScopeKey`,\n// `fieldRead` sources) and the engine both address field entries by scope.\nexport const FIELD_SCOPES = ['workflow', 'stage', 'activity'] as const\nexport type FieldScope = (typeof FIELD_SCOPES)[number]\n\n// Document-value permissions. Grants (`Grant` in ./authorization.ts) compose\n// most-permissive-wins.\nexport const DOCUMENT_VALUE_PERMISSIONS = ['create', 'read', 'update'] as const\nexport type DocumentValuePermission = (typeof DOCUMENT_VALUE_PERMISSIONS)[number]\n\n// Mutation-guard actions — the lake operations a guard can gate. See the\n// guard types in ./authorization.ts.\nexport const MUTATION_GUARD_ACTIONS = [\n 'create',\n 'update',\n 'delete',\n 'publish',\n 'unpublish',\n] as const\nexport type MutationGuardAction = (typeof MUTATION_GUARD_ACTIONS)[number]\n\n// Activity kinds — BPMN-aligned classification of an activity by its EXECUTOR. Purely\n// advisory: `kind` labels an activity so tooling renders it as what it is (and the\n// graph can show the work + its driver). It changes no gating or runtime — an\n// activity resolves and a transition fires exactly as the rest of its shape says.\n// Optional on the definition; derived from the activity's shape when omitted (see\n// `../activity-kind.ts`), so existing definitions need no edits.\nexport const ACTIVITY_KINDS = ['user', 'service', 'script', 'manual', 'receive'] as const\nexport type ActivityKind = (typeof ACTIVITY_KINDS)[number]\n\n// Driver kinds — what KIND of actor actually drove an action, recorded on the\n// `actionFired` history entry for the audit-trail \"who did this?\" glyph. Distinct\n// from {@link ActivityKind} (the intended execution lane): any driver can fire any\n// kind. Derived from the firing {@link Actor} (see `../activity-kind.ts`).\nexport const DRIVER_KINDS = ['person', 'agent', 'service', 'engine'] as const\nexport type DriverKind = (typeof DRIVER_KINDS)[number]\n","/**\n * Valibot schemas for the workflow authoring surface — the things a workflow\n * author writes by hand and feeds to `defineWorkflow`. Types in this\n * file are the **canonical** authoring types: they are inferred from\n * the schemas, so the runtime schema and the compile-time type cannot\n * drift.\n *\n * Two layers live here, mirroring the design model (generic stored data,\n * sugar that compiles away):\n *\n * - **Stored** schemas (`WorkflowDefinitionSchema`, `OpSchema`, …) describe\n * the primitives the engine persists. No sugar variants, every state\n * reference carries an explicit resolved `scope`.\n * - **Authoring** schemas (`AuthoringWorkflowSchema`, …) accept the same\n * primitives **plus** define-time sugar: the `claim` field/action pair,\n * the `audit` op, the `roles` and `status` action fields, omitted\n * transition filters, omitted reference scopes. `desugar.ts` expands\n * authoring input into the stored shape.\n *\n * Strictness: every object schema is `v.strictObject` so unknown keys\n * produce a parse error. That catches typos like `verison: 1` at deploy\n * time — and it is also what enforces each sugar contract's *reserved*\n * fields (an `ops:` on a `claim` action is an unknown key, fail loud).\n */\n\nimport * as v from 'valibot'\n\nimport {\n MUTATION_GUARD_ACTIONS,\n FIELD_SCOPES,\n ACTIVITY_KINDS,\n ACTIVITY_STATUSES,\n TERMINAL_ACTIVITY_STATUSES,\n} from '../types/enums.ts'\n\nconst NonEmpty = v.pipe(v.string(), v.minLength(1, 'must be a non-empty string'))\n\nconst PositiveInt = v.pipe(v.number(), v.integer(), v.minValue(1))\n\n/**\n * Names that get spliced into GROQ — field entries (`$fields.<name>` in the\n * claim no-steal filter and every condition) and predicate keys (`$<name>`).\n * A name like `review-owner` would parse as subtraction inside GROQ and\n * silently change the expression's meaning, so these are constrained to\n * GROQ-identifier-safe names. See {@link GROQ_IDENTIFIER}.\n */\nexport const GROQ_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/\n\nfunction groqIdentifier(referencedAs: string) {\n return v.pipe(\n v.string(),\n v.regex(\n GROQ_IDENTIFIER,\n `must be a GROQ-safe identifier (letters, digits, underscore; not starting with a digit) ` +\n `because it is referenced as ${referencedAs} in GROQ conditions`,\n ),\n )\n}\n\n/**\n * Picklist with a zod-compatible \"Invalid option\" message that lists every\n * allowed value, so a typo'd discriminator or enum lands with a message an\n * author can act on (e.g. `Invalid option: expected one of \"done\"|\"skipped\"`).\n */\nfunction picklist<const TOptions extends readonly [string, ...string[]]>(options: TOptions) {\n return v.picklist(\n options,\n `Invalid option: expected one of ${options.map((o) => `\"${o}\"`).join('|')}`,\n )\n}\n\n// Where a value comes from. Two distinct jobs, two types — never conflated:\n// FieldSource is how a field SEEDS its `initialValue`; ValueExpr is what an op\n// WRITES. They overlap on two arms — a constant and a field read — declared\n// once below and shared by both. Conditions and effect bindings are neither —\n// they are GROQ strings over the rendered scope ($fields, $actor, $row, …).\n\ntype LiteralExpr = {type: 'literal'; value: unknown}\ntype FieldReadExpr = {\n type: 'fieldRead'\n scope?: 'workflow' | 'stage' | undefined\n field: string\n path?: string | undefined\n}\n\nconst LiteralSchema = v.strictObject({type: v.literal('literal'), value: v.unknown()})\nconst FieldReadSchema = v.strictObject({\n type: v.literal('fieldRead'),\n scope: v.optional(v.union([v.literal('workflow'), v.literal('stage')])),\n field: NonEmpty,\n path: v.optional(v.string()),\n})\n\n// FieldSource — a field's seed recipe: how its `initialValue` is produced once,\n// at materialisation (then advisory; the slot is freely editable after). Every\n// arm is a discriminated `{type, …}` object — defs are data, not code, so a\n// seed stays serializable and unambiguous, never a bare value. An ABSENT\n// `initialValue` means working memory: the slot starts empty and an op fills it\n// later. That is the common default, so it is spelled by omission, not an arm.\ntype FieldSourceInternal =\n | {type: 'input'}\n | {type: 'query'; query: string}\n | LiteralExpr\n | FieldReadExpr\n\nconst FieldSourceSchema: v.GenericSchema<FieldSourceInternal> = v.union([\n // The caller supplies it at start/spawn (`initialFields` / `subworkflows.with`).\n v.strictObject({type: v.literal('input')}),\n // Computed once by running GROQ against the lake at materialisation.\n v.strictObject({type: v.literal('query'), query: NonEmpty}),\n LiteralSchema,\n FieldReadSchema,\n])\nexport type FieldSource = FieldSourceInternal\n\n// ValueExpr — an op payload expression, resolved to concrete JSON when the op\n// applies. Each context-bound arm has a rendered $-twin in conditions\n// (actor ↔ $actor, now ↔ $now, self ↔ $self) so learning one side teaches the\n// other.\ntype ValueExprInternal =\n | LiteralExpr\n | FieldReadExpr\n | {type: 'param'; param: string}\n | {type: 'actor'}\n | {type: 'now'}\n | {type: 'self'}\n | {type: 'stage'}\n | {type: 'object'; fields: Record<string, ValueExprInternal>}\n\nconst ValueExprSchema: v.GenericSchema<ValueExprInternal> = v.lazy(() =>\n v.union([\n LiteralSchema,\n FieldReadSchema,\n v.strictObject({type: v.literal('param'), param: NonEmpty}),\n v.strictObject({type: v.literal('actor')}),\n v.strictObject({type: v.literal('now')}),\n v.strictObject({type: v.literal('self')}),\n v.strictObject({type: v.literal('stage')}),\n v.strictObject({type: v.literal('object'), fields: v.record(NonEmpty, ValueExprSchema)}),\n ]),\n)\nexport type ValueExpr = ValueExprInternal\n\n// Field references — `{ scope?, field }` addressing a field entry by name.\n// Authoring may omit `scope`; desugar resolves it lexically (activity → stage →\n// workflow), so the STORED form always carries an explicit scope.\n\nconst StoredFieldRefSchema = v.strictObject({\n scope: picklist(FIELD_SCOPES),\n field: NonEmpty,\n})\nexport type StoredFieldRef = v.InferOutput<typeof StoredFieldRefSchema>\n\nconst AuthoringFieldRefSchema = v.strictObject({\n scope: v.optional(picklist(FIELD_SCOPES)),\n field: NonEmpty,\n})\nexport type AuthoringFieldRef = v.InferOutput<typeof AuthoringFieldRefSchema>\n\n// Manual-activity deep-link target — render-only metadata for the \"go do this off\n// system\" affordance on a `kind: \"manual\"` activity: either a static URL, or a\n// field reference whose resolved document the consumer opens. The `field`\n// variant resolves lexically at desugar like every op target, so the stored\n// form carries an explicit scope; deploy checks it points at a doc-valued entry.\n// A manual target's URL becomes an `href` in a downstream consumer, so the\n// scheme is allow-listed to http(s) at deploy — `v.url()` alone accepts\n// `javascript:` / `data:` / `file:`, which have no business in a deep-link.\nconst HREF_SCHEMES = ['http:', 'https:']\n// Tolerant of unparseable input — the pipe doesn't short-circuit, so this runs\n// even when `v.url()` already flagged the string; a parse failure is `false`,\n// not a thrown error.\nfunction isHttpUrl(value: string): boolean {\n try {\n return HREF_SCHEMES.includes(new URL(value).protocol)\n } catch {\n return false\n }\n}\nconst UrlString = v.pipe(\n v.string(),\n v.url('must be a valid URL'),\n v.check(isHttpUrl, 'must be an http(s) URL'),\n)\n\nfunction manualTargetSchema<TRef extends v.GenericSchema>(ref: TRef) {\n return v.variant('type', [\n v.strictObject({type: v.literal('url'), url: UrlString}),\n v.strictObject({type: v.literal('field'), field: ref}),\n ])\n}\n\nconst StoredManualTargetSchema = manualTargetSchema(StoredFieldRefSchema)\nexport type ManualTarget = v.InferOutput<typeof StoredManualTargetSchema>\n\n// Authoring accepts a bare field name as well as `{scope?, field}`, like the\n// `claim` action's field reference; desugar normalises and resolves it.\nconst AuthoringManualTargetSchema = manualTargetSchema(v.union([NonEmpty, AuthoringFieldRefSchema]))\nexport type AuthoringManualTarget = v.InferOutput<typeof AuthoringManualTargetSchema>\n\n// Op predicates — small typed predicate for field.updateWhere /\n// field.removeWhere. Runs in the pure in-memory op path, so it stays a\n// typed structure rather than GROQ. Discriminated by `type` like every union.\n\ntype OpPredicateInternal =\n | {type: 'field'; field: string; equals: ValueExpr}\n | {type: 'all'; of: OpPredicateInternal[]}\n | {type: 'any'; of: OpPredicateInternal[]}\n\nconst OpPredicateSchema: v.GenericSchema<OpPredicateInternal> = v.lazy(() =>\n v.union([\n v.strictObject({\n type: v.literal('field'),\n field: NonEmpty,\n equals: ValueExprSchema,\n }),\n v.strictObject({type: v.literal('all'), of: v.array(OpPredicateSchema)}),\n v.strictObject({type: v.literal('any'), of: v.array(OpPredicateSchema)}),\n ]),\n)\nexport type OpPredicate = OpPredicateInternal\n\n// Ops — the six stored mutation primitives. `value` is the one payload key.\n// `status.set` may name a sibling activity; desugar fills the firing activity when\n// authoring omitted it, so the stored op always carries `activity`.\n\nfunction opSchemas<T extends v.GenericSchema>(targetSchema: T) {\n return [\n v.strictObject({\n type: v.literal('field.set'),\n target: targetSchema,\n value: ValueExprSchema,\n }),\n v.strictObject({\n type: v.literal('field.unset'),\n target: targetSchema,\n }),\n v.strictObject({\n type: v.literal('field.append'),\n target: targetSchema,\n value: ValueExprSchema,\n }),\n v.strictObject({\n type: v.literal('field.updateWhere'),\n target: targetSchema,\n where: OpPredicateSchema,\n value: ValueExprSchema,\n }),\n v.strictObject({\n type: v.literal('field.removeWhere'),\n target: targetSchema,\n where: OpPredicateSchema,\n }),\n ] as const\n}\n\nconst StoredOpSchema = v.variant('type', [\n ...opSchemas(StoredFieldRefSchema),\n v.strictObject({\n type: v.literal('status.set'),\n activity: NonEmpty,\n status: picklist(ACTIVITY_STATUSES),\n }),\n])\nexport type Op = v.InferOutput<typeof StoredOpSchema>\n\n/**\n * The `field.*` subset a transition may carry — `status.set` has no coherent\n * activity target while the stage's activities tear down, so the engine rejects it\n * at parse time rather than dropping it silently.\n */\nconst StoredTransitionOpSchema = v.variant('type', [...opSchemas(StoredFieldRefSchema)])\nexport type TransitionOp = v.InferOutput<typeof StoredTransitionOpSchema>\n\n// Authoring ops: scope optional on targets, `activity` optional on status.set\n// (defaults to the firing activity), plus the `audit` sugar type — a stamped\n// append whose expansion merges `actor`/`at` ValueExpr fields into its own value.\n\nconst AuditOpSchema = v.strictObject({\n type: v.literal('audit'),\n target: AuthoringFieldRefSchema,\n value: ValueExprSchema,\n stampFields: v.optional(\n v.strictObject({\n actor: v.optional(NonEmpty),\n at: v.optional(NonEmpty),\n }),\n ),\n})\n\nexport const AuthoringOpSchema = v.variant('type', [\n ...opSchemas(AuthoringFieldRefSchema),\n v.strictObject({\n type: v.literal('status.set'),\n activity: v.optional(NonEmpty),\n status: picklist(ACTIVITY_STATUSES),\n }),\n AuditOpSchema,\n])\nexport type AuthoringOp = v.InferOutput<typeof AuthoringOpSchema>\n\n// Field entries — the generic stored data. Kinds are bare: a discriminator is\n// unique within its union; namespaces live only on engine-owned lake document\n// `_type`s ({@link WORKFLOW_DEFINITION_TYPE}, the instance type).\n\n/**\n * The kinds a VALUE can take — scalars aligned to Sanity's names, the\n * reference kinds, the actor/assignee identities, and the two compositional\n * kinds (`object` with named `fields`, `array` of objects shaped by `of`).\n * This is also the set a nested {@link FieldShape} sub-field may use.\n */\nconst FIELD_VALUE_KINDS = [\n 'doc.ref',\n 'doc.refs',\n // Release reference. A workflow declares this entry to say \"I target a\n // Content Release\"; the runtime fills it at start time and auto-derives\n // the instance's read perspective from it.\n 'release.ref',\n 'string',\n 'text',\n 'number',\n 'boolean',\n 'date',\n 'datetime',\n 'url',\n 'actor',\n // A single {@link Assignee} — the singular of `assignees`.\n 'assignee',\n // The WHO-FOR entry: the inbox reverse-query reads it by kind, and the\n // rendered `$assigned` gate matches the caller against it.\n 'assignees',\n // Compositional kinds — mirror Sanity's `object.fields` / `array.of`.\n 'object',\n 'array',\n] as const\n\nconst FieldValueKindSchema = picklist(FIELD_VALUE_KINDS)\n\nconst FieldKindSchema = picklist(FIELD_VALUE_KINDS)\n\nconst FieldEntryName = groqIdentifier('`$fields.<name>`')\n\n// Compositional kinds carry a recursive sub-field shape (`object.fields` /\n// `array.of`). A {@link FieldShape} is lighter than a {@link FieldEntry}: it\n// carries only `type`/`name`/labels and its own nesting — the slot-level\n// concerns (`initialValue`/`editable`/`required`) live ONLY on the top-level\n// entry, since a sub-field's value comes from the parent value.\n\nfunction asShape(input: unknown): {\n type?: unknown\n name?: unknown\n fields?: unknown\n of?: unknown\n} {\n return typeof input === 'object' && input !== null ? input : {}\n}\n\n/**\n * The compositional-kind contract, shared by top-level field entries and\n * nested {@link FieldShape}s: an `object` carries non-empty `fields` (and no\n * `of`), an `array` carries non-empty `of` (and no `fields`), and every other\n * kind carries neither.\n */\nfunction compositeShapeOk(input: unknown): boolean {\n const shape = asShape(input)\n if (shape.type === 'object') {\n return Array.isArray(shape.fields) && shape.fields.length > 0 && shape.of === undefined\n }\n if (shape.type === 'array') {\n return Array.isArray(shape.of) && shape.of.length > 0 && shape.fields === undefined\n }\n return shape.fields === undefined && shape.of === undefined\n}\n\nfunction compositeShapeMessage(input: unknown): string {\n const shape = asShape(input)\n if (shape.type === 'object') {\n return shape.of !== undefined\n ? 'an `object` kind declares its sub-fields with `fields`, not `of`'\n : 'an `object` kind needs a non-empty `fields` list of sub-field shapes'\n }\n if (shape.type === 'array') {\n return shape.fields !== undefined\n ? 'an `array` kind declares its item shape with `of`, not `fields`'\n : 'an `array` kind needs a non-empty `of` list of sub-field shapes'\n }\n return `\\`fields\\` / \\`of\\` are only valid on the \\`object\\` / \\`array\\` kinds, not \"${String(shape.type)}\"`\n}\n\n/** The first duplicated sub-field name in an object's `fields` / array's `of`,\n * or undefined when they are unique. Sub-field names key the value object, so a\n * duplicate would silently overwrite (last-wins) and drop a declared shape. */\nfunction duplicateSubfieldName(input: unknown): string | undefined {\n const shape = asShape(input)\n let list: unknown[] = []\n if (Array.isArray(shape.fields)) list = shape.fields\n else if (Array.isArray(shape.of)) list = shape.of\n const seen = new Set<string>()\n for (const item of list) {\n const name = asShape(item).name\n if (typeof name !== 'string') continue\n if (seen.has(name)) return name\n seen.add(name)\n }\n return undefined\n}\n\n/**\n * Build a strict object schema that also enforces the compositional-kind\n * contract. The `v.check`s are inlined here (not shared consts) so valibot\n * threads the object's output type through them — an extracted check loses that\n * inference and breaks the pipe.\n */\nfunction compositeChecked<TEntries extends v.ObjectEntries>(entries: TEntries) {\n return v.pipe(\n v.strictObject(entries),\n v.check(\n (input) => compositeShapeOk(input),\n (issue) => compositeShapeMessage(issue.input),\n ),\n v.check(\n (input) => duplicateSubfieldName(input) === undefined,\n (issue) =>\n `duplicate sub-field name \"${duplicateSubfieldName(issue.input)}\" — sub-field names must be unique within \\`fields\\` / \\`of\\``,\n ),\n )\n}\n\nexport interface FieldShape {\n type: (typeof FIELD_VALUE_KINDS)[number]\n name: string\n title?: string | undefined\n description?: string | undefined\n fields?: FieldShape[] | undefined\n of?: FieldShape[] | undefined\n}\n\nconst FieldShapeSchema: v.GenericSchema<FieldShape> = v.lazy(() =>\n compositeChecked({\n type: FieldValueKindSchema,\n name: FieldEntryName,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n fields: v.optional(v.array(FieldShapeSchema)),\n of: v.optional(v.array(FieldShapeSchema)),\n }),\n)\n\n/**\n * Declared editability of a field slot — the generic edit seam's gate. Default\n * (absent) is NOT editable: a slot is op-only engine working memory unless the\n * modeler opens it. The stored form is `true` (editable by anyone within the\n * slot's scope window) or a GROQ predicate over the rendered scope (`$actor`,\n * `$can`, `$fields`, `$assigned`), checked like an action filter to decide\n * who-may-edit. ADVISORY like every engine gate — it disables the inline field\n * and explains; real immutability needs a lake {@link Guard}.\n */\nconst StoredEditableSchema = v.union([v.literal(true), NonEmpty])\nexport type Editable = v.InferOutput<typeof StoredEditableSchema>\n\n/**\n * Authoring editability adds the `role[]` convenience: a non-empty role list\n * desugars to the same `count($actor.roles[@ in [...]]) > 0` membership\n * predicate `action.roles` produces. `true` opens the slot to anyone in its\n * window; a bare string is a raw predicate.\n */\nconst AuthoringEditableSchema = v.union([v.literal(true), v.array(NonEmpty), NonEmpty])\nexport type AuthoringEditable = v.InferOutput<typeof AuthoringEditableSchema>\n\n/** The slot-level concerns every field carries — name, labels, the seed recipe,\n * and who-may-edit — shared by raw entries and the `todoList`/`notes` list\n * sugars, parameterised over the `editable` grammar (stored is normalised;\n * authoring keeps `role[]`). */\nfunction slotFields<TEditable extends v.GenericSchema>(editable: TEditable) {\n return {\n name: FieldEntryName,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n /**\n * When true, the caller MUST supply this entry at start (via\n * `initialFields`) or spawn (via the parent's `subworkflows.with`). A\n * missing required entry throws rather than silently defaulting to\n * `null`/`[]` — the same fail-fast an action's `required` param gets.\n * Valid only on a workflow-scope `input`-sourced entry (deploy invariant).\n */\n required: v.optional(v.boolean()),\n /**\n * How this field SEEDS its value at materialisation — see\n * {@link FieldSourceSchema}. Optional: an absent `initialValue` is working\n * memory (the slot starts empty and an op fills it later), the common case.\n */\n initialValue: v.optional(FieldSourceSchema),\n /** Who-may-edit this slot via the edit seam — see {@link StoredEditableSchema}. */\n editable: v.optional(editable),\n }\n}\n\n/** Field-entry fields shared by the stored and authoring shapes: the slot-level\n * concerns plus the kind discriminator and the compositional `fields` / `of`. */\nfunction fieldEntryFields<TEditable extends v.GenericSchema>(editable: TEditable) {\n return {\n type: FieldKindSchema,\n ...slotFields(editable),\n /** Sub-field shapes for an `object` kind (see {@link compositeShapeOk}). */\n fields: v.optional(v.array(FieldShapeSchema)),\n /** Item sub-field shapes for an `array` kind (see {@link compositeShapeOk}). */\n of: v.optional(v.array(FieldShapeSchema)),\n }\n}\n\nconst FieldEntrySchema = compositeChecked(fieldEntryFields(StoredEditableSchema))\nexport type FieldEntry = v.InferOutput<typeof FieldEntrySchema>\n\nconst RawAuthoringFieldEntrySchema = compositeChecked(fieldEntryFields(AuthoringEditableSchema))\n\n/**\n * Authoring fields accept the raw entries plus the `claim` sugar type — the\n * field half of the mirrored claim pair. Expansion: an `actor` working-\n * memory slot (no `initialValue`; the claim action's op fills it), strictly\n * within this entry.\n */\nconst ClaimFieldSchema = v.strictObject({\n type: v.literal('claim'),\n name: FieldEntryName,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n})\n\n/** Fields shared by the `todoList` / `notes` list sugars — both desugar to an\n * `array` kind with a fixed `of`, so they accept the same slot-level concerns\n * a raw entry does (`initialValue` optional — absent is working memory, the\n * common case for a list ops append rows to). */\nfunction listSugarFields<const TType extends string>(type: TType) {\n return {\n type: v.literal(type),\n ...slotFields(AuthoringEditableSchema),\n }\n}\n\n/**\n * `todoList` — ad-hoc, status-tracked work items. Sugar over `array of object\n * { label, status, assignee?, dueDate? }`; a plain checklist is this used with\n * `{label, status}` only (open ↔ done). Never a stored kind.\n */\nconst TodoListFieldSchema = v.strictObject(listSugarFields('todoList'))\n\n/**\n * `notes` — an append-only audit/comment log. Sugar over `array of object\n * { body, actor, at }` (the `actor`/`at` sub-fields match the `audit` op's\n * stamp names, so it pairs with it). Never a stored kind.\n */\nconst NotesFieldSchema = v.strictObject(listSugarFields('notes'))\n\nexport const AuthoringFieldEntrySchema = v.union([\n RawAuthoringFieldEntrySchema,\n ClaimFieldSchema,\n TodoListFieldSchema,\n NotesFieldSchema,\n])\nexport type AuthoringFieldEntry = v.InferOutput<typeof AuthoringFieldEntrySchema>\n\n// Conditions are raw GROQ strings over the rendered scope — built-in vars\n// ($fields, $actor, $assigned, $can, $row, $effects, $subworkflows, $activities,\n// $now, $allActivitiesDone, $anyActivityFailed) plus the author's nullary predicates.\n// There is no {ref, args} wrapper; parameterized reuse is a define-time\n// TypeScript function (see the `groq` tag in ./groq.ts).\n\nconst ConditionSchema = NonEmpty\nexport type Condition = string\n\n// Effects — the registry model. `name` is the effect's only identity; the\n// host app registers a handler against it (1:1) and the stored definition\n// never references code. Names are unique per definition (invariant) so\n// `$effects.<name>` is unambiguous.\n\nexport const EffectSchema = v.strictObject({\n name: NonEmpty,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n /** GROQ reads over the rendered scope, resolved to concrete JSON at queue time. */\n bindings: v.optional(v.record(v.string(), ConditionSchema)),\n /** Static config, passed through to the handler verbatim. */\n input: v.optional(v.record(v.string(), v.unknown())),\n})\nexport type Effect = v.InferOutput<typeof EffectSchema>\n\n// Actions\n\n/**\n * Caller-supplied params declared on an action. The engine validates\n * incoming `params` against this list before running ops or queuing\n * effects: missing required params → ActionParamsInvalidError, action\n * does not commit. Resolved values feed `ValueExpr.param` lookups.\n */\nconst ActionParamSchema = v.strictObject({\n type: picklist([\n 'string',\n 'number',\n 'boolean',\n 'url',\n 'dateTime',\n 'actor',\n 'doc.ref',\n 'doc.refs',\n 'json',\n ]),\n name: NonEmpty,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n required: v.optional(v.boolean()),\n})\nexport type ActionParam = v.InferOutput<typeof ActionParamSchema>\n\n/** Fields shared by the stored and authoring action shapes, parameterised\n * over the op schema (stored ops are fully resolved; authoring ops keep\n * their sugar). */\nfunction actionFields<TOp extends v.GenericSchema>(op: TOp) {\n return {\n name: NonEmpty,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n /**\n * The one gate mechanism: a condition over the rendered scope. Hard\n * enforcement lives outside the engine entirely (the lake ACL on the\n * documents, and guards) — every engine-evaluated gate is authoring/UX.\n */\n filter: v.optional(ConditionSchema),\n params: v.optional(v.array(ActionParamSchema)),\n ops: v.optional(v.array(op)),\n effects: v.optional(v.array(EffectSchema)),\n }\n}\n\nconst StoredActionSchema = v.strictObject(actionFields(StoredOpSchema))\nexport type Action = v.InferOutput<typeof StoredActionSchema>\n\nconst TerminalActivityStatus = picklist(TERMINAL_ACTIVITY_STATUSES)\n\n/**\n * Authoring action — the stored fields plus two field sugars with one\n * defined expansion each:\n *\n * - `roles` → a `count($actor.roles[@ in [...]]) > 0` membership condition\n * ANDed with the authored `filter`. The definition's `roleAliases`\n * ({@link RoleAliasesSchema}) widen that membership at desugar time.\n * - `status` → a `status.set` op on the firing activity, appended **after**\n * the authored ops (deliberately never implied: a forgotten explicit\n * `status` is a visible stall, an implied default silently completes\n * claim-like actions).\n */\nconst RawAuthoringActionSchema = v.strictObject({\n ...actionFields(AuthoringOpSchema),\n roles: v.optional(v.array(NonEmpty)),\n status: v.optional(TerminalActivityStatus),\n})\n\n/**\n * The action half of the mirrored claim pair. `field` references an\n * author-declared actor-valued entry (the pair's other half), resolved\n * lexically. Expansion, strictly within this action: a no-steal\n * `!defined($fields.<field>)` filter ANDed with `roles`/`filter`, plus a\n * `field.set` ← actor op. `ops` and `status` are reserved (the expansion\n * owns them) — strictObject rejects them as unknown keys.\n */\nconst ClaimActionSchema = v.strictObject({\n type: v.literal('claim'),\n name: NonEmpty,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n field: v.union([NonEmpty, AuthoringFieldRefSchema]),\n roles: v.optional(v.array(NonEmpty)),\n filter: v.optional(ConditionSchema),\n params: v.optional(v.array(ActionParamSchema)),\n effects: v.optional(v.array(EffectSchema)),\n})\n\nexport const AuthoringActionSchema = v.union([RawAuthoringActionSchema, ClaimActionSchema])\nexport type AuthoringAction = v.InferOutput<typeof AuthoringActionSchema>\n\n// Subworkflows — declare `subworkflows`, read `$subworkflows`. The spawning\n// activity resolves like any activity: `completeWhen` / `failWhen` over the rendered\n// `$subworkflows`; no `completeWhen` means all subworkflows done.\n\n/**\n * Logical reference to a deployed workflow definition, by its `name` (the\n * stable contract — the tag can be renamed, workflows redeployed). The engine\n * resolves it at spawn time, ordering by `version desc` unless an explicit\n * `version` pins one.\n */\nconst DefinitionRefSchema = v.strictObject({\n name: NonEmpty,\n version: v.optional(v.union([PositiveInt, v.literal('latest')])),\n})\n\nconst SubworkflowsSchema = v.strictObject({\n /** GROQ producing one row per subworkflow; each row binds as `$row`. */\n forEach: NonEmpty,\n definition: DefinitionRefSchema,\n /** Initial fields for each subworkflow — entry name → GROQ over `$row` + the parent scope. */\n with: v.optional(v.record(NonEmpty, ConditionSchema)),\n /**\n * Extra values evaluated in the parent's rendered scope at spawn time and\n * delivered into each subworkflow's `$effects` bag — the parent→child\n * handoff, read exactly like an effect output.\n */\n context: v.optional(v.record(NonEmpty, ConditionSchema)),\n})\nexport type Subworkflows = v.InferOutput<typeof SubworkflowsSchema>\n\n// Activities — activities own the ENTER moment: `ops` + `effects` run at activation,\n// `filter` makes activation conditional on the stage's entry fields, and\n// `activation` switches the stage-enter flip (default `manual`: an activity never\n// activates silently; \"auto\" is the explicit opt-in). An activity with no actions\n// and no `completeWhen` is a machine step — it runs its activation payload\n// and resolves `done` immediately, leaving an audit row.\n\nfunction activityFields<\n TField extends v.GenericSchema,\n TAction extends v.GenericSchema,\n TOp extends v.GenericSchema,\n TTarget extends v.GenericSchema,\n>(field: TField, action: TAction, op: TOp, target: TTarget) {\n return {\n name: NonEmpty,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n /**\n * Advisory BPMN-aligned classification of this activity by its executor (see\n * {@link ACTIVITY_KINDS}). Optional and derived from the activity's shape when\n * omitted; declaring it lets deploy check the shape matches the lane.\n * Changes no gating or resolution — a label for tooling, like `assignees`.\n */\n kind: v.optional(picklist(ACTIVITY_KINDS)),\n /** Deep-link target for a `kind: \"manual\"` activity (off-system work). Render-only\n * metadata; only valid on a manual activity (deploy-checked). */\n target: v.optional(target),\n activation: v.optional(picklist(['auto', 'manual'])),\n filter: v.optional(ConditionSchema),\n /**\n * Readiness gates, by name — conditions over the rendered scope that must\n * hold for the activity to be *executable*, orthogonal to `filter`\n * (visibility). An unmet requirement keeps the activity visible but disables\n * its actions with a `requirements-unmet` verdict naming the unmet keys;\n * all must hold (any-of lives inside one condition). Advisory like every\n * engine gate — the lake still enforces. Distinct from ACL (authorization)\n * and guards (content-write locks).\n */\n requirements: v.optional(v.record(NonEmpty, ConditionSchema)),\n /**\n * Auto-completion condition — evaluated at activation and on every\n * cascade; truthy flips the activity to `done` with a system actor. On a\n * spawning activity it typically reads `$subworkflows`.\n */\n completeWhen: v.optional(ConditionSchema),\n /**\n * Auto-failure condition — symmetric to `completeWhen`, flips to\n * `failed`. When both are truthy on the same evaluation, `failWhen`\n * wins — failure is the more notable signal.\n */\n failWhen: v.optional(ConditionSchema),\n ops: v.optional(v.array(op)),\n effects: v.optional(v.array(EffectSchema)),\n actions: v.optional(v.array(action)),\n subworkflows: v.optional(SubworkflowsSchema),\n /** Activity-scoped field entries. Resolved at activity activation time. */\n fields: v.optional(v.array(field)),\n }\n}\n\nconst StoredActivitySchema = v.strictObject(\n activityFields(FieldEntrySchema, StoredActionSchema, StoredOpSchema, StoredManualTargetSchema),\n)\nexport type Activity = v.InferOutput<typeof StoredActivitySchema>\n\nexport const AuthoringActivitySchema = v.strictObject(\n activityFields(\n AuthoringFieldEntrySchema,\n AuthoringActionSchema,\n AuthoringOpSchema,\n AuthoringManualTargetSchema,\n ),\n)\nexport type AuthoringActivity = v.InferOutput<typeof AuthoringActivitySchema>\n\n// Transitions — purely a condition over the rendered scope. Selection rule:\n// every transition is evaluated on every commit and cascade; the first truthy\n// `filter` in declaration order fires. No action coupling: a routing\n// difference is written into fields by the action and read by the filter.\n\nfunction transitionFields<TOp extends v.GenericSchema, TFilter extends v.GenericSchema>(\n op: TOp,\n filter: TFilter,\n) {\n return {\n name: NonEmpty,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n to: NonEmpty,\n filter,\n /** The `field.*` subset — field-write-on-move, the stage's EXIT/ARRIVAL payload. */\n ops: v.optional(v.array(op)),\n effects: v.optional(v.array(EffectSchema)),\n }\n}\n\nconst StoredTransitionSchema = v.strictObject(\n transitionFields(StoredTransitionOpSchema, ConditionSchema),\n)\nexport type Transition = v.InferOutput<typeof StoredTransitionSchema>\n\n/**\n * Authoring transitions may omit `filter`; desugar fills the safe,\n * overwhelmingly-common gate `\"$allActivitiesDone\"`. \"Fire unconditionally\"\n * stays spellable as an explicit `filter: \"true\"`.\n */\nconst AuthoringTransitionOpSchema = v.variant('type', [\n ...opSchemas(AuthoringFieldRefSchema),\n AuditOpSchema,\n])\nexport const AuthoringTransitionSchema = v.strictObject(\n transitionFields(AuthoringTransitionOpSchema, v.optional(ConditionSchema)),\n)\nexport type AuthoringTransition = v.InferOutput<typeof AuthoringTransitionSchema>\n\n// Guards — lake mutation guards. A FOREIGN CONTRACT mirrored 1:1: the\n// `temp.system.guard` doc's `match` / `predicate` / `metadata` fields are the\n// content lake's API, not engine surface, so authoring keeps the lake's\n// vocabulary verbatim. The engine adds exactly two things: `name` (authoring\n// identity — the lake `_id` derives from (instanceId, guard.name)) and\n// `$fields`-read VALUES (`idRefs: [\"$fields.subject\"]`, `metadata.outcome:\n// \"$fields.outcome\"`), resolved at deploy into the bare values the contract\n// expects. Guards + the lake ACL are the only HARD gates in the system.\n\nconst GuardActionSchema = picklist(MUTATION_GUARD_ACTIONS)\nexport type GuardAction = v.InferOutput<typeof GuardActionSchema>\n\nconst GuardMatchSchema = v.strictObject({\n /** Subject `_type`(s); empty matches any type. */\n types: v.optional(v.array(NonEmpty)),\n /** Target docs as `$fields` reads (or `\"$self\"`), resolved at deploy to bare ids + the resource. */\n idRefs: v.optional(v.array(NonEmpty)),\n /** Glob id patterns (bare, resource-local). */\n idPatterns: v.optional(v.array(NonEmpty)),\n actions: v.pipe(\n v.array(GuardActionSchema),\n v.minLength(1, 'a guard must match at least one action'),\n ),\n})\nexport type GuardMatch = v.InferOutput<typeof GuardMatchSchema>\n\nexport const GuardSchema = v.strictObject({\n name: NonEmpty,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n match: GuardMatchSchema,\n /**\n * Lake GROQ predicate — a distinct eval context reading\n * `document.before`/`document.after`, `mutation`, `guard`, and\n * `identity()`. Bare ids/fields only. Omitted or empty means\n * UNCONDITIONAL DENY.\n */\n predicate: v.optional(v.string()),\n /**\n * Projected workflow fields the predicate reads as `guard.metadata.*` —\n * the only bridge from the lake eval context (which cannot see `$fields`)\n * to workflow fields. Values are NOT GROQ: each is a deploy-time read in\n * the guard mini-language — `\"$self\"`, `\"$now\"`, or\n * `\"$fields.<name>[.path]\"` — resolved into a bare value at deploy and\n * re-synced by the post-field-op guard refresh.\n */\n metadata: v.optional(v.record(NonEmpty, NonEmpty)),\n})\nexport type Guard = v.InferOutput<typeof GuardSchema>\n\n// Stages — pure containers: name / fields / guards / activities / transitions, no\n// behaviour of their own. Activities own enter, transitions own exit and arrival.\n// `initial` is whatever `initialStage` names; a stage with no transitions IS\n// terminal (structural, nothing to declare or mis-declare).\n\nfunction stageFields<\n TField extends v.GenericSchema,\n TActivity extends v.GenericSchema,\n TTransition extends v.GenericSchema,\n TEditable extends v.GenericSchema,\n>(field: TField, activity: TActivity, transition: TTransition, editable: TEditable) {\n return {\n name: NonEmpty,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n activities: v.optional(v.array(activity)),\n transitions: v.optional(v.array(transition)),\n /**\n * Lake mutation guards active while this stage holds. Each compiles to a\n * `temp.system.guard` doc deployed on stage entry and retracted on exit.\n */\n guards: v.optional(v.array(GuardSchema)),\n /** Stage-scoped field entries. Resolved at stage entry. */\n fields: v.optional(v.array(field)),\n /**\n * Tighten-only editability overrides for the time this stage holds, keyed\n * by an in-scope slot name. The slot's own `editable` is the ceiling; a\n * stage value is ANDed with it at runtime, so an override can only NARROW\n * (never open a slot the baseline left closed). An unlisted slot inherits\n * its baseline.\n */\n editable: v.optional(v.record(FieldEntryName, editable)),\n }\n}\n\nconst StoredStageSchema = v.strictObject(\n stageFields(FieldEntrySchema, StoredActivitySchema, StoredTransitionSchema, StoredEditableSchema),\n)\nexport type Stage = v.InferOutput<typeof StoredStageSchema>\n\nexport const AuthoringStageSchema = v.strictObject(\n stageFields(\n AuthoringFieldEntrySchema,\n AuthoringActivitySchema,\n AuthoringTransitionSchema,\n AuthoringEditableSchema,\n ),\n)\nexport type AuthoringStage = v.InferOutput<typeof AuthoringStageSchema>\n\n// Workflow definition (the root)\n\n/**\n * Role aliasing — the \"can be fulfilled by\" map, an authoring convenience.\n * A `roles` gate (or an `assignees` entry) names the role the author writes;\n * but the SAME capability is often carried by different role names depending\n * on how a given project deploys its Content Lake roles, and several roles may\n * legitimately do the job. Rather than enumerate every equivalent role inline\n * in each gate — or fork the definition per deployment — declare once here\n * which other roles also fulfill it.\n *\n * Each key is a role a gate/assignee names; its value lists the roles that\n * also satisfy it. The reserved key `\"*\"` lists roles that fulfill ANY gate\n * (e.g. `\"*\": [\"administrator\"]` — whatever this deployment's broad role is).\n * `\"*\"` is the spelling authors write; it is rewritten to a lake-safe stored\n * key before the definition is persisted, since the Content Lake rejects `\"*\"`\n * as a document attribute name (see {@link normalizeRoleAliases}).\n *\n * Applied as an in-place expansion of the REQUIRED side, never the actor's\n * roles: the `roles` gate bakes the expanded membership into its desugared\n * GROQ at define time; `$assigned` expands the assignee's role at match time\n * (see {@link expandRequiredRoles}). Carried into the stored definition for\n * that runtime half.\n *\n * Advisory, like every engine gate — an alias only predicts what the\n * deployment's Content Lake ACLs already allow, it never grants access. An\n * alias the lake won't honor makes the gate predict \"allowed\" for a write the\n * lake then rejects, so keep it true to what's actually deployed.\n */\nconst RoleAliasesSchema = v.record(\n NonEmpty,\n v.pipe(v.array(NonEmpty), v.minLength(1, 'a role alias must list at least one fulfilling role')),\n)\nexport type RoleAliases = v.InferOutput<typeof RoleAliasesSchema>\n\nconst WORKFLOW_ROLES = ['workflow', 'child'] as const\n/** A definition's lifecycle role. `'child'` is spawn-only — see {@link isStartableDefinition}. */\nexport type WorkflowRole = (typeof WORKFLOW_ROLES)[number]\n\nfunction workflowFields<TField extends v.GenericSchema, TStage extends v.GenericSchema>(\n field: TField,\n stage: TStage,\n) {\n return {\n name: NonEmpty,\n title: NonEmpty,\n description: v.optional(v.string()),\n /**\n * Whether a human may start this workflow standalone. `'child'` marks a\n * spawn-only definition — instantiated by a parent via `activity.subworkflows`,\n * never started cold from a picker. Omitted ⇒ `'workflow'` (startable).\n * Advisory: consumers filter their start pickers on it (see\n * {@link isStartableDefinition}); the engine does NOT refuse a\n * `startInstance` on a `'child'` def — load-bearing `required` field is the\n * runtime backstop.\n */\n role: v.optional(picklist(WORKFLOW_ROLES)),\n /** Reference field: named for the target, holds the stage's `name`. */\n initialStage: NonEmpty,\n /** Workflow-scope field entries. Persist for the instance lifetime. */\n fields: v.optional(v.array(field)),\n stages: v.pipe(v.array(stage), v.minLength(1, 'must declare at least one stage')),\n /**\n * Nullary named conditions — each `name: groq` entry is pre-evaluated\n * and bound as the boolean `$name` var, composable with native GROQ.\n * Redefining a built-in var is a deploy error (never silently shadow).\n */\n predicates: v.optional(v.record(groqIdentifier('`$<name>`'), ConditionSchema)),\n /** Role aliasing for this definition — see {@link RoleAliasesSchema}. */\n roleAliases: v.optional(RoleAliasesSchema),\n }\n}\n\n/**\n * Structural schema for a STORED workflow definition — primitives only,\n * every reference scope resolved. Cross-field invariants (unique names,\n * transition targets, effect-name uniqueness, predicate shadowing) are\n * checked by `checkWorkflowInvariants` after desugar — see `defineWorkflow`.\n *\n * Carries NO `version` — the author never writes one. A definition's version\n * (and its content fingerprint) are stamped onto the deployed *document* at\n * deploy time, derived from the content itself; see `DeployedDefinition` and\n * `planDefinitionDeploy` in `api/deploy.ts`. The author's content is the sole\n * source of identity: redeploying identical content is a no-op, any change\n * mints the next version.\n */\nconst WorkflowDefinitionSchema = v.strictObject(workflowFields(FieldEntrySchema, StoredStageSchema))\nexport type WorkflowDefinition = v.InferOutput<typeof WorkflowDefinitionSchema>\n\n/** The authoring surface: stored primitives plus the define-time sugar. */\nexport const AuthoringWorkflowSchema = v.strictObject(\n workflowFields(AuthoringFieldEntrySchema, AuthoringStageSchema),\n)\nexport type AuthoringWorkflow = v.InferOutput<typeof AuthoringWorkflowSchema>\n\n/**\n * The lake document type for a deployed workflow definition. Engine-owned\n * standalone documents carry the platform namespace; in-array discriminators\n * stay bare. Mirrors {@link WORKFLOW_INSTANCE_TYPE}.\n */\nexport const WORKFLOW_DEFINITION_TYPE = 'sanity.workflow.definition'\n\n/**\n * Whether a human may start this definition standalone (the default). A\n * `role: 'child'` definition is spawn-only — instantiated by a parent via\n * `activity.subworkflows`, so consumers exclude it from top-level start pickers.\n * Advisory: the engine does not enforce it (see the `required`-field backstop\n * for load-bearing input slots). Accepts any definition-shaped value (authored,\n * stored, deployed, or a projected list row).\n */\nexport function isStartableDefinition(definition: {role?: WorkflowRole | undefined}): boolean {\n return definition.role !== 'child'\n}\n\n// Error formatting — turn validation issues into a multi-line,\n// path-prefixed message that points at the exact field the author got\n// wrong. Shared by structural parse errors (via {@link issuesFromValibot})\n// and cross-field invariant issues.\n\nexport interface ValidationIssue {\n path: ReadonlyArray<PropertyKey>\n message: string\n}\n\n/** The buildable path form desugar and the invariants accumulate issues under. */\nexport type IssuePath = (string | number)[]\n\nexport function formatValidationError(label: string, issues: readonly ValidationIssue[]): string {\n const lines = issues.map((issue) => {\n const path = issue.path.length === 0 ? '(root)' : formatPath(issue.path)\n return ` - ${path}: ${issue.message}`\n })\n return `${label} failed validation (${issues.length} issue${\n issues.length === 1 ? '' : 's'\n }):\\n${lines.join('\\n')}`\n}\n\nexport function issuesFromValibot(issues: readonly v.BaseIssue<unknown>[]): ValidationIssue[] {\n return issues.map((issue) => ({\n path: issue.path ? issue.path.map((item) => item.key as PropertyKey) : [],\n message: issue.message,\n }))\n}\n\nfunction formatPath(path: ReadonlyArray<PropertyKey>): string {\n let out = ''\n for (const seg of path) {\n if (typeof seg === 'number') out += `[${seg}]`\n else out += out.length === 0 ? String(seg) : `.${String(seg)}`\n }\n return out\n}\n"],"names":["v"],"mappings":";;;;;;;;;;;;;;;;;;AAeO,SAAS,cAAc,OAA4D;AACxF,QAAM,UAAU,MAAM,OAAO,CAAC,MAAmB,MAAM,MAAS;AAChE,MAAI,QAAQ,WAAW;AACvB,WAAI,QAAQ,WAAW,IAAU,QAAQ,CAAC,IACnC,QAAQ,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,KAAK,MAAM;AACjD;ACIO,MAAM,2BAA2B;AAWjC,SAAS,qBAAqB,SAA2D;AAC9F,MAAI,YAAY,UAAa,EAAE,OAAqC,SAAU,QAAO;AACrF,QAAM,EAAC,CAAC,GAAiC,GAAG,WAAW,GAAG,YAAW;AACrE,SAAO,EAAC,GAAG,SAAS,CAAC,wBAAwB,GAAG,UAAA;AAClD;AAaO,SAAS,oBACd,UACA,SACU;AACV,MAAI,YAAY,OAAW,QAAO,CAAC,GAAG,QAAQ;AAC9C,QAAM,0BAAU,IAAA;AAChB,aAAW,QAAQ,UAAU;AAC3B,QAAI,IAAI,IAAI;AACZ,eAAW,aAAa,QAAQ,IAAI,KAAK,CAAA,EAAI,KAAI,IAAI,SAAS;AAAA,EAChE;AACA,aAAW,aAAa,QAAQ,wBAAwB,KAAK,CAAA,EAAI,KAAI,IAAI,SAAS;AAClF,SAAO,CAAC,GAAG,GAAG;AAChB;AAOO,SAAS,kBACd,YACA,UACA,SACS;AACT,MAAI,eAAe,UAAa,WAAW,WAAW,EAAG,QAAO;AAChE,QAAM,WAAW,IAAI,IAAI,oBAAoB,CAAC,QAAQ,GAAG,OAAO,CAAC;AACjE,SAAO,WAAW,KAAK,CAAC,SAAS,SAAS,IAAI,IAAI,CAAC;AACrD;AClEO,MAAM,oBAAoB,CAAC,WAAW,UAAU,QAAQ,WAAW,QAAQ,GAKrE,6BAA6B,CAAC,QAAQ,WAAW,QAAQ;AAG/D,SAAS,yBAAyB,QAA0D;AACjG,SAAQ,2BAAyD,SAAS,MAAM;AAClF;AAIO,MAAM,eAAe,CAAC,YAAY,SAAS,UAAU,GAK/C,6BAA6B,CAAC,UAAU,QAAQ,QAAQ,GAKxD,yBAAyB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GASa,iBAAiB,CAAC,QAAQ,WAAW,UAAU,UAAU,SAAS,GAOlE,eAAe,CAAC,UAAU,SAAS,WAAW,QAAQ,GCxB7D,WAAWA,aAAE,KAAKA,aAAE,UAAUA,aAAE,UAAU,GAAG,4BAA4B,CAAC,GAE1E,cAAcA,aAAE,KAAKA,aAAE,UAAUA,aAAE,WAAWA,aAAE,SAAS,CAAC,CAAC,GASpD,kBAAkB;AAE/B,SAAS,eAAe,cAAsB;AAC5C,SAAOA,aAAE;AAAA,IACPA,aAAE,OAAA;AAAA,IACFA,aAAE;AAAA,MACA;AAAA,MACA,uHACiC,YAAY;AAAA,IAAA;AAAA,EAC/C;AAEJ;AAOA,SAAS,SAAgE,SAAmB;AAC1F,SAAOA,aAAE;AAAA,IACP;AAAA,IACA,mCAAmC,QAAQ,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,EAAE,KAAK,GAAG,CAAC;AAAA,EAAA;AAE7E;AAgBA,MAAM,gBAAgBA,aAAE,aAAa,EAAC,MAAMA,aAAE,QAAQ,SAAS,GAAG,OAAOA,aAAE,QAAA,EAAQ,CAAE,GAC/E,kBAAkBA,aAAE,aAAa;AAAA,EACrC,MAAMA,aAAE,QAAQ,WAAW;AAAA,EAC3B,OAAOA,aAAE,SAASA,aAAE,MAAM,CAACA,aAAE,QAAQ,UAAU,GAAGA,aAAE,QAAQ,OAAO,CAAC,CAAC,CAAC;AAAA,EACtE,OAAO;AAAA,EACP,MAAMA,aAAE,SAASA,aAAE,QAAQ;AAC7B,CAAC,GAcK,oBAA0DA,aAAE,MAAM;AAAA;AAAA,EAEtEA,aAAE,aAAa,EAAC,MAAMA,aAAE,QAAQ,OAAO,GAAE;AAAA;AAAA,EAEzCA,aAAE,aAAa,EAAC,MAAMA,aAAE,QAAQ,OAAO,GAAG,OAAO,UAAS;AAAA,EAC1D;AAAA,EACA;AACF,CAAC,GAiBK,kBAAsDA,aAAE;AAAA,EAAK,MACjEA,aAAE,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACAA,aAAE,aAAa,EAAC,MAAMA,aAAE,QAAQ,OAAO,GAAG,OAAO,UAAS;AAAA,IAC1DA,aAAE,aAAa,EAAC,MAAMA,aAAE,QAAQ,OAAO,GAAE;AAAA,IACzCA,aAAE,aAAa,EAAC,MAAMA,aAAE,QAAQ,KAAK,GAAE;AAAA,IACvCA,aAAE,aAAa,EAAC,MAAMA,aAAE,QAAQ,MAAM,GAAE;AAAA,IACxCA,aAAE,aAAa,EAAC,MAAMA,aAAE,QAAQ,OAAO,GAAE;AAAA,IACzCA,aAAE,aAAa,EAAC,MAAMA,aAAE,QAAQ,QAAQ,GAAG,QAAQA,aAAE,OAAO,UAAU,eAAe,GAAE;AAAA,EAAA,CACxF;AACH,GAOM,uBAAuBA,aAAE,aAAa;AAAA,EAC1C,OAAO,SAAS,YAAY;AAAA,EAC5B,OAAO;AACT,CAAC,GAGK,0BAA0BA,aAAE,aAAa;AAAA,EAC7C,OAAOA,aAAE,SAAS,SAAS,YAAY,CAAC;AAAA,EACxC,OAAO;AACT,CAAC,GAWK,eAAe,CAAC,SAAS,QAAQ;AAIvC,SAAS,UAAU,OAAwB;AACzC,MAAI;AACF,WAAO,aAAa,SAAS,IAAI,IAAI,KAAK,EAAE,QAAQ;AAAA,EACtD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AACA,MAAM,YAAYA,aAAE;AAAA,EAClBA,aAAE,OAAA;AAAA,EACFA,aAAE,IAAI,qBAAqB;AAAA,EAC3BA,aAAE,MAAM,WAAW,wBAAwB;AAC7C;AAEA,SAAS,mBAAiD,KAAW;AACnE,SAAOA,aAAE,QAAQ,QAAQ;AAAA,IACvBA,aAAE,aAAa,EAAC,MAAMA,aAAE,QAAQ,KAAK,GAAG,KAAK,WAAU;AAAA,IACvDA,aAAE,aAAa,EAAC,MAAMA,aAAE,QAAQ,OAAO,GAAG,OAAO,IAAA,CAAI;AAAA,EAAA,CACtD;AACH;AAEA,MAAM,2BAA2B,mBAAmB,oBAAoB,GAKlE,8BAA8B,mBAAmBA,aAAE,MAAM,CAAC,UAAU,uBAAuB,CAAC,CAAC,GAY7F,oBAA0DA,aAAE;AAAA,EAAK,MACrEA,aAAE,MAAM;AAAA,IACNA,aAAE,aAAa;AAAA,MACb,MAAMA,aAAE,QAAQ,OAAO;AAAA,MACvB,OAAO;AAAA,MACP,QAAQ;AAAA,IAAA,CACT;AAAA,IACDA,aAAE,aAAa,EAAC,MAAMA,aAAE,QAAQ,KAAK,GAAG,IAAIA,aAAE,MAAM,iBAAiB,GAAE;AAAA,IACvEA,aAAE,aAAa,EAAC,MAAMA,aAAE,QAAQ,KAAK,GAAG,IAAIA,aAAE,MAAM,iBAAiB,GAAE;AAAA,EAAA,CACxE;AACH;AAOA,SAAS,UAAqC,cAAiB;AAC7D,SAAO;AAAA,IACLA,aAAE,aAAa;AAAA,MACb,MAAMA,aAAE,QAAQ,WAAW;AAAA,MAC3B,QAAQ;AAAA,MACR,OAAO;AAAA,IAAA,CACR;AAAA,IACDA,aAAE,aAAa;AAAA,MACb,MAAMA,aAAE,QAAQ,aAAa;AAAA,MAC7B,QAAQ;AAAA,IAAA,CACT;AAAA,IACDA,aAAE,aAAa;AAAA,MACb,MAAMA,aAAE,QAAQ,cAAc;AAAA,MAC9B,QAAQ;AAAA,MACR,OAAO;AAAA,IAAA,CACR;AAAA,IACDA,aAAE,aAAa;AAAA,MACb,MAAMA,aAAE,QAAQ,mBAAmB;AAAA,MACnC,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,OAAO;AAAA,IAAA,CACR;AAAA,IACDA,aAAE,aAAa;AAAA,MACb,MAAMA,aAAE,QAAQ,mBAAmB;AAAA,MACnC,QAAQ;AAAA,MACR,OAAO;AAAA,IAAA,CACR;AAAA,EAAA;AAEL;AAEA,MAAM,iBAAiBA,aAAE,QAAQ,QAAQ;AAAA,EACvC,GAAG,UAAU,oBAAoB;AAAA,EACjCA,aAAE,aAAa;AAAA,IACb,MAAMA,aAAE,QAAQ,YAAY;AAAA,IAC5B,UAAU;AAAA,IACV,QAAQ,SAAS,iBAAiB;AAAA,EAAA,CACnC;AACH,CAAC,GAQK,2BAA2BA,aAAE,QAAQ,QAAQ,CAAC,GAAG,UAAU,oBAAoB,CAAC,CAAC,GAOjF,gBAAgBA,aAAE,aAAa;AAAA,EACnC,MAAMA,aAAE,QAAQ,OAAO;AAAA,EACvB,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,aAAaA,aAAE;AAAA,IACbA,aAAE,aAAa;AAAA,MACb,OAAOA,aAAE,SAAS,QAAQ;AAAA,MAC1B,IAAIA,aAAE,SAAS,QAAQ;AAAA,IAAA,CACxB;AAAA,EAAA;AAEL,CAAC,GAEY,oBAAoBA,aAAE,QAAQ,QAAQ;AAAA,EACjD,GAAG,UAAU,uBAAuB;AAAA,EACpCA,aAAE,aAAa;AAAA,IACb,MAAMA,aAAE,QAAQ,YAAY;AAAA,IAC5B,UAAUA,aAAE,SAAS,QAAQ;AAAA,IAC7B,QAAQ,SAAS,iBAAiB;AAAA,EAAA,CACnC;AAAA,EACD;AACF,CAAC,GAaK,oBAAoB;AAAA,EACxB;AAAA,EACA;AAAA;AAAA;AAAA;AAAA,EAIA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA;AAAA;AAAA,EAGA;AAAA;AAAA,EAEA;AAAA,EACA;AACF,GAEM,uBAAuB,SAAS,iBAAiB,GAEjD,kBAAkB,SAAS,iBAAiB,GAE5C,iBAAiB,eAAe,kBAAkB;AAQxD,SAAS,QAAQ,OAKf;AACA,SAAO,OAAO,SAAU,YAAY,UAAU,OAAO,QAAQ,CAAA;AAC/D;AAQA,SAAS,iBAAiB,OAAyB;AACjD,QAAM,QAAQ,QAAQ,KAAK;AAC3B,SAAI,MAAM,SAAS,WACV,MAAM,QAAQ,MAAM,MAAM,KAAK,MAAM,OAAO,SAAS,KAAK,MAAM,OAAO,SAE5E,MAAM,SAAS,UACV,MAAM,QAAQ,MAAM,EAAE,KAAK,MAAM,GAAG,SAAS,KAAK,MAAM,WAAW,SAErE,MAAM,WAAW,UAAa,MAAM,OAAO;AACpD;AAEA,SAAS,sBAAsB,OAAwB;AACrD,QAAM,QAAQ,QAAQ,KAAK;AAC3B,SAAI,MAAM,SAAS,WACV,MAAM,OAAO,SAChB,qEACA,yEAEF,MAAM,SAAS,UACV,MAAM,WAAW,SACpB,oEACA,oEAEC,gFAAgF,OAAO,MAAM,IAAI,CAAC;AAC3G;AAKA,SAAS,sBAAsB,OAAoC;AACjE,QAAM,QAAQ,QAAQ,KAAK;AAC3B,MAAI,OAAkB,CAAA;AAClB,QAAM,QAAQ,MAAM,MAAM,IAAG,OAAO,MAAM,SACrC,MAAM,QAAQ,MAAM,EAAE,MAAG,OAAO,MAAM;AAC/C,QAAM,2BAAW,IAAA;AACjB,aAAW,QAAQ,MAAM;AACvB,UAAM,OAAO,QAAQ,IAAI,EAAE;AAC3B,QAAI,OAAO,QAAS,UACpB;AAAA,UAAI,KAAK,IAAI,IAAI,EAAG,QAAO;AAC3B,WAAK,IAAI,IAAI;AAAA,IAAA;AAAA,EACf;AAEF;AAQA,SAAS,iBAAmD,SAAmB;AAC7E,SAAOA,aAAE;AAAA,IACPA,aAAE,aAAa,OAAO;AAAA,IACtBA,aAAE;AAAA,MACA,CAAC,UAAU,iBAAiB,KAAK;AAAA,MACjC,CAAC,UAAU,sBAAsB,MAAM,KAAK;AAAA,IAAA;AAAA,IAE9CA,aAAE;AAAA,MACA,CAAC,UAAU,sBAAsB,KAAK,MAAM;AAAA,MAC5C,CAAC,UACC,6BAA6B,sBAAsB,MAAM,KAAK,CAAC;AAAA,IAAA;AAAA,EACnE;AAEJ;AAWA,MAAM,mBAAgDA,aAAE;AAAA,EAAK,MAC3D,iBAAiB;AAAA,IACf,MAAM;AAAA,IACN,MAAM;AAAA,IACN,OAAOA,aAAE,SAASA,aAAE,QAAQ;AAAA,IAC5B,aAAaA,aAAE,SAASA,aAAE,QAAQ;AAAA,IAClC,QAAQA,aAAE,SAASA,aAAE,MAAM,gBAAgB,CAAC;AAAA,IAC5C,IAAIA,aAAE,SAASA,aAAE,MAAM,gBAAgB,CAAC;AAAA,EAAA,CACzC;AACH,GAWM,uBAAuBA,aAAE,MAAM,CAACA,aAAE,QAAQ,EAAI,GAAG,QAAQ,CAAC,GAS1D,0BAA0BA,aAAE,MAAM,CAACA,aAAE,QAAQ,EAAI,GAAGA,aAAE,MAAM,QAAQ,GAAG,QAAQ,CAAC;AAOtF,SAAS,WAA8C,UAAqB;AAC1E,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAOA,aAAE,SAASA,aAAE,QAAQ;AAAA,IAC5B,aAAaA,aAAE,SAASA,aAAE,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQlC,UAAUA,aAAE,SAASA,aAAE,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMhC,cAAcA,aAAE,SAAS,iBAAiB;AAAA;AAAA,IAE1C,UAAUA,aAAE,SAAS,QAAQ;AAAA,EAAA;AAEjC;AAIA,SAAS,iBAAoD,UAAqB;AAChF,SAAO;AAAA,IACL,MAAM;AAAA,IACN,GAAG,WAAW,QAAQ;AAAA;AAAA,IAEtB,QAAQA,aAAE,SAASA,aAAE,MAAM,gBAAgB,CAAC;AAAA;AAAA,IAE5C,IAAIA,aAAE,SAASA,aAAE,MAAM,gBAAgB,CAAC;AAAA,EAAA;AAE5C;AAEA,MAAM,mBAAmB,iBAAiB,iBAAiB,oBAAoB,CAAC,GAG1E,+BAA+B,iBAAiB,iBAAiB,uBAAuB,CAAC,GAQzF,mBAAmBA,aAAE,aAAa;AAAA,EACtC,MAAMA,aAAE,QAAQ,OAAO;AAAA,EACvB,MAAM;AAAA,EACN,OAAOA,aAAE,SAASA,aAAE,QAAQ;AAAA,EAC5B,aAAaA,aAAE,SAASA,aAAE,QAAQ;AACpC,CAAC;AAMD,SAAS,gBAA4C,MAAa;AAChE,SAAO;AAAA,IACL,MAAMA,aAAE,QAAQ,IAAI;AAAA,IACpB,GAAG,WAAW,uBAAuB;AAAA,EAAA;AAEzC;AAOA,MAAM,sBAAsBA,aAAE,aAAa,gBAAgB,UAAU,CAAC,GAOhE,mBAAmBA,aAAE,aAAa,gBAAgB,OAAO,CAAC,GAEnD,4BAA4BA,aAAE,MAAM;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC,GASK,kBAAkB,UAQX,eAAeA,aAAE,aAAa;AAAA,EACzC,MAAM;AAAA,EACN,OAAOA,aAAE,SAASA,aAAE,QAAQ;AAAA,EAC5B,aAAaA,aAAE,SAASA,aAAE,QAAQ;AAAA;AAAA,EAElC,UAAUA,aAAE,SAASA,aAAE,OAAOA,aAAE,UAAU,eAAe,CAAC;AAAA;AAAA,EAE1D,OAAOA,aAAE,SAASA,aAAE,OAAOA,aAAE,OAAA,GAAUA,aAAE,SAAS,CAAC;AACrD,CAAC,GAWK,oBAAoBA,aAAE,aAAa;AAAA,EACvC,MAAM,SAAS;AAAA,IACb;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA,CACD;AAAA,EACD,MAAM;AAAA,EACN,OAAOA,aAAE,SAASA,aAAE,QAAQ;AAAA,EAC5B,aAAaA,aAAE,SAASA,aAAE,QAAQ;AAAA,EAClC,UAAUA,aAAE,SAASA,aAAE,SAAS;AAClC,CAAC;AAMD,SAAS,aAA0C,IAAS;AAC1D,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAOA,aAAE,SAASA,aAAE,QAAQ;AAAA,IAC5B,aAAaA,aAAE,SAASA,aAAE,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMlC,QAAQA,aAAE,SAAS,eAAe;AAAA,IAClC,QAAQA,aAAE,SAASA,aAAE,MAAM,iBAAiB,CAAC;AAAA,IAC7C,KAAKA,aAAE,SAASA,aAAE,MAAM,EAAE,CAAC;AAAA,IAC3B,SAASA,aAAE,SAASA,aAAE,MAAM,YAAY,CAAC;AAAA,EAAA;AAE7C;AAEA,MAAM,qBAAqBA,aAAE,aAAa,aAAa,cAAc,CAAC,GAGhE,yBAAyB,SAAS,0BAA0B,GAc5D,2BAA2BA,aAAE,aAAa;AAAA,EAC9C,GAAG,aAAa,iBAAiB;AAAA,EACjC,OAAOA,aAAE,SAASA,aAAE,MAAM,QAAQ,CAAC;AAAA,EACnC,QAAQA,aAAE,SAAS,sBAAsB;AAC3C,CAAC,GAUK,oBAAoBA,aAAE,aAAa;AAAA,EACvC,MAAMA,aAAE,QAAQ,OAAO;AAAA,EACvB,MAAM;AAAA,EACN,OAAOA,aAAE,SAASA,aAAE,QAAQ;AAAA,EAC5B,aAAaA,aAAE,SAASA,aAAE,QAAQ;AAAA,EAClC,OAAOA,aAAE,MAAM,CAAC,UAAU,uBAAuB,CAAC;AAAA,EAClD,OAAOA,aAAE,SAASA,aAAE,MAAM,QAAQ,CAAC;AAAA,EACnC,QAAQA,aAAE,SAAS,eAAe;AAAA,EAClC,QAAQA,aAAE,SAASA,aAAE,MAAM,iBAAiB,CAAC;AAAA,EAC7C,SAASA,aAAE,SAASA,aAAE,MAAM,YAAY,CAAC;AAC3C,CAAC,GAEY,wBAAwBA,aAAE,MAAM,CAAC,0BAA0B,iBAAiB,CAAC,GAapF,sBAAsBA,aAAE,aAAa;AAAA,EACzC,MAAM;AAAA,EACN,SAASA,aAAE,SAASA,aAAE,MAAM,CAAC,aAAaA,aAAE,QAAQ,QAAQ,CAAC,CAAC,CAAC;AACjE,CAAC,GAEK,qBAAqBA,aAAE,aAAa;AAAA;AAAA,EAExC,SAAS;AAAA,EACT,YAAY;AAAA;AAAA,EAEZ,MAAMA,aAAE,SAASA,aAAE,OAAO,UAAU,eAAe,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMpD,SAASA,aAAE,SAASA,aAAE,OAAO,UAAU,eAAe,CAAC;AACzD,CAAC;AAUD,SAAS,eAKP,OAAe,QAAiB,IAAS,QAAiB;AAC1D,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAOA,aAAE,SAASA,aAAE,QAAQ;AAAA,IAC5B,aAAaA,aAAE,SAASA,aAAE,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOlC,MAAMA,aAAE,SAAS,SAAS,cAAc,CAAC;AAAA;AAAA;AAAA,IAGzC,QAAQA,aAAE,SAAS,MAAM;AAAA,IACzB,YAAYA,aAAE,SAAS,SAAS,CAAC,QAAQ,QAAQ,CAAC,CAAC;AAAA,IACnD,QAAQA,aAAE,SAAS,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUlC,cAAcA,aAAE,SAASA,aAAE,OAAO,UAAU,eAAe,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAM5D,cAAcA,aAAE,SAAS,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMxC,UAAUA,aAAE,SAAS,eAAe;AAAA,IACpC,KAAKA,aAAE,SAASA,aAAE,MAAM,EAAE,CAAC;AAAA,IAC3B,SAASA,aAAE,SAASA,aAAE,MAAM,YAAY,CAAC;AAAA,IACzC,SAASA,aAAE,SAASA,aAAE,MAAM,MAAM,CAAC;AAAA,IACnC,cAAcA,aAAE,SAAS,kBAAkB;AAAA;AAAA,IAE3C,QAAQA,aAAE,SAASA,aAAE,MAAM,KAAK,CAAC;AAAA,EAAA;AAErC;AAEA,MAAM,uBAAuBA,aAAE;AAAA,EAC7B,eAAe,kBAAkB,oBAAoB,gBAAgB,wBAAwB;AAC/F,GAGa,0BAA0BA,aAAE;AAAA,EACvC;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ;AAQA,SAAS,iBACP,IACA,QACA;AACA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAOA,aAAE,SAASA,aAAE,QAAQ;AAAA,IAC5B,aAAaA,aAAE,SAASA,aAAE,QAAQ;AAAA,IAClC,IAAI;AAAA,IACJ;AAAA;AAAA,IAEA,KAAKA,aAAE,SAASA,aAAE,MAAM,EAAE,CAAC;AAAA,IAC3B,SAASA,aAAE,SAASA,aAAE,MAAM,YAAY,CAAC;AAAA,EAAA;AAE7C;AAEA,MAAM,yBAAyBA,aAAE;AAAA,EAC/B,iBAAiB,0BAA0B,eAAe;AAC5D,GAQM,8BAA8BA,aAAE,QAAQ,QAAQ;AAAA,EACpD,GAAG,UAAU,uBAAuB;AAAA,EACpC;AACF,CAAC,GACY,4BAA4BA,aAAE;AAAA,EACzC,iBAAiB,6BAA6BA,aAAE,SAAS,eAAe,CAAC;AAC3E,GAYM,oBAAoB,SAAS,sBAAsB,GAGnD,mBAAmBA,aAAE,aAAa;AAAA;AAAA,EAEtC,OAAOA,aAAE,SAASA,aAAE,MAAM,QAAQ,CAAC;AAAA;AAAA,EAEnC,QAAQA,aAAE,SAASA,aAAE,MAAM,QAAQ,CAAC;AAAA;AAAA,EAEpC,YAAYA,aAAE,SAASA,aAAE,MAAM,QAAQ,CAAC;AAAA,EACxC,SAASA,aAAE;AAAA,IACTA,aAAE,MAAM,iBAAiB;AAAA,IACzBA,aAAE,UAAU,GAAG,wCAAwC;AAAA,EAAA;AAE3D,CAAC,GAGY,cAAcA,aAAE,aAAa;AAAA,EACxC,MAAM;AAAA,EACN,OAAOA,aAAE,SAASA,aAAE,QAAQ;AAAA,EAC5B,aAAaA,aAAE,SAASA,aAAE,QAAQ;AAAA,EAClC,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOP,WAAWA,aAAE,SAASA,aAAE,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAShC,UAAUA,aAAE,SAASA,aAAE,OAAO,UAAU,QAAQ,CAAC;AACnD,CAAC;AAQD,SAAS,YAKP,OAAe,UAAqB,YAAyB,UAAqB;AAClF,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAOA,aAAE,SAASA,aAAE,QAAQ;AAAA,IAC5B,aAAaA,aAAE,SAASA,aAAE,QAAQ;AAAA,IAClC,YAAYA,aAAE,SAASA,aAAE,MAAM,QAAQ,CAAC;AAAA,IACxC,aAAaA,aAAE,SAASA,aAAE,MAAM,UAAU,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,IAK3C,QAAQA,aAAE,SAASA,aAAE,MAAM,WAAW,CAAC;AAAA;AAAA,IAEvC,QAAQA,aAAE,SAASA,aAAE,MAAM,KAAK,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQjC,UAAUA,aAAE,SAASA,aAAE,OAAO,gBAAgB,QAAQ,CAAC;AAAA,EAAA;AAE3D;AAEA,MAAM,oBAAoBA,aAAE;AAAA,EAC1B,YAAY,kBAAkB,sBAAsB,wBAAwB,oBAAoB;AAClG,GAGa,uBAAuBA,aAAE;AAAA,EACpC;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEJ,GAgCM,oBAAoBA,aAAE;AAAA,EAC1B;AAAA,EACAA,aAAE,KAAKA,aAAE,MAAM,QAAQ,GAAGA,aAAE,UAAU,GAAG,qDAAqD,CAAC;AACjG,GAGM,iBAAiB,CAAC,YAAY,OAAO;AAI3C,SAAS,eACP,OACA,OACA;AACA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,aAAaA,aAAE,SAASA,aAAE,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAUlC,MAAMA,aAAE,SAAS,SAAS,cAAc,CAAC;AAAA;AAAA,IAEzC,cAAc;AAAA;AAAA,IAEd,QAAQA,aAAE,SAASA,aAAE,MAAM,KAAK,CAAC;AAAA,IACjC,QAAQA,aAAE,KAAKA,aAAE,MAAM,KAAK,GAAGA,aAAE,UAAU,GAAG,iCAAiC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMhF,YAAYA,aAAE,SAASA,aAAE,OAAO,eAAe,WAAW,GAAG,eAAe,CAAC;AAAA;AAAA,IAE7E,aAAaA,aAAE,SAAS,iBAAiB;AAAA,EAAA;AAE7C;AAeiCA,aAAE,aAAa,eAAe,kBAAkB,iBAAiB,CAAC;AAI5F,MAAM,0BAA0BA,aAAE;AAAA,EACvC,eAAe,2BAA2B,oBAAoB;AAChE,GAQa,2BAA2B;AAUjC,SAAS,sBAAsB,YAAwD;AAC5F,SAAO,WAAW,SAAS;AAC7B;AAeO,SAAS,sBAAsB,OAAe,QAA4C;AAC/F,QAAM,QAAQ,OAAO,IAAI,CAAC,UAEjB,OADM,MAAM,KAAK,WAAW,IAAI,WAAW,WAAW,MAAM,IAAI,CACrD,KAAK,MAAM,OAAO,EACrC;AACD,SAAO,GAAG,KAAK,uBAAuB,OAAO,MAAM,SACjD,OAAO,WAAW,IAAI,KAAK,GAC7B;AAAA,EAAO,MAAM,KAAK;AAAA,CAAI,CAAC;AACzB;AAEO,SAAS,kBAAkB,QAA4D;AAC5F,SAAO,OAAO,IAAI,CAAC,WAAW;AAAA,IAC5B,MAAM,MAAM,OAAO,MAAM,KAAK,IAAI,CAAC,SAAS,KAAK,GAAkB,IAAI,CAAA;AAAA,IACvE,SAAS,MAAM;AAAA,EAAA,EACf;AACJ;AAEA,SAAS,WAAW,MAA0C;AAC5D,MAAI,MAAM;AACV,aAAW,OAAO;AACZ,WAAO,OAAQ,WAAU,OAAO,IAAI,GAAG,MACtC,OAAO,IAAI,WAAW,IAAI,OAAO,GAAG,IAAI,IAAI,OAAO,GAAG,CAAC;AAE9D,SAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"schema.cjs","sources":["../../src/core/refs.ts","../../src/types/errors.ts","../../src/tags.ts","../../src/define/config.ts","../../src/core/conditions.ts","../../src/core/guard-reads.ts","../../src/core/roles.ts","../../src/define/condition-scope.ts","../../src/types/actor.ts","../../src/core/field-validation.ts","../../src/types/enums.ts","../../src/define/schema.ts"],"sourcesContent":["/**\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/**\n * Parse a GDR URI, returning `undefined` instead of throwing when the string\n * is not a GDR (or is malformed). The \"is this a GDR, and if so its parts\"\n * primitive — every \"parse a ref, treat unparseable as not-a-GDR\" call site\n * routes through this rather than re-spelling the try/catch.\n */\nexport function tryParseGdr(uri: string): ParsedGdr | undefined {\n try {\n return parseGdr(uri)\n } catch {\n return undefined\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/**\n * A map binding each resource-alias name to the physical {@link WorkflowResource}\n * it resolves to at deploy. Parallels the role-alias map: where role aliases map\n * a role to its fulfillers, resource aliases map a logical content reference\n * (`@<alias>:<id>`) to a physical resource. Swapping the map is how the same\n * source definitions deploy to different environments.\n */\nexport type ResourceAliases = Record<string, WorkflowResource>\n\n/**\n * Character grammar of a resource-alias name: a lowercase-letter/digit start,\n * then letters, digits, and dashes. Exported so {@link validateResourceAliasName}\n * and the deploy-time expansion scan share one definition instead of drifting apart.\n */\nexport const RESOURCE_ALIAS_NAME_SOURCE = '[a-z0-9][a-z0-9-]*'\nconst RESOURCE_ALIAS_NAME_RE = new RegExp(`^${RESOURCE_ALIAS_NAME_SOURCE}$`)\n\n/**\n * Checks a resource-alias name: lowercase letters, digits, dashes; no leading\n * dash. Keeps `@<alias>:` clean to parse and safe to drop into GROQ.\n */\nexport function validateResourceAliasName(name: string): void {\n if (!RESOURCE_ALIAS_NAME_RE.test(name)) {\n throw new Error(\n `Invalid resource alias name \"${name}\": expected lowercase letters, digits, and dashes (no leading dash).`,\n )\n }\n}\n\n/**\n * Turn a runtime id into a physical GDR — one place that decides between\n * the two forms a value can take once instances are running:\n * - physical GDR → use as-is\n * - bare id → root at the home resource\n * Logical `@<alias>:` references never reach here: they're expanded to\n * physical GDRs at deploy, before any instance runs.\n */\nexport function toPhysicalGdr(id: string, home: WorkflowResource): GdrUri {\n if (isGdrUri(id)) {\n return id\n }\n\n return gdrFromResource(home, id)\n}\n\n/** Make a GDR pointer to a project-dataset doc. */\nexport function refDataset({\n projectId,\n dataset,\n documentId,\n type,\n}: {\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/** Args for the single-resource ref constructors ({@link refCanvas}, {@link refMediaLibrary}, {@link refDashboard}). */\ninterface ResourceRefArgs {\n resourceId: string\n documentId: string\n type: string\n}\n\n/** Make a GDR pointer to a Canvas-resource doc. */\nexport function refCanvas({\n resourceId,\n documentId,\n type,\n}: ResourceRefArgs): 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,\n documentId,\n type,\n}: ResourceRefArgs): 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,\n documentId,\n type,\n}: ResourceRefArgs): 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 physical GDR prefix a resource contributes — everything that precedes\n * the document id, trailing \":\" included. This is exactly what a bound\n * `@<alias>:` expands to at deploy. Derived from {@link gdrFromResource} so\n * the prefix and the full URI can never drift apart.\n */\nexport function gdrResourcePrefix(res: WorkflowResource): string {\n const sentinel = 'x'\n const full = gdrFromResource(res, sentinel)\n return full.slice(0, full.length - sentinel.length)\n}\n\n/**\n * The {@link WorkflowResource} an already-parsed GDR addresses. Total: a caller\n * holding a {@link ParsedGdr} has already proven the URI parsed, so there's no\n * not-a-GDR case to handle. The `?? ''` only satisfies the cross-scheme-optional\n * `resourceId` type — {@link parseGdr} guarantees it is present per non-dataset\n * scheme, so the fallback never fires.\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 * The {@link WorkflowResource} a GDR URI addresses — the inverse of\n * {@link gdrFromResource}, dropping the document-id tail. The partial,\n * parse-from-string front door over {@link resourceFromParsed}: returns\n * `undefined` for a non-GDR string so callers can treat \"unparseable\" as\n * \"no resource\" rather than handling a throw.\n */\nexport function resourceFromGdrUri(uri: string): WorkflowResource | undefined {\n const parsed = tryParseGdr(uri)\n return parsed === undefined ? undefined : resourceFromParsed(parsed)\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 * Mint the Sanity document `_id` for a `workflow.definition` — deterministic\n * in `(tag, definition, version)`, so a redeploy of the same version targets\n * the same doc. Bare form (no GDR scheme prefix) because Sanity rejects `:`\n * in document IDs; a cross-resource reference rebuilds the full GDR URI from\n * `(workflowResource, _id)` on demand via {@link gdrFromResource}.\n */\nexport function definitionDocId({\n tag,\n definition,\n version,\n}: {\n tag: string\n definition: string\n version: number\n}): string {\n return `${tag}.${definition}.v${version}`\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 return typeof value === 'string' && tryParseGdr(value) !== undefined\n}\n\n/**\n * A GDR URI stripped back to its bare document `_id`; a non-GDR string passes\n * through unchanged. The one canonical \"URI → bare id\" transform — use it\n * wherever a stored ref (which may be a full GDR URI, or already bare) must\n * become a lake-queryable `_id`.\n */\nexport function toBareId(id: string): string {\n return isGdrUri(id) ? extractDocumentId(id) : id\n}\n\n/** Build a GDR (id + type) pointing at a document within a workflow resource. */\nexport function gdrRef({\n res,\n documentId,\n type,\n}: {\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 * The engine's error model — one base class, one discriminant.\n *\n * Every structured error the engine throws at a caller extends\n * {@link WorkflowError} and carries a {@link WorkflowErrorKind}, so a consumer\n * can write ONE catch-and-render path: `instanceof WorkflowError`, then switch\n * on `kind` (or `instanceof` a concrete class to read its typed payload). The\n * model covers the runtime verbs' refusals, denials, races and lookups.\n * Three things deliberately stay plain `Error`: deploy/authoring validation\n * (a structured issue-report design of its own), transient transport\n * failures (retryable, carrying `cause` — not engine verdicts), and internal\n * invariant violations (the remediation is a bug report, not a catch branch).\n *\n * How thrown errors relate to the read-side verdicts is documented on\n * {@link DisabledReason}.\n */\n\nexport type WorkflowErrorKind =\n | 'action-disabled'\n | 'edit-field-denied'\n | 'mutation-guard-denied'\n | 'action-params-invalid'\n | 'effect-ops-invalid'\n | 'required-field-not-provided'\n | 'workflow-state-diverged'\n | 'partial-guard-deploy'\n | 'concurrent-fire-action'\n | 'concurrent-edit-field'\n | 'cascade-limit'\n | 'field-value-shape'\n | 'instance-not-found'\n | 'definition-not-found'\n | 'definition-in-use'\n | 'effect-not-found'\n | 'missing-effect-handler'\n | 'contract-violation'\n\n/**\n * Base class of the engine's structured errors. `kind` is the stable\n * discriminant — render on it; `name` mirrors the concrete class for logs.\n * Each subclass pins its literal via the `K` parameter, so passing a\n * mismatched kind to `super` is a compile error. Advisory like every engine\n * check: catching one of these explains a refusal, it does not enforce\n * anything.\n */\nexport abstract class WorkflowError<K extends WorkflowErrorKind = WorkflowErrorKind> extends Error {\n readonly kind: K\n\n // oxlint-disable-next-line max-params -- the platform `Error(message, options)` signature with the discriminant prepended\n constructor(kind: K, message: string, options?: ErrorOptions) {\n super(message, options)\n this.kind = kind\n }\n}\n\n/**\n * A caller broke a public-API contract — a call the engine rejects\n * before touching the lake: an invalid `tag`, a `workflow.query` GROQ that\n * never binds `$tag`, a bare id where a GDR URI is required, an action,\n * activity, or field the definition never declared. Fix the call site;\n * retrying cannot succeed.\n */\nexport class ContractViolationError extends WorkflowError<'contract-violation'> {\n constructor(message: string) {\n super('contract-violation', message)\n this.name = 'ContractViolationError'\n }\n}\n\n/**\n * The instance id does not resolve to a workflow instance this engine can\n * see — the document is missing, or it belongs to another engine's tag\n * partition. Both arms share this class and kind (an invisible instance is\n * not-found to this caller); the message says which arm it was.\n */\nexport class InstanceNotFoundError extends WorkflowError<'instance-not-found'> {\n readonly instanceId: string\n\n constructor(args: {instanceId: string; detail?: string}) {\n super(\n 'instance-not-found',\n `Workflow instance ${args.instanceId} not found${args.detail ? ` (${args.detail})` : ''}`,\n )\n this.name = 'InstanceNotFoundError'\n this.instanceId = args.instanceId\n }\n}\n\n/** No deployed workflow definition matches the requested name (and version,\n * when given) under this engine's tag. */\nexport class DefinitionNotFoundError extends WorkflowError<'definition-not-found'> {\n readonly definition: string\n readonly version?: number\n\n constructor(args: {definition: string; version?: number}) {\n super(\n 'definition-not-found',\n args.version !== undefined\n ? `Workflow definition ${args.definition} v${args.version} not deployed`\n : `Workflow definition ${args.definition} has no deployed versions`,\n )\n this.name = 'DefinitionNotFoundError'\n this.definition = args.definition\n if (args.version !== undefined) this.version = args.version\n }\n}\n\n/** What blocks a `deleteDefinition`, so a consumer can render the remediation:\n * abort-in-place via `cascade`, or delete/redeploy the referrer first. */\nexport type DefinitionInUseBlocker =\n | {reason: 'non-terminal-instances'; instanceIds: string[]}\n | {reason: 'spawn-referrers'; referrers: {definition: string; version: number}[]}\n\n/**\n * `deleteDefinition` refused because the definition is still in use — either\n * non-terminal instances are pinned to it (pass `cascade` to abort them in\n * place first) or a surviving deployed definition still spawn-references a\n * targeted version (delete or redeploy the referrer first). `blockedBy` says\n * which, with the blocking ids, so a consumer can render the remediation.\n */\nexport class DefinitionInUseError extends WorkflowError<'definition-in-use'> {\n readonly definition: string\n readonly blockedBy: DefinitionInUseBlocker\n\n constructor(args: {definition: string; blockedBy: DefinitionInUseBlocker}) {\n super('definition-in-use', definitionInUseMessage(args.definition, args.blockedBy))\n this.name = 'DefinitionInUseError'\n this.definition = args.definition\n this.blockedBy = args.blockedBy\n }\n}\n\nfunction definitionInUseMessage(definition: string, blockedBy: DefinitionInUseBlocker): string {\n if (blockedBy.reason === 'non-terminal-instances') {\n const head = blockedBy.instanceIds.slice(0, 3).join(', ')\n const preview = blockedBy.instanceIds.length > 3 ? `${head}, …` : head\n return (\n `Cannot delete ${definition}: ${blockedBy.instanceIds.length} non-terminal instance(s) exist ` +\n `(${preview}). Pass cascade to abort them first — instances are aborted in place, never deleted.`\n )\n }\n const names = blockedBy.referrers.map((r) => `${r.definition} v${r.version}`).join(', ')\n return (\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 * The effect key does not match any pending effect on the instance. Besides a\n * typo'd key, an at-least-once runtime hits this on a double delivery — the\n * first completion drained the effect — so a consumer can branch on this kind\n * to treat the second attempt as already-done rather than as a failure.\n */\nexport class EffectNotFoundError extends WorkflowError<'effect-not-found'> {\n readonly instanceId: string\n readonly effectKey: string\n\n constructor(args: {instanceId: string; effectKey: string}) {\n super(\n 'effect-not-found',\n `Pending effect \"${args.effectKey}\" not found on instance ${args.instanceId}`,\n )\n this.name = 'EffectNotFoundError'\n this.instanceId = args.instanceId\n this.effectKey = args.effectKey\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\nimport {ContractViolationError} from './types/errors.ts'\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 ContractViolationError(\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 * Deploy-config authoring surface — binds a workflow's logical resource\n * handles to physical resources, per environment (tag).\n *\n * A definition references content through `@<handle>:` aliases; this config\n * says what each handle resolves to in a given environment. The CLI discovers\n * one of these files, picks a deployment by tag, and hands the bound resources\n * to {@link deployDefinitions}, which expands the aliases at deploy and fails\n * closed on any handle a deployment doesn't bind.\n */\n\nimport * as v from 'valibot'\n\nimport {\n datasetResourceParts,\n validateResourceAliasName,\n type ResourceAliases,\n type WorkflowResource,\n} from '../core/refs.ts'\nimport {validateTag} from '../tags.ts'\nimport type {WorkflowDefinition} from './schema.ts'\n\nconst NonEmptyString = v.pipe(v.string(), v.nonEmpty('must not be empty'))\n\n// Adapt an engine validator (throws on invalid) into a valibot boolean\n// predicate, so a bad value fails at the config boundary rather than deep\n// inside deployDefinitions: validateTag for the partition key,\n// validateResourceAliasName for a handle name, datasetResourceParts for a\n// dataset id's `<projectId>.<dataset>` shape. Deploy expands `@<name>:` by the\n// same alias grammar and silently ignores a name that doesn't match — which\n// surfaces as an \"unbound alias\" mid-deploy, the late failure this layer exists\n// to catch.\nfunction asPredicate(validate: (value: string) => void): (value: string) => boolean {\n return (value) => {\n try {\n validate(value)\n return true\n } catch {\n return false\n }\n }\n}\n\nconst isValidTag = asPredicate(validateTag)\nconst isValidAliasName = asPredicate(validateResourceAliasName)\nconst isValidDatasetId = asPredicate(datasetResourceParts)\n\n// Mirrors the WorkflowResource union in core/refs.ts. A `variant` (not a\n// `picklist` on `type` + `id`) so the INFERRED output is the discriminated\n// union and stays assignable to the engine's WorkflowResource. A flat\n// `{type: <union>; id}` would be wider than the engine union and force a cast\n// at every deploy seam it flows into.\n//\n// The dataset branch additionally checks the `<projectId>.<dataset>` shape:\n// otherwise a malformed id (no dot) validates clean here and throws late inside\n// datasetResourceParts when a client is built. The other types carry an opaque\n// resource id the engine never destructures, so a non-empty string is the whole\n// contract — no format to check.\nconst WorkflowResourceSchema = v.variant('type', [\n v.object({\n type: v.literal('dataset'),\n id: v.pipe(\n NonEmptyString,\n v.check(isValidDatasetId, 'invalid dataset resource id — expected \"<projectId>.<dataset>\"'),\n ),\n }),\n v.object({type: v.literal('canvas'), id: NonEmptyString}),\n v.object({type: v.literal('media-library'), id: NonEmptyString}),\n v.object({type: v.literal('dashboard'), id: NonEmptyString}),\n])\n\n// Compile-time check: the schema's inferred output must match the engine's\n// WorkflowResource union exactly. The variant exists to mirror that union, so\n// adding a resource type in core/refs.ts and forgetting it here (or vice\n// versa) errors with a \"MISSING from …\" diagnostic.\ntype _ResourceSchemaAgrees =\n v.InferOutput<typeof WorkflowResourceSchema> extends WorkflowResource\n ? WorkflowResource extends v.InferOutput<typeof WorkflowResourceSchema>\n ? true\n : [\n 'MISSING from WorkflowResourceSchema:',\n Exclude<WorkflowResource, v.InferOutput<typeof WorkflowResourceSchema>>,\n ]\n : [\n 'not a WorkflowResource:',\n Exclude<v.InferOutput<typeof WorkflowResourceSchema>, WorkflowResource>,\n ]\nconst _resourceSchemaAgrees: _ResourceSchemaAgrees = true\nvoid _resourceSchemaAgrees\n\n// One logical handle → physical resource binding. `name` is the handle an\n// author writes as `@<name>:` inside a definition.\nconst ResourceBindingSchema = v.object({\n name: v.pipe(\n NonEmptyString,\n v.check(\n isValidAliasName,\n 'invalid resource handle name — lowercase letters, digits and dashes only, no leading dash',\n ),\n ),\n resource: WorkflowResourceSchema,\n})\n\n// Definitions are already validated by defineWorkflow, and the deploy path\n// re-checks their references. `v.custom` asserts \"object with a string name\"\n// and passes the value THROUGH untouched — a `v.object` would strip every\n// other field — while keeping the large WorkflowDefinition schema out of type\n// inference (which is what trips TS2589 for published consumers).\nconst DefinitionSchema = v.custom<WorkflowDefinition>(\n (input) =>\n typeof input === 'object' &&\n input !== null &&\n typeof (input as {name?: unknown}).name === 'string',\n 'expected a workflow definition (an object with a string `name`)',\n)\n\nconst DeploymentSchema = v.object({\n name: NonEmptyString,\n tag: v.pipe(\n v.string(),\n v.nonEmpty(),\n v.check(\n isValidTag,\n 'invalid tag — lowercase letters, digits and dashes only, no leading dash, no dots',\n ),\n ),\n workflowResource: WorkflowResourceSchema,\n // Optional — omit for a workflow whose definitions reference no `@handle:`.\n // No valibot default: a default makes the inferred output `resourceAliases`\n // required (poor authoring ergonomics) and diverges input from output,\n // which the shared `parseOrThrow` can't model. resourceAliasesToMap treats\n // an absent map as none.\n //\n // Handle names must be unique: resourceAliasesToMap collapses bindings into a\n // map, so a duplicate would silently overwrite — and the dup is gone before\n // the engine sees it. Caught here, at the only layer that still can.\n resourceAliases: v.optional(\n v.pipe(\n v.array(ResourceBindingSchema),\n v.check(\n (bindings) => new Set(bindings.map((binding) => binding.name)).size === bindings.length,\n 'duplicate resource handle name — each binding name must be unique within a deployment',\n ),\n ),\n ),\n definitions: v.pipe(\n v.array(DefinitionSchema),\n v.minLength(1, 'a deployment needs at least one definition'),\n ),\n})\n\nexport const WorkflowConfigSchema = v.object({\n // Tags must be unique: a tag is the environment key the CLI selects a\n // deployment by, so two deployments sharing one make selection ambiguous.\n // Enforced here so the ambiguity is a config error, not a deploy-time\n // surprise — and so consumers can treat a tag as naming one deployment.\n deployments: v.pipe(\n v.array(DeploymentSchema),\n v.minLength(1, 'a config needs at least one deployment'),\n v.check(\n (deployments) =>\n new Set(deployments.map((deployment) => deployment.tag)).size === deployments.length,\n 'duplicate deployment tag — each deployment must use a unique tag',\n ),\n ),\n})\n\nexport type WorkflowConfig = v.InferOutput<typeof WorkflowConfigSchema>\nexport type WorkflowDeployment = WorkflowConfig['deployments'][number]\n\n/**\n * Collapse a deployment's `resourceAliases` bindings into the engine's\n * {@link ResourceAliases} map (handle name → physical resource) — the shape\n * {@link deployDefinitions} consumes.\n */\nexport function resourceAliasesToMap(\n resourceAliases: WorkflowDeployment['resourceAliases'],\n): ResourceAliases {\n return Object.fromEntries(\n (resourceAliases ?? []).map((binding): [string, WorkflowResource] => [\n binding.name,\n binding.resource,\n ]),\n )\n}\n","/**\n * Shared GROQ condition composition. The one place that knows how the engine\n * ANDs partial conditions into a single predicate string — reused by the\n * define-time filter desugar (`roles` + `filter` + claim no-steal) and the\n * runtime editability resolution (field baseline AND stage tighten-override).\n * Keeping it in one spot means the parenthesisation can't drift between the two.\n */\n\n/**\n * AND the supplied conditions into one GROQ predicate, dropping `undefined`\n * parts. Returns `undefined` when nothing remains (vacuously satisfied — the\n * caller's \"no gate\" case), the lone part verbatim when only one survives, and\n * each part parenthesised + `&&`-joined otherwise so operator precedence can't\n * change a part's meaning.\n */\nexport function andConditions(parts: readonly (string | undefined)[]): string | undefined {\n const present = parts.filter((p): p is string => p !== undefined)\n if (present.length === 0) return undefined\n if (present.length === 1) return present[0]\n return present.map((p) => `(${p})`).join(' && ')\n}\n","/**\n * The guard-read grammar — ONE home for both halves of the stored string\n * mini-language on `match.idRefs` and `metadata`: the printer (typed\n * {@link GuardRead} → stored spelling, used by desugar) and the anchored\n * regexes the deploy validator and runtime resolver parse with. Print and\n * parse must stay byte-compatible; co-locating them makes that structural\n * rather than test-enforced. Pure string ops, no I/O.\n */\n\nimport type {GuardRead} from '../define/schema.ts'\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.\nexport const 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.\nexport const 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 * the guard-binding resolver.\n */\nexport function isGuardReadExpr(expr: string): boolean {\n return expr === '$self' || expr === '$now' || FIELD_READ.test(expr) || EFFECTS_READ.test(expr)\n}\n\n/** Print a typed authoring read as the stored string spelling — the exact\n * form {@link FIELD_READ} / {@link EFFECTS_READ} re-parse. */\nexport function printGuardRead(read: GuardRead): string {\n switch (read.type) {\n case 'self':\n return '$self'\n case 'now':\n return '$now'\n case 'fieldRead':\n return read.path === undefined\n ? `$fields.${read.field}`\n : `$fields.${read.field}.${read.path}`\n case 'effectsRead':\n return read.path === undefined\n ? `$effects['${read.effect}']`\n : `$effects['${read.effect}'].${read.path}`\n }\n}\n","/**\n * Role-alias expansion — the pure rule behind the \"can be fulfilled by\" map.\n * One definition of \"which roles satisfy a required role\", shared by the two\n * sites that match an actor against required roles: the `roles` gate (baked\n * into GROQ at desugar) and `$assigned` (resolved at runtime). Keeping it in\n * one place is what lets the baked gate and the runtime check agree.\n */\n\nimport type {RoleAliases} from '../define/schema.ts'\n\n/**\n * The universal-fulfiller key as authors write it: roles listed under `\"*\"`\n * fulfill ANY required role. Rewritten to {@link UNIVERSAL_ROLE_ALIAS_KEY}\n * before the definition is stored — see {@link normalizeRoleAliases}.\n */\nconst AUTHORED_UNIVERSAL_ROLE_ALIAS_KEY = '*'\n\n/**\n * The stored spelling of the universal-fulfiller key. A deployed definition\n * persists `roleAliases` as structured document fields, and the Content Lake\n * rejects any attribute name that isn't `^\\$?[a-zA-Z0-9_-]+$` — so the authored\n * `\"*\"` ({@link AUTHORED_UNIVERSAL_ROLE_ALIAS_KEY}) cannot be a key on disk. The\n * `$` prefix is lake-legal and can't collide with a deployment role name.\n */\nexport const UNIVERSAL_ROLE_ALIAS_KEY = '$all'\n\n/**\n * Rewrite the authored universal key `\"*\"` to the lake-safe\n * {@link UNIVERSAL_ROLE_ALIAS_KEY} so the stored (and thus deployed) definition\n * carries no attribute name the Content Lake rejects. Per-role keys pass\n * through untouched. Define-time validation rejects an authored key in the\n * reserved `$` namespace, so the input never already carries the stored\n * universal key — this is a straight rename, not a merge. Pure — returns a new\n * map, or the input unchanged when there's no `\"*\"` to rewrite.\n */\nexport function normalizeRoleAliases(aliases: RoleAliases | undefined): RoleAliases | undefined {\n if (aliases === undefined || !(AUTHORED_UNIVERSAL_ROLE_ALIAS_KEY in aliases)) return aliases\n const {[AUTHORED_UNIVERSAL_ROLE_ALIAS_KEY]: universal, ...perRole} = aliases\n return {...perRole, [UNIVERSAL_ROLE_ALIAS_KEY]: universal}\n}\n\n/**\n * Widen a set of REQUIRED roles to every role that fulfills them: each\n * required role itself, plus its declared fulfillers, plus the universal\n * fulfillers under {@link UNIVERSAL_ROLE_ALIAS_KEY}. The actor's own roles are\n * never touched — only the accepted set grows. Reads the stored (normalised)\n * alias map, so the universal key is the lake-safe spelling, not `\"*\"`.\n *\n * Deterministic (declaration order, first occurrence wins) so the baked gate\n * and golden snapshots stay stable. Expansion is one level, not transitive: a\n * fulfiller that is itself an alias key is not followed.\n */\nexport function expandRequiredRoles(\n required: readonly string[],\n aliases: RoleAliases | undefined,\n): string[] {\n if (aliases === undefined) return [...required]\n const out = new Set<string>()\n for (const role of required) {\n out.add(role)\n for (const fulfiller of aliases[role] ?? []) out.add(fulfiller)\n }\n for (const fulfiller of aliases[UNIVERSAL_ROLE_ALIAS_KEY] ?? []) out.add(fulfiller)\n return [...out]\n}\n\n/**\n * Does the actor hold a role that fulfills `required` (a single required\n * role, e.g. an `assignees` entry's role)? The runtime twin of the baked\n * {@link expandRequiredRoles} gate, for `$assigned`.\n */\nexport function actorFulfillsRole({\n actorRoles,\n required,\n aliases,\n}: {\n actorRoles: readonly string[] | undefined\n required: string\n aliases: RoleAliases | undefined\n}): boolean {\n if (actorRoles === undefined || actorRoles.length === 0) return false\n const accepted = new Set(expandRequiredRoles([required], aliases))\n return actorRoles.some((role) => accepted.has(role))\n}\n","/**\n * The condition-variable inventory — the single source of truth for every\n * `$var` the engine binds when it evaluates a {@link Condition}.\n *\n * Three evaluation contexts read a definition's GROQ:\n *\n * 1. **Rendered condition scope** — every condition site in a definition\n * (transition filters, `completeWhen`/`failWhen`, action filters, effect\n * bindings, `subworkflows` reads, where-op `where`s, editability\n * predicates, author predicates). {@link CONDITION_VARS} is its inventory;\n * each entry's `binding` says when the var actually holds a value. The\n * where-op context is the one closed subset — its bound set is statically\n * fixed and deploy-enforced (see the op-where scope's param-name list in\n * the op applier).\n * 2. **Filter evaluation without a caller** — the engine's cascade evaluates\n * transition filters and `completeWhen`/`failWhen` with no caller, so only\n * the `'always'`-bound subset carries values there ({@link FILTER_SCOPE_VARS}).\n * Caller-bound vars evaluate to `undefined` and fail closed.\n * 3. **Guard predicates** — NOT conditions. A lake mutation guard's\n * `predicate` is groq-js **delta-mode** GROQ over a document mutation:\n * `before()`/`after()`/`identity()` are dialect natives, and the wire\n * format binds the identifiers in {@link GUARD_PREDICATE_VARS}. None of\n * the condition vars exist there.\n */\n\n/**\n * When a condition var holds a value:\n *\n * - `'always'` — bound in every condition evaluation, derived from the\n * instance and its snapshot.\n * - `'caller'` — rides the acting caller; without one the var is `undefined`\n * (conditions referencing it fail closed). Author predicates may not read\n * these — they pre-evaluate once per instance, caller-free.\n * - `'spawn'` — bound only at `subworkflows` sites.\n */\nexport type ConditionVarBinding = 'always' | 'caller' | 'spawn'\n\nexport interface ConditionVar {\n /** The GROQ param name, read as `$<name>`. */\n name: string\n binding: ConditionVarBinding\n description: string\n}\n\n/**\n * Every variable the engine binds for conditions, in one place. The\n * deploy-time shadow check ({@link RESERVED_CONDITION_VARS}) and the docs on\n * {@link Condition} derive from this list — extend it here when the engine\n * grows a binding, never in a comment elsewhere.\n */\nexport const CONDITION_VARS: readonly ConditionVar[] = [\n {\n name: 'self',\n binding: 'always',\n description:\n 'GDR URI of the instance document itself — `*[_id == $self][0]` reads the instance in the snapshot.',\n },\n {\n name: 'fields',\n binding: 'always',\n description:\n 'Declared field entries rendered by name (`$fields.<name>` is the value, no envelope). Stage/activity scopes overlay lexically; `doc.ref` values render the hydrated document when the snapshot holds it.',\n },\n {\n name: 'parent',\n binding: 'always',\n description: \"The parent instance's GDR URI, `null` on a root instance.\",\n },\n {\n name: 'ancestors',\n binding: 'always',\n description: 'GDR URIs of the ancestor chain, root first.',\n },\n {name: 'stage', binding: 'always', description: \"The current stage's name.\"},\n {\n name: 'now',\n binding: 'always',\n description:\n 'The ISO clock reading shared by every condition in one evaluation pass, so they agree on the time.',\n },\n {\n name: 'effects',\n binding: 'always',\n description:\n \"The `effectsContext` map: stable handler params seeded at start plus completed effects' outputs namespaced by effect name (`$effects['<effect>'].<output>`). Handler fuel — transition filters should read instance/lake state (or $effectStatus) instead.\",\n },\n {\n name: 'effectStatus',\n binding: 'always',\n description:\n \"Effect name → `'done'` | `'failed'` of the latest completed run queued during the current stage entry; absent until the effect drains for this entry. Re-entry-safe: runs queued under a prior entry never count, so `$effectStatus['<effect>'] == 'done'` (or `defined($effectStatus['<effect>'])` for settled-either-way) waits for the fresh run.\",\n },\n {\n name: 'activities',\n binding: 'always',\n description: \"The current stage's activity rows, statuses included.\",\n },\n {\n name: 'allActivitiesDone',\n binding: 'always',\n description:\n 'Every current-stage activity is `done` or `skipped` — the default transition gate.',\n },\n {\n name: 'anyActivityFailed',\n binding: 'always',\n description: 'Some current-stage activity is `failed`.',\n },\n {\n name: 'actor',\n binding: 'caller',\n description:\n 'The acting identity (id + roles); `undefined` when no caller rides the evaluation.',\n },\n {\n name: 'assigned',\n binding: 'caller',\n description:\n \"Whether the caller matches the activity's assignees-kind field entry (by user id, or by a role under the definition's `roleAliases`); `false` outside an activity context.\",\n },\n {\n name: 'can',\n binding: 'caller',\n description:\n \"Advisory per-permission booleans computed from the caller's grants; `undefined` without grants. Bound only while an action fires, so it may appear in action filters only (deploy-enforced).\",\n },\n {\n name: 'row',\n binding: 'spawn',\n description:\n 'One `subworkflows.forEach` result row, bound while its `with` map evaluates — and the row under test while a where-op `where` evaluates (per row).',\n },\n {\n name: 'params',\n binding: 'caller',\n description:\n \"The firing action's args — bound while its effect bindings and where-op `where` conditions evaluate.\",\n },\n {\n name: 'subworkflows',\n binding: 'spawn',\n description:\n 'The spawned child rows (status included) of the spawning activity, bound for its `completeWhen`/`failWhen` — the implicit completion gate reads it.',\n },\n]\n\n/**\n * Names an author's predicate may not use — engine-owned and author names\n * share one namespace, so a predicate redefining a binding would silently\n * shadow engine behaviour. Rejected at deploy; derived from\n * {@link CONDITION_VARS}.\n */\nexport const RESERVED_CONDITION_VARS: readonly string[] = CONDITION_VARS.map((v) => v.name)\n\n/**\n * The subset that holds a value when the engine evaluates filters without a\n * caller (the cascade path: transition filters, `completeWhen`/`failWhen`).\n */\nexport const FILTER_SCOPE_VARS: readonly string[] = CONDITION_VARS.filter(\n (v) => v.binding === 'always',\n).map((v) => v.name)\n\n/**\n * The identifiers a lake mutation guard's `predicate` reads — the wire\n * dialect, not the condition scope (so no {@link ConditionVarBinding}: these\n * bind only when a guard evaluates a mutation). `before()`/`after()`/\n * `identity()` are groq-js delta-mode natives on top of these. Bound in one\n * place: `guardPredicateParams` in the guard evaluator.\n */\nexport const GUARD_PREDICATE_VARS: readonly {name: string; description: string}[] = [\n {\n name: 'guard',\n description: 'The guard document itself (its `metadata` carries deploy-time resolved values).',\n },\n {\n name: 'mutation',\n description: 'The attempted mutation — `mutation.action` is the write kind being gated.',\n },\n]\n","// Actor kinds — WHO is acting: a human, an LLM, or automated machinery. The\n// `system` kind covers both the engine's own housekeeping and external\n// services; {@link DriverKind} splits that for the audit-trail glyph.\nexport const ACTOR_KINDS = ['person', 'agent', 'system'] as const\nexport type ActorKind = (typeof ACTOR_KINDS)[number]\n\n/**\n * Who is acting, as asserted by the caller — advisory provenance, not an\n * authenticated principal. The engine resolves it from the client's token by\n * default (`/users/me`), but every acting verb accepts an `access.actor`\n * override and nothing verifies the asserted id against the token performing\n * the writes. Only the lake's own token identity is authenticated; hard\n * enforcement lives there.\n */\nexport interface Actor {\n kind: ActorKind\n id: string\n /**\n * Free-form role names — typically a copy of Sanity's `user.roles[].name`\n * for the token behind the call. The engine treats these as opaque\n * strings, matched by literal membership: `Action.roles` and `assignees`\n * roles OR-match against this list. There is no actor-side wildcard — a\n * `\"*\"` here is just a literal string and matches nothing on its own.\n *\n * To let one role satisfy a gate it doesn't literally name — e.g. an\n * `administrator` satisfying a narrower gate, or one deployment's role\n * standing in for another's — declare the definition's `roleAliases`\n * \"can be fulfilled by\" map; it widens the REQUIRED side, never the\n * actor's roles.\n */\n roles?: string[]\n onBehalfOf?: string\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 {ACTOR_KINDS} from '../types/actor.ts'\nimport {WorkflowError} from '../types/errors.ts'\nimport {isGdrUri, RESOURCE_ALIAS_NAME_SOURCE} from './refs.ts'\n\nexport class FieldValueShapeError extends WorkflowError<'field-value-shape'> {\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-value-shape',\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(ACTOR_KINDS),\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}). The\n// builders take the map as a parameter so the literal-seed grammar (ref ids\n// in authoring spellings) threads through nested sub-shapes too.\ntype LeafSchemas = Partial<Record<string, v.GenericSchema>>\n\nconst valueSchemas: LeafSchemas = {\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}\n\n/**\n * Schema for one sub-field's VALUE. Leaf kinds reuse the fixed schemas\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, leaf: LeafSchemas): v.GenericSchema {\n if (shape.type === 'object') return objectSchema(shape.fields ?? [], leaf)\n if (shape.type === 'array') return v.array(objectSchema(shape.of ?? [], leaf))\n return leaf[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[], leaf: LeafSchemas): 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, leaf))\n return v.looseObject(entries)\n}\n\ninterface CompositeShape {\n fields?: readonly FieldShape[] | undefined\n of?: readonly FieldShape[] | undefined\n}\n\nfunction wholeValueSchema(args: {\n entryType: string\n shape: CompositeShape\n leaf: LeafSchemas\n}): v.GenericSchema | undefined {\n const {entryType, shape, leaf} = args\n if (entryType === 'object') return v.union([v.null(), objectSchema(shape.fields ?? [], leaf)])\n if (entryType === 'array') return v.array(objectSchema(shape.of ?? [], leaf))\n return leaf[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 ?? [], valueSchemas)\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 return checkValueAgainst(args, valueSchemas)\n}\n\nfunction checkValueAgainst(\n args: {\n entryType: string\n value: unknown\n fields?: readonly FieldShape[] | undefined\n of?: readonly FieldShape[] | undefined\n },\n leaf: LeafSchemas,\n): string[] | undefined {\n const schema = wholeValueSchema({entryType: args.entryType, shape: args, leaf})\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\n// Authoring ref ids — what a LITERAL seed may put in a `doc.ref`-family `id`:\n// a physical GDR URI, a portable `@<alias>:<id>` (expanded at deploy), or a\n// bare id (rooted at the home resource at materialisation — see the literal\n// branch of field resolution). A string starting with `@` MUST be a\n// well-formed alias ref — a typo like `@Brand:x` must fail here, not degrade\n// to a bare id and silently read the wrong resource. Bare ids follow Sanity's\n// `_id` charset (no `:` — that's the GDR scheme separator; a leading `_`\n// covers system docs like `_.releases.<name>`), and the alias grammar's id\n// part speaks the same charset so junk after the alias can't ride through\n// deploy into a GDR no document can ever have.\nconst BARE_ID_SOURCE = '[A-Za-z0-9_][A-Za-z0-9._-]*'\nconst BARE_ID_RE = new RegExp(`^${BARE_ID_SOURCE}$`)\nconst ALIAS_REF_RE = new RegExp(`^@${RESOURCE_ALIAS_NAME_SOURCE}:${BARE_ID_SOURCE}$`)\n\nfunction isAuthoringRefId(id: string): boolean {\n if (id.startsWith('@')) return ALIAS_REF_RE.test(id)\n if (id.includes(':')) return isGdrUri(id)\n return BARE_ID_RE.test(id)\n}\n\n/** A ref-position id in a literal seed speaks a bare id, not a GDR URI. */\nexport function isBareSeedId(id: string): boolean {\n return BARE_ID_RE.test(id)\n}\n\nconst AuthoringRefId = v.pipe(\n v.string(),\n v.check(\n isAuthoringRefId,\n 'must be a bare document id, a GDR URI, or a portable `@<alias>:<id>` reference',\n ),\n)\n\nconst AuthoringGdrShape = v.looseObject({\n id: AuthoringRefId,\n type: v.pipe(v.string(), v.minLength(1)),\n})\n\n// The literal-seed grammar: like the runtime map, but ref-position ids speak\n// the authoring spellings — at every depth, so a `doc.ref` sub-field inside an\n// `object`/`array` seed accepts the same three id forms as a top-level entry.\nconst seedValueSchemas: LeafSchemas = {\n ...valueSchemas,\n 'doc.ref': v.union([v.null(), AuthoringGdrShape]),\n 'doc.refs': v.array(AuthoringGdrShape),\n 'release.ref': v.union([\n v.null(),\n v.looseObject({\n id: AuthoringRefId,\n type: v.literal('system.release'),\n releaseName: v.pipe(v.string(), v.minLength(1)),\n }),\n ]),\n}\n\n/**\n * Issues for a LITERAL seed value at define time, or `undefined` when it fits\n * the entry's declared kind. Differs from the runtime {@link checkFieldValue}\n * in exactly two ways: ref ids speak the authoring grammar (bare id | GDR URI\n * | `@<alias>:<id>` — a runtime entry always carries GDR URIs), and the\n * top-level `null` is rejected (an empty start is spelled by omitting\n * `initialValue`; a nested sub-field may still seed null, matching runtime).\n */\nexport function checkLiteralSeed(args: {\n entryType: string\n value: unknown\n fields?: readonly FieldShape[] | undefined\n of?: readonly FieldShape[] | undefined\n}): string[] | undefined {\n if (args.value === null) {\n return ['a literal seed cannot be null — omit `initialValue` to start the field empty']\n }\n return checkValueAgainst(args, seedValueSchemas)\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\nexport function 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 * Leaf enums — the const arrays (and their derived union types) that both\n * the authoring schema and the engine address by name.\n *\n * This module imports nothing. It is the schema-free foundation that\n * `../define/schema.ts` reads its value constants from, which is what keeps\n * the type model and the valibot schema free of an import cycle: the value edge\n * `schema.ts → enums.ts` terminates here.\n */\n\n// Activity status — used by instance state. The authored action `status:` sugar\n// (and the `status.set` op it desugars to) is constrained to the terminal\n// subset below.\nexport const ACTIVITY_STATUSES = ['pending', 'active', 'done', 'skipped', 'failed'] as const\nexport type ActivityStatus = (typeof ACTIVITY_STATUSES)[number]\n\n// The statuses an activity can be resolved INTO — what `status.set` accepts.\n// A health axis, not a decision axis: a routine decision (decline, send back,\n// hold) resolves `done` and routes via a field write; `failed` means the work\n// genuinely could not complete. Only `done`/`skipped` satisfy `$allActivitiesDone`\n// — a `failed` activity blocks it permanently, surfacing via `$anyActivityFailed`.\nexport const TERMINAL_ACTIVITY_STATUSES = ['done', 'skipped', 'failed'] as const\nexport type TerminalActivityStatus = (typeof TERMINAL_ACTIVITY_STATUSES)[number]\n\nexport function isTerminalActivityStatus(status: ActivityStatus): status is TerminalActivityStatus {\n return (TERMINAL_ACTIVITY_STATUSES as readonly ActivityStatus[]).includes(status)\n}\n\n// The three field scopes a field entry can live in. Authoring (`ScopeKey`,\n// `fieldRead` sources) and the engine both address field entries by scope.\nexport const FIELD_SCOPES = ['workflow', 'stage', 'activity'] as const\nexport type FieldScope = (typeof FIELD_SCOPES)[number]\n\n// Document-value permissions. Grants (`Grant` in ./authorization.ts) compose\n// most-permissive-wins.\nexport const DOCUMENT_VALUE_PERMISSIONS = ['create', 'read', 'update'] as const\nexport type DocumentValuePermission = (typeof DOCUMENT_VALUE_PERMISSIONS)[number]\n\n// Mutation-guard actions — the lake operations a guard can gate. See the\n// guard types in ./authorization.ts.\nexport const MUTATION_GUARD_ACTIONS = [\n 'create',\n 'update',\n 'delete',\n 'publish',\n 'unpublish',\n] as const\nexport type MutationGuardAction = (typeof MUTATION_GUARD_ACTIONS)[number]\n\n// Activity kinds — BPMN-aligned classification of an activity by its EXECUTOR. Purely\n// advisory: `kind` labels an activity so tooling renders it as what it is (and the\n// graph can show the work + its driver). It changes no gating or runtime — an\n// activity resolves and a transition fires exactly as the rest of its shape says.\n// Optional on the definition; derived from the activity's shape when omitted (see\n// `../activity-kind.ts`), so existing definitions need no edits.\nexport const ACTIVITY_KINDS = ['user', 'service', 'script', 'manual', 'receive'] as const\nexport type ActivityKind = (typeof ACTIVITY_KINDS)[number]\n\n// Driver kinds — what KIND of actor actually drove an action, recorded on the\n// `actionFired` history entry for the audit-trail \"who did this?\" glyph. Distinct\n// from {@link ActivityKind} (the intended execution lane): any driver can fire any\n// kind. Derived from the firing {@link Actor} (see `../activity-kind.ts`).\nexport const DRIVER_KINDS = ['person', 'agent', 'service', 'engine'] as const\nexport type DriverKind = (typeof DRIVER_KINDS)[number]\n","/**\n * Valibot schemas for the workflow authoring surface — the things a workflow\n * author writes by hand and feeds to `defineWorkflow`. Types in this\n * file are the **canonical** authoring types.\n *\n * Node types (`WorkflowDefinition` / `Stage` / `Activity` / `Action` /\n * `FieldEntry`, and their `Authoring*` twins) are **hand-written named types**\n * built from generic type-mirrors of the schema value-factories\n * (`{@link WorkflowFields}` mirrors `{@link workflowFields}`, etc.), each\n * **compile-time-pinned to its schema** via {@link pinned} — so a schema entry\n * the type no longer matches is a *compile* error, not a silent divergence.\n * This extends the pinning the recursive leaves (`{@link ValueExpr}` /\n * `{@link FieldSource}` / `{@link FieldShape}`) already use. The leaf/bounded\n * types (ops, refs, effects, guards, …) stay inferred with `v.InferOutput` —\n * they neither recurse deeply nor drive the problem the pinning solves. They are\n * `type` aliases, not `interface`s, deliberately — see {@link pinned}'s callers.\n *\n * Why named types instead of `v.InferOutput<typeof schema>` over the whole\n * tree: api-extractor inlines a non-pinned schema const's type into one giant\n * `v.StrictObjectSchema<{…}>` in the bundled `.d.ts`, and computing\n * `InferOutput` over that inlined form instantiates eagerly in one pass and\n * blows TS's instantiation cap → `TS2589` for any consumer resolving the\n * published declarations (e.g. `defineWorkflow(def)` on a realistic literal).\n * Pinning each node schema to `v.GenericSchema<Named>` short-circuits the\n * inlining at every level, so the bundled `.d.ts` carries named types and the\n * consumer never re-derives the full tree.\n *\n * Two layers live here, mirroring the design model (generic stored data,\n * sugar that compiles away):\n *\n * - **Stored** schemas (`WorkflowDefinitionSchema`, `OpSchema`, …) describe\n * the primitives the engine persists. No sugar variants, every state\n * reference carries an explicit resolved `scope`.\n * - **Authoring** schemas (`AuthoringWorkflowSchema`, …) accept the same\n * primitives **plus** define-time sugar: the `claim` field/action pair,\n * the `audit` op, the `roles` and `status` action fields, omitted\n * transition filters, omitted reference scopes. `desugar.ts` expands\n * authoring input into the stored shape.\n *\n * Strictness: every object schema is `v.strictObject` so unknown keys\n * produce a parse error. That catches typos like `verison: 1` at deploy\n * time — and it is also what enforces each sugar contract's *reserved*\n * fields (an `ops:` on a `claim` action is an unknown key, fail loud).\n */\n\nimport * as v from 'valibot'\n\nimport {checkLiteralSeed} from '../core/field-validation.ts'\nimport {\n MUTATION_GUARD_ACTIONS,\n FIELD_SCOPES,\n ACTIVITY_KINDS,\n ACTIVITY_STATUSES,\n TERMINAL_ACTIVITY_STATUSES,\n type ActivityKind,\n type TerminalActivityStatus,\n} from '../types/enums.ts'\n\nconst NonEmpty = v.pipe(v.string(), v.minLength(1, 'must be a non-empty string'))\n\nconst PositiveInt = v.pipe(v.number(), v.integer(), v.minValue(1))\n\n/**\n * Names that get spliced into GROQ — field entries (`$fields.<name>` in the\n * claim no-steal filter and every condition) and named-condition keys (`$<name>`).\n * A name like `review-owner` would parse as subtraction inside GROQ and\n * silently change the expression's meaning, so these are constrained to\n * GROQ-identifier-safe names. See {@link GROQ_IDENTIFIER}.\n */\nexport const GROQ_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/\n\nfunction groqIdentifier(referencedAs: string) {\n return v.pipe(\n v.string(),\n v.regex(\n GROQ_IDENTIFIER,\n `must be a GROQ-safe identifier (letters, digits, underscore; not starting with a digit) ` +\n `because it is referenced as ${referencedAs} in GROQ conditions`,\n ),\n )\n}\n\n/**\n * Picklist with a zod-compatible \"Invalid option\" message that lists every\n * allowed value, so a typo'd discriminator or enum lands with a message an\n * author can act on (e.g. `Invalid option: expected one of \"done\"|\"skipped\"`).\n */\nfunction picklist<const TOptions extends readonly [string, ...string[]]>(options: TOptions) {\n return v.picklist(\n options,\n `Invalid option: expected one of ${options.map((o) => `\"${o}\"`).join('|')}`,\n )\n}\n\n// Bidirectional \"same shape\" check, in two parts that each cover a gap the\n// other leaves. The tuple wrap (`[A] extends [B]`) stops union distribution so\n// both operate on the whole types.\ntype MutuallyAssignable<A, B> = [A] extends [B] ? ([B] extends [A] ? true : false) : false\n/** Same key SET both ways — catches an extra field (optional *or* required) on\n * one side, which {@link MutuallyAssignable} alone misses: an extra *optional*\n * field stays mutually assignable (absent satisfies optional). */\ntype SameKeys<A, B> = [keyof A] extends [keyof B]\n ? [keyof B] extends [keyof A]\n ? true\n : false\n : false\n/** The schema output and its pinned type are the exact same shape — same keys\n * AND mutually assignable values/optionality. (Strict structural identity via\n * the `(<G>() => …)` trick is unusable here: it false-negatives on the\n * intersection-typed mirrors like {@link FieldEntry}.) */\ntype ExactlyMirrors<A, B> =\n SameKeys<A, B> extends true ? (MutuallyAssignable<A, B> extends true ? true : false) : false\n\n/**\n * Pin a runtime schema to its hand-written node type, BIDIRECTIONALLY: the call\n * is a **compile error** unless the schema's inferred output is the exact same\n * shape as `T` — so the schema and its type cannot drift in *either* direction\n * (a schema field the type omits, OR a type field the schema lacks, both fail;\n * a one-way `: v.GenericSchema<T>` annotation misses the former). The returned\n * `v.GenericSchema<T>` widens the schema's expressed type to a named type,\n * which is what stops api-extractor inlining it into the multi-thousand-line\n * `v.StrictObjectSchema<{…}>` whose `v.InferOutput` trips `TS2589` for published\n * consumers (see the file header).\n *\n * The drift check rides a second rest-parameter: when the output matches it is\n * `[]` (call with one arg), otherwise it is a one-tuple, so the call reports\n * \"Expected 2 arguments, but got 1\" at the offending schema.\n */\nfunction pinned<T>() {\n return <S extends v.GenericSchema>(\n schema: S,\n ..._exact: ExactlyMirrors<v.InferOutput<S>, T> extends true\n ? []\n : [error: 'schema output is not the same shape as its pinned type']\n // Safe: the rest-param has type-proven `InferOutput<S>` ≅ `T`, and the value\n // is a real schema whose parse output is `T`; this only widens its type.\n ): v.GenericSchema<T> => schema as unknown as v.GenericSchema<T>\n}\n\n// Where a value comes from. Two distinct jobs, two types — never conflated:\n// FieldSource is how a field SEEDS its `initialValue`; ValueExpr is what an op\n// WRITES. They overlap on two arms — a constant and a field read — declared\n// once below and shared by both. Conditions and effect bindings are neither —\n// they are GROQ strings over the rendered scope ($fields, $actor, $row, …).\n\ntype LiteralExpr = {type: 'literal'; value: unknown}\ntype FieldReadExpr = {\n type: 'fieldRead'\n scope?: 'workflow' | 'stage' | undefined\n field: string\n path?: string | undefined\n}\n\nconst LiteralSchema = v.strictObject({type: v.literal('literal'), value: v.unknown()})\nconst FieldReadSchema = v.strictObject({\n type: v.literal('fieldRead'),\n scope: v.optional(v.union([v.literal('workflow'), v.literal('stage')])),\n field: NonEmpty,\n path: v.optional(v.string()),\n})\n\n// FieldSource — a field's seed recipe: how its `initialValue` is produced once,\n// at materialisation (then advisory; the field is freely editable after). Every\n// arm is a discriminated `{type, …}` object — defs are data, not code, so a\n// seed stays serializable and unambiguous, never a bare value. An ABSENT\n// `initialValue` means working memory: the field starts empty and an op fills it\n// later. That is the common default, so it is spelled by omission, not an arm.\ntype FieldSourceInternal =\n | {type: 'input'}\n | {type: 'query'; query: string}\n | LiteralExpr\n | FieldReadExpr\n\nconst FieldSourceSchema: v.GenericSchema<FieldSourceInternal> = v.union([\n // The caller supplies it at start/spawn (`initialFields` / `subworkflows.with`).\n v.strictObject({type: v.literal('input')}),\n // Computed once by running GROQ against the lake at materialisation.\n v.strictObject({type: v.literal('query'), query: NonEmpty}),\n LiteralSchema,\n FieldReadSchema,\n])\nexport type FieldSource = FieldSourceInternal\n\n// ValueExpr — an op payload expression, resolved to concrete JSON when the op\n// applies. Each context-bound arm has a rendered $-twin in conditions\n// (actor ↔ $actor, now ↔ $now, self ↔ $self) so learning one side teaches the\n// other.\ntype ValueExprInternal =\n | LiteralExpr\n | FieldReadExpr\n | {type: 'param'; param: string}\n | {type: 'actor'}\n | {type: 'now'}\n | {type: 'self'}\n | {type: 'stage'}\n | {type: 'object'; fields: Record<string, ValueExprInternal>}\n\nconst ValueExprSchema: v.GenericSchema<ValueExprInternal> = v.lazy(() =>\n v.union([\n LiteralSchema,\n FieldReadSchema,\n v.strictObject({type: v.literal('param'), param: NonEmpty}),\n v.strictObject({type: v.literal('actor')}),\n v.strictObject({type: v.literal('now')}),\n v.strictObject({type: v.literal('self')}),\n v.strictObject({type: v.literal('stage')}),\n v.strictObject({type: v.literal('object'), fields: v.record(NonEmpty, ValueExprSchema)}),\n ]),\n)\nexport type ValueExpr = ValueExprInternal\n\n// Field references — `{ scope?, field }` addressing a field entry by name.\n// Authoring may omit `scope`; desugar resolves it lexically (activity → stage →\n// workflow), so the STORED form always carries an explicit scope.\n\nconst StoredFieldRefSchema = v.strictObject({\n scope: picklist(FIELD_SCOPES),\n field: NonEmpty,\n})\nexport type StoredFieldRef = v.InferOutput<typeof StoredFieldRefSchema>\n\nconst AuthoringFieldRefSchema = v.strictObject({\n scope: v.optional(picklist(FIELD_SCOPES)),\n field: NonEmpty,\n})\nexport type AuthoringFieldRef = v.InferOutput<typeof AuthoringFieldRefSchema>\n\n// Manual-activity deep-link target — render-only metadata for the \"go do this off\n// system\" affordance on a `kind: \"manual\"` activity: either a static URL, or a\n// field reference whose resolved document the consumer opens. The `field`\n// variant resolves lexically at desugar like every op target, so the stored\n// form carries an explicit scope; deploy checks it points at a doc-valued entry.\n// A manual target's URL becomes an `href` in a downstream consumer, so the\n// scheme is allow-listed to http(s) at deploy — `v.url()` alone accepts\n// `javascript:` / `data:` / `file:`, which have no business in a deep-link.\nconst HREF_SCHEMES = ['http:', 'https:']\n// Tolerant of unparseable input — the pipe doesn't short-circuit, so this runs\n// even when `v.url()` already flagged the string; a parse failure is `false`,\n// not a thrown error.\nfunction isHttpUrl(value: string): boolean {\n try {\n return HREF_SCHEMES.includes(new URL(value).protocol)\n } catch {\n return false\n }\n}\nconst UrlString = v.pipe(\n v.string(),\n v.url('must be a valid URL'),\n v.check(isHttpUrl, 'must be an http(s) URL'),\n)\n\nfunction manualTargetSchema<TRef extends v.GenericSchema>(ref: TRef) {\n return v.variant('type', [\n v.strictObject({type: v.literal('url'), url: UrlString}),\n v.strictObject({type: v.literal('field'), field: ref}),\n ])\n}\n\nconst StoredManualTargetSchema = manualTargetSchema(StoredFieldRefSchema)\nexport type ManualTarget = v.InferOutput<typeof StoredManualTargetSchema>\n\n// Authoring accepts a bare field name as well as `{scope?, field}`, like the\n// `claim` action's field reference; desugar normalises and resolves it.\nconst AuthoringManualTargetSchema = manualTargetSchema(v.union([NonEmpty, AuthoringFieldRefSchema]))\nexport type AuthoringManualTarget = v.InferOutput<typeof AuthoringManualTargetSchema>\n\n// Declared before the ops section: the where-ops' `where` is a condition, so\n// `opSchemas` evaluates this schema when `StoredFieldOpSchema` is built below.\nconst ConditionSchema = NonEmpty\n\n/**\n * A raw GROQ string evaluated over the rendered scope: the engine-bound\n * variables inventoried in {@link CONDITION_VARS} (each annotated with the\n * context that binds it) plus the author's nullary `predicates` as `$<name>`\n * booleans. Evaluation runs against the instance's in-memory snapshot —\n * never a `_type` scan over the lake (rejected at deploy).\n *\n * There is no `{ref, args}` wrapper: parameterized reuse is a define-time\n * TypeScript function producing a condition string (see the {@link groq} tag).\n */\nexport type Condition = string\n\n// Ops — the six stored mutation primitives. `value` is the one payload key.\n// The where-ops (`field.updateWhere` / `field.removeWhere`) select rows with a\n// `where` CONDITION — the same rendered-scope GROQ as every filter — with the\n// op-only vars `$row` (the row under test) and `$params` (the firing action's\n// args) bound. A GROQ-null (unevaluable) row never matches: `where` is row\n// selection, not gating.\n// `status.set` may name a sibling activity; desugar fills the firing activity when\n// authoring omitted it, so the stored op always carries `activity`.\n\nfunction opSchemas<T extends v.GenericSchema>(targetSchema: T) {\n return [\n v.strictObject({\n type: v.literal('field.set'),\n target: targetSchema,\n value: ValueExprSchema,\n }),\n v.strictObject({\n type: v.literal('field.unset'),\n target: targetSchema,\n }),\n v.strictObject({\n type: v.literal('field.append'),\n target: targetSchema,\n value: ValueExprSchema,\n }),\n v.strictObject({\n type: v.literal('field.updateWhere'),\n target: targetSchema,\n where: ConditionSchema,\n value: ValueExprSchema,\n }),\n v.strictObject({\n type: v.literal('field.removeWhere'),\n target: targetSchema,\n where: ConditionSchema,\n }),\n ] as const\n}\n\n/**\n * The `field.*` subset — every mutation op EXCEPT `status.set`. Shared by the\n * boundaries that write fields but must not set an activity status: a transition\n * (its stage's activities are tearing down, so `status.set` has no coherent\n * target) and an effect's completion (an effect is OUTSIDE the activity's own\n * awaiting — it reports its result through fields, never by flipping a status;\n * the activity/stage gate then reads those fields). The full {@link StoredOpSchema}\n * (these plus `status.set`) is what actions and activity boundaries carry.\n */\nexport const StoredFieldOpSchema = v.variant('type', [...opSchemas(StoredFieldRefSchema)])\nexport type FieldOp = v.InferOutput<typeof StoredFieldOpSchema>\n\nconst StoredOpSchema = v.variant('type', [\n ...opSchemas(StoredFieldRefSchema),\n v.strictObject({\n type: v.literal('status.set'),\n activity: NonEmpty,\n status: picklist(ACTIVITY_STATUSES),\n }),\n])\nexport type Op = v.InferOutput<typeof StoredOpSchema>\n\n/** A transition carries the field-op subset (no `status.set`) — see {@link FieldOp}. */\nconst StoredTransitionOpSchema = StoredFieldOpSchema\nexport type TransitionOp = FieldOp\n\n// Authoring ops: scope optional on targets, `activity` optional on status.set\n// (defaults to the firing activity), plus the `audit` sugar type — a stamped\n// append whose expansion merges `actor`/`at` ValueExpr fields into its own value.\n\nconst AuditOpSchema = v.strictObject({\n type: v.literal('audit'),\n target: AuthoringFieldRefSchema,\n value: ValueExprSchema,\n stampFields: v.optional(\n v.strictObject({\n actor: v.optional(NonEmpty),\n at: v.optional(NonEmpty),\n }),\n ),\n})\n\nexport const AuthoringOpSchema = v.variant('type', [\n ...opSchemas(AuthoringFieldRefSchema),\n v.strictObject({\n type: v.literal('status.set'),\n activity: v.optional(NonEmpty),\n status: picklist(ACTIVITY_STATUSES),\n }),\n AuditOpSchema,\n])\nexport type AuthoringOp = v.InferOutput<typeof AuthoringOpSchema>\n\n// Field entries — the generic stored data. Kinds are bare: a discriminator is\n// unique within its union; namespaces live only on engine-owned lake document\n// `_type`s ({@link WORKFLOW_DEFINITION_TYPE}, the instance type).\n\n/**\n * The kinds a VALUE can take — scalars aligned to Sanity's names, the\n * reference kinds, the actor/assignee identities, and the two compositional\n * kinds (`object` with named `fields`, `array` of objects shaped by `of`).\n * This is also the set a nested {@link FieldShape} sub-field may use.\n */\nconst FIELD_VALUE_KINDS = [\n 'doc.ref',\n 'doc.refs',\n // Release reference. A workflow declares this entry to say \"I target a\n // Content Release\"; the runtime fills it at start time and auto-derives\n // the instance's read perspective from it.\n 'release.ref',\n 'string',\n 'text',\n 'number',\n 'boolean',\n 'date',\n 'datetime',\n 'url',\n 'actor',\n // A single {@link Assignee} — the singular of `assignees`.\n 'assignee',\n // The WHO-FOR entry: the inbox reverse-query reads it by kind, and the\n // rendered `$assigned` gate matches the caller against it.\n 'assignees',\n // Compositional kinds — mirror Sanity's `object.fields` / `array.of`.\n 'object',\n 'array',\n] as const\n\n/** The union a value (or nested {@link FieldShape}) kind may take — see {@link FIELD_VALUE_KINDS}. */\ntype FieldValueKind = (typeof FIELD_VALUE_KINDS)[number]\n\nconst FieldValueKindSchema = picklist(FIELD_VALUE_KINDS)\n\nconst FieldKindSchema = picklist(FIELD_VALUE_KINDS)\n\nconst FieldEntryName = groqIdentifier('`$fields.<name>`')\n\n// Compositional kinds carry a recursive sub-field shape (`object.fields` /\n// `array.of`). A {@link FieldShape} is lighter than a {@link FieldEntry}: it\n// carries only `type`/`name`/labels and its own nesting — the field-level\n// concerns (`initialValue`/`editable`/`required`) live ONLY on the top-level\n// entry, since a sub-field's value comes from the parent value.\n\nfunction asShape(input: unknown): {\n type?: unknown\n name?: unknown\n fields?: unknown\n of?: unknown\n} {\n return typeof input === 'object' && input !== null ? input : {}\n}\n\n/**\n * The compositional-kind contract, shared by top-level field entries and\n * nested {@link FieldShape}s: an `object` carries non-empty `fields` (and no\n * `of`), an `array` carries non-empty `of` (and no `fields`), and every other\n * kind carries neither.\n */\nfunction compositeShapeOk(input: unknown): boolean {\n const shape = asShape(input)\n if (shape.type === 'object') {\n return Array.isArray(shape.fields) && shape.fields.length > 0 && shape.of === undefined\n }\n if (shape.type === 'array') {\n return Array.isArray(shape.of) && shape.of.length > 0 && shape.fields === undefined\n }\n return shape.fields === undefined && shape.of === undefined\n}\n\nfunction compositeShapeMessage(input: unknown): string {\n const shape = asShape(input)\n if (shape.type === 'object') {\n return shape.of !== undefined\n ? 'an `object` kind declares its sub-fields with `fields`, not `of`'\n : 'an `object` kind needs a non-empty `fields` list of sub-field shapes'\n }\n if (shape.type === 'array') {\n return shape.fields !== undefined\n ? 'an `array` kind declares its item shape with `of`, not `fields`'\n : 'an `array` kind needs a non-empty `of` list of sub-field shapes'\n }\n return `\\`fields\\` / \\`of\\` are only valid on the \\`object\\` / \\`array\\` kinds, not \"${String(shape.type)}\"`\n}\n\n/** The first duplicated sub-field name in an object's `fields` / array's `of`,\n * or undefined when they are unique. Sub-field names key the value object, so a\n * duplicate would silently overwrite (last-wins) and drop a declared shape. */\nfunction duplicateSubfieldName(input: unknown): string | undefined {\n const shape = asShape(input)\n let list: unknown[] = []\n if (Array.isArray(shape.fields)) list = shape.fields\n else if (Array.isArray(shape.of)) list = shape.of\n const seen = new Set<string>()\n for (const item of list) {\n const name = asShape(item).name\n if (typeof name !== 'string') continue\n if (seen.has(name)) return name\n seen.add(name)\n }\n return undefined\n}\n\n/**\n * Build a strict object schema that also enforces the compositional-kind\n * contract. The `v.check`s are inlined here (not shared consts) so valibot\n * threads the object's output type through them — an extracted check loses that\n * inference and breaks the pipe.\n */\nfunction compositeChecked<TEntries extends v.ObjectEntries>(entries: TEntries) {\n return v.pipe(\n v.strictObject(entries),\n v.check(\n (input) => compositeShapeOk(input),\n (issue) => compositeShapeMessage(issue.input),\n ),\n v.check(\n (input) => duplicateSubfieldName(input) === undefined,\n (issue) =>\n `duplicate sub-field name \"${duplicateSubfieldName(issue.input)}\" — sub-field names must be unique within \\`fields\\` / \\`of\\``,\n ),\n )\n}\n\nexport interface FieldShape {\n type: FieldValueKind\n name: string\n title?: string | undefined\n description?: string | undefined\n fields?: FieldShape[] | undefined\n of?: FieldShape[] | undefined\n}\n\nconst FieldShapeSchema: v.GenericSchema<FieldShape> = v.lazy(() =>\n compositeChecked({\n type: FieldValueKindSchema,\n name: FieldEntryName,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n fields: v.optional(v.array(FieldShapeSchema)),\n of: v.optional(v.array(FieldShapeSchema)),\n }),\n)\n\n/**\n * Declared editability of a field — the generic edit seam's gate. Default\n * (absent) is NOT editable: a field is op-only engine working memory unless the\n * modeler opens it. The stored form is `true` (editable by anyone within the\n * field's scope window) or an EDIT CONDITION — rendered-scope GROQ (`$actor`,\n * `$can`, `$fields`, `$assigned`), checked like an action filter to decide\n * who-may-edit. ADVISORY like every engine gate — it disables the inline field\n * and explains; a {@link Guard} declares the intended write-lock.\n */\nconst StoredEditableSchema = v.union([v.literal(true), NonEmpty])\nexport type Editable = v.InferOutput<typeof StoredEditableSchema>\n\n/**\n * Authoring editability adds the `role[]` convenience: a non-empty role list\n * desugars to the same `count($actor.roles[@ in [...]]) > 0` membership\n * predicate `action.roles` produces. `true` opens the field to anyone in its\n * window; a bare string is a raw predicate.\n */\nconst AuthoringEditableSchema = v.union([v.literal(true), v.array(NonEmpty), NonEmpty])\nexport type AuthoringEditable = v.InferOutput<typeof AuthoringEditableSchema>\n\n// The node types below are hand-written object-literal type aliases (not\n// interfaces) by design: a type alias to an object literal carries an implicit\n// index signature, so a definition stays assignable to `Record<string, unknown>`\n// the way the former `v.InferOutput` aliases were — `interface` drops that and\n// breaks real call sites. Concretely: `DeployedDefinition` (`WorkflowDefinition &\n// {…}`, api/deploy.ts) is read as an opaque record — `loadLatestDeployed` →\n// `diffEntry(latestRaw: Record<string, unknown>)` (definition-diff.ts) and\n// `stripSystemFields(doc: Record<string, unknown>)` — which only compiles while\n// the underlying `WorkflowDefinition` keeps that implicit index signature.\n\n/** Type-mirror of {@link fieldBase}, parameterised over the `editable` grammar. */\ntype FieldBase<TEditable> = {\n name: string\n title?: string | undefined\n description?: string | undefined\n required?: boolean | undefined\n initialValue?: FieldSource | undefined\n editable?: TEditable | undefined\n}\n\n/** The field-level concerns every field carries — name, labels, the seed recipe,\n * and who-may-edit — shared by raw entries and the `todoList`/`notes` list\n * sugars, parameterised over the `editable` grammar (stored is normalised;\n * authoring keeps `role[]`). */\nfunction fieldBase<TEditable extends v.GenericSchema>(editable: TEditable) {\n return {\n name: FieldEntryName,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n /**\n * When true, the caller MUST supply this entry at start (via\n * `initialFields`) or spawn (via the parent's `subworkflows.with`). A\n * missing required entry throws rather than silently defaulting to\n * `null`/`[]` — the same fail-fast an action's `required` param gets.\n * Valid only on a workflow-scope `input`-sourced entry (deploy invariant).\n */\n required: v.optional(v.boolean()),\n /**\n * How this field SEEDS its value at materialisation — see\n * {@link FieldSourceSchema}. Optional: an absent `initialValue` is working\n * memory (the field starts empty and an op fills it later), the common case.\n */\n initialValue: v.optional(FieldSourceSchema),\n /** Who-may-edit this field via the edit seam — see {@link StoredEditableSchema}. */\n editable: v.optional(editable),\n }\n}\n\n/** Type-mirror of {@link fieldEntryFields}: a raw field entry of the given\n * editability grammar. */\ntype FieldEntryFields<TEditable> = FieldBase<TEditable> & {\n type: FieldValueKind\n fields?: FieldShape[] | undefined\n of?: FieldShape[] | undefined\n}\n\n/** Field-entry fields shared by the stored and authoring shapes: the field-level\n * concerns plus the kind discriminator and the compositional `fields` / `of`. */\nfunction fieldEntryFields<TEditable extends v.GenericSchema>(editable: TEditable) {\n return {\n type: FieldKindSchema,\n ...fieldBase(editable),\n /** Sub-field shapes for an `object` kind (see {@link compositeShapeOk}). */\n fields: v.optional(v.array(FieldShapeSchema)),\n /** Item sub-field shapes for an `array` kind (see {@link compositeShapeOk}). */\n of: v.optional(v.array(FieldShapeSchema)),\n }\n}\n\n/**\n * Issues for an entry whose `initialValue` is a LITERAL that doesn't fit the\n * declared kind — the seed's shape is knowable at define time, so a mismatch\n * (or a ref id outside the bare | GDR | `@<alias>:` grammar) fails here, not\n * at materialisation. Non-literal sources (input/query/fieldRead) resolve at\n * runtime and are validated there.\n */\nfunction literalSeedIssues(entry: {\n type: string\n initialValue?: FieldSource | undefined\n fields?: FieldShape[] | undefined\n of?: FieldShape[] | undefined\n}): string[] | undefined {\n if (entry.initialValue?.type !== 'literal') return undefined\n return checkLiteralSeed({\n entryType: entry.type,\n value: entry.initialValue.value,\n fields: entry.fields,\n of: entry.of,\n })\n}\n\n/** The literal-seed check as a pipe action, typed to the entry shape it rides\n * on — one check shared by the stored and authoring entry schemas. */\nfunction literalSeedCheck<TEntry extends Parameters<typeof literalSeedIssues>[0]>() {\n return v.check(\n (entry: TEntry) => literalSeedIssues(entry) === undefined,\n (issue) =>\n `initialValue literal does not fit the declared kind: ${(literalSeedIssues(issue.input) ?? []).join('; ')}`,\n )\n}\n\nexport type FieldEntry = FieldEntryFields<Editable>\nconst FieldEntrySchema = pinned<FieldEntry>()(\n v.pipe(compositeChecked(fieldEntryFields(StoredEditableSchema)), literalSeedCheck<FieldEntry>()),\n)\n\ntype AuthoringRawFieldEntry = FieldEntryFields<AuthoringEditable>\nconst RawAuthoringFieldEntrySchema = pinned<AuthoringRawFieldEntry>()(\n v.pipe(\n compositeChecked(fieldEntryFields(AuthoringEditableSchema)),\n literalSeedCheck<AuthoringRawFieldEntry>(),\n ),\n)\n\n/**\n * Authoring fields accept the raw entries plus the `claim` sugar type — the\n * field half of the mirrored claim pair. Expansion: an `actor` working-\n * memory field (no `initialValue`; the claim action's op fills it), strictly\n * within this entry.\n */\ntype ClaimField = {\n type: 'claim'\n name: string\n title?: string | undefined\n description?: string | undefined\n}\nconst ClaimFieldSchema = pinned<ClaimField>()(\n v.strictObject({\n type: v.literal('claim'),\n name: FieldEntryName,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n }),\n)\n\n/** Fields shared by the `todoList` / `notes` list sugars — both desugar to an\n * `array` kind with a fixed `of`, so they accept the same field-level concerns\n * a raw entry does (`initialValue` optional — absent is working memory, the\n * common case for a list ops append rows to). */\nfunction listSugarFields<const TType extends string>(type: TType) {\n return {\n type: v.literal(type),\n ...fieldBase(AuthoringEditableSchema),\n }\n}\n\n/**\n * `todoList` — ad-hoc, status-tracked work items. Sugar over `array of object\n * { label, status, assignee?, dueDate? }`; a plain checklist is this used with\n * `{label, status}` only (open ↔ done). Never a stored kind.\n */\ntype TodoListField = FieldBase<AuthoringEditable> & {\n type: 'todoList'\n}\nconst TodoListFieldSchema = pinned<TodoListField>()(v.strictObject(listSugarFields('todoList')))\n\n/**\n * `notes` — an append-only audit/comment log. Sugar over `array of object\n * { body, actor, at }` (the `actor`/`at` sub-fields match the `audit` op's\n * stamp names, so it pairs with it). Never a stored kind.\n */\ntype NotesField = FieldBase<AuthoringEditable> & {\n type: 'notes'\n}\nconst NotesFieldSchema = pinned<NotesField>()(v.strictObject(listSugarFields('notes')))\n\nexport type AuthoringFieldEntry = AuthoringRawFieldEntry | ClaimField | TodoListField | NotesField\nexport const AuthoringFieldEntrySchema = pinned<AuthoringFieldEntry>()(\n v.union([RawAuthoringFieldEntrySchema, ClaimFieldSchema, TodoListFieldSchema, NotesFieldSchema]),\n)\n\n// Effects — the registry model. `name` is the effect's only identity; the\n// host app registers a handler against it (1:1) and the stored definition\n// never references code. Names are unique per definition (invariant) so\n// `$effects.<name>` is unambiguous.\n\nexport const EffectSchema = v.strictObject({\n name: NonEmpty,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n /** GROQ reads over the rendered scope, resolved to concrete JSON at queue time. */\n bindings: v.optional(v.record(v.string(), ConditionSchema)),\n /** Static config, passed through to the handler verbatim. */\n input: v.optional(v.record(v.string(), v.unknown())),\n})\nexport type Effect = v.InferOutput<typeof EffectSchema>\n\n// Actions\n\n/**\n * Caller-supplied params declared on an action. The engine validates\n * incoming `params` against this list before running ops or queuing\n * effects: missing required params → ActionParamsInvalidError, action\n * does not commit. Resolved values feed `ValueExpr.param` lookups.\n */\nconst ActionParamSchema = v.strictObject({\n type: picklist([\n 'string',\n 'number',\n 'boolean',\n 'url',\n 'dateTime',\n 'actor',\n 'doc.ref',\n 'doc.refs',\n 'json',\n ]),\n name: NonEmpty,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n required: v.optional(v.boolean()),\n})\nexport type ActionParam = v.InferOutput<typeof ActionParamSchema>\n\n/** Type-mirror of {@link actionFields}, parameterised over the op grammar. */\ntype ActionFields<TOp> = {\n name: string\n title?: string | undefined\n description?: string | undefined\n filter?: string | undefined\n params?: ActionParam[] | undefined\n ops?: TOp[] | undefined\n effects?: Effect[] | undefined\n}\n\n/** Fields shared by the stored and authoring action shapes, parameterised\n * over the op schema (stored ops are fully resolved; authoring ops keep\n * their sugar). */\nfunction actionFields<TOp extends v.GenericSchema>(op: TOp) {\n return {\n name: NonEmpty,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n /**\n * The one gate mechanism: a condition over the rendered scope. Hard\n * enforcement lives outside the engine; every engine-evaluated gate is\n * authoring/UX.\n */\n filter: v.optional(ConditionSchema),\n params: v.optional(v.array(ActionParamSchema)),\n ops: v.optional(v.array(op)),\n effects: v.optional(v.array(EffectSchema)),\n }\n}\n\nexport type Action = ActionFields<Op>\nconst StoredActionSchema = pinned<Action>()(v.strictObject(actionFields(StoredOpSchema)))\n\nconst TerminalActivityStatus = picklist(TERMINAL_ACTIVITY_STATUSES)\n\n/**\n * Authoring action — the stored fields plus two field sugars with one\n * defined expansion each:\n *\n * - `roles` → a `count($actor.roles[@ in [...]]) > 0` membership condition\n * ANDed with the authored `filter`. The definition's `roleAliases`\n * ({@link RoleAliasesSchema}) widen that membership at desugar time.\n * - `status` → a `status.set` op on the firing activity, appended **after**\n * the authored ops (deliberately never implied: a forgotten explicit\n * `status` is a visible stall, an implied default silently completes\n * claim-like actions). Status is the health axis: a decision action\n * (decline, send back) resolves `done` and writes the decision into a\n * field the transition filter reads — `failed` is for work that\n * genuinely could not complete.\n */\ntype AuthoringRawAction = ActionFields<AuthoringOp> & {\n roles?: string[] | undefined\n status?: TerminalActivityStatus | undefined\n}\nconst RawAuthoringActionSchema = pinned<AuthoringRawAction>()(\n v.strictObject({\n ...actionFields(AuthoringOpSchema),\n roles: v.optional(v.array(NonEmpty)),\n status: v.optional(TerminalActivityStatus),\n }),\n)\n\n/**\n * The action half of the mirrored claim pair. `field` references an\n * author-declared actor-valued entry (the pair's other half), resolved\n * lexically. Expansion, strictly within this action: a no-steal\n * `!defined($fields.<field>)` filter ANDed with `roles`/`filter`, plus a\n * `field.set` ← actor op. `ops` and `status` are reserved (the expansion\n * owns them) — strictObject rejects them as unknown keys.\n */\ntype ClaimAction = {\n type: 'claim'\n name: string\n title?: string | undefined\n description?: string | undefined\n field: string | AuthoringFieldRef\n roles?: string[] | undefined\n filter?: string | undefined\n params?: ActionParam[] | undefined\n effects?: Effect[] | undefined\n}\nconst ClaimActionSchema = pinned<ClaimAction>()(\n v.strictObject({\n type: v.literal('claim'),\n name: NonEmpty,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n field: v.union([NonEmpty, AuthoringFieldRefSchema]),\n roles: v.optional(v.array(NonEmpty)),\n filter: v.optional(ConditionSchema),\n params: v.optional(v.array(ActionParamSchema)),\n effects: v.optional(v.array(EffectSchema)),\n }),\n)\n\nexport type AuthoringAction = AuthoringRawAction | ClaimAction\nexport const AuthoringActionSchema = pinned<AuthoringAction>()(\n v.union([RawAuthoringActionSchema, ClaimActionSchema]),\n)\n\n// Subworkflows — declare `subworkflows`, read `$subworkflows`. The spawning\n// activity resolves like any activity: `completeWhen` / `failWhen` over the rendered\n// `$subworkflows`; no `completeWhen` means all subworkflows done.\n\n/**\n * Logical reference to a deployed workflow definition, by its `name` (the\n * stable contract — the tag can be renamed, workflows redeployed). The engine\n * resolves it at spawn time, ordering by `version desc` unless an explicit\n * `version` pins one.\n */\nconst DefinitionRefSchema = v.strictObject({\n name: NonEmpty,\n version: v.optional(v.union([PositiveInt, v.literal('latest')])),\n})\n\nconst SubworkflowsSchema = v.strictObject({\n /** GROQ producing one row per subworkflow; each row binds as `$row`. */\n forEach: NonEmpty,\n definition: DefinitionRefSchema,\n /** Initial fields for each subworkflow — entry name → GROQ over `$row` + the parent scope. */\n with: v.optional(v.record(NonEmpty, ConditionSchema)),\n /**\n * Extra values evaluated in the parent's rendered scope at spawn time and\n * delivered into each subworkflow's `$effects` bag — the parent→child\n * handoff, read exactly like an effect output.\n */\n context: v.optional(v.record(NonEmpty, ConditionSchema)),\n})\nexport type Subworkflows = v.InferOutput<typeof SubworkflowsSchema>\n\n// Activities — activities own the ENTER moment: `ops` + `effects` run at activation,\n// `filter` makes activation conditional on the stage's entry fields, and\n// `activation` switches the stage-enter flip (default `manual`: an activity never\n// activates silently; \"auto\" is the explicit opt-in). An activity with no actions\n// and no `completeWhen` is a machine step — it runs its activation payload\n// and resolves `done` immediately, leaving an audit row.\n\n/** Type-mirror of {@link activityFields}, parameterised over field/action/op/target. */\ntype ActivityFields<TField, TAction, TOp, TTarget> = {\n name: string\n title?: string | undefined\n description?: string | undefined\n kind?: ActivityKind | undefined\n target?: TTarget | undefined\n activation?: 'auto' | 'manual' | undefined\n filter?: string | undefined\n requirements?: Record<string, string> | undefined\n completeWhen?: string | undefined\n failWhen?: string | undefined\n ops?: TOp[] | undefined\n effects?: Effect[] | undefined\n actions?: TAction[] | undefined\n subworkflows?: Subworkflows | undefined\n fields?: TField[] | undefined\n}\n\nfunction activityFields<\n TField extends v.GenericSchema,\n TAction extends v.GenericSchema,\n TOp extends v.GenericSchema,\n TTarget extends v.GenericSchema,\n>({field, action, op, target}: {field: TField; action: TAction; op: TOp; target: TTarget}) {\n return {\n name: NonEmpty,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n /**\n * Advisory BPMN-aligned classification of this activity by its executor (see\n * {@link ACTIVITY_KINDS}). Optional and derived from the activity's shape when\n * omitted; declaring it lets deploy check the shape matches the lane.\n * Changes no gating or resolution — a label for tooling, like `assignees`.\n */\n kind: v.optional(picklist(ACTIVITY_KINDS)),\n /** Deep-link target for a `kind: \"manual\"` activity (off-system work). Render-only\n * metadata; only valid on a manual activity (deploy-checked). */\n target: v.optional(target),\n activation: v.optional(picklist(['auto', 'manual'])),\n filter: v.optional(ConditionSchema),\n /**\n * Readiness gates, by name — conditions over the rendered scope that must\n * hold for the activity to be *executable*, orthogonal to `filter`\n * (visibility). An unmet requirement keeps the activity visible but disables\n * its actions with a `requirements-unmet` verdict naming the unmet keys;\n * all must hold (any-of lives inside one condition). Advisory like every\n * engine gate. Distinct from ACL (authorization) and guards\n * (content-write locks).\n */\n requirements: v.optional(v.record(NonEmpty, ConditionSchema)),\n /**\n * Auto-completion condition — evaluated at activation and on every\n * cascade; truthy flips the activity to `done` with a system actor. On a\n * spawning activity it typically reads `$subworkflows`.\n */\n completeWhen: v.optional(ConditionSchema),\n /**\n * Auto-failure condition — symmetric to `completeWhen`, flips to\n * `failed`. When both are truthy on the same evaluation, `failWhen`\n * wins — failure is the more notable signal.\n */\n failWhen: v.optional(ConditionSchema),\n ops: v.optional(v.array(op)),\n effects: v.optional(v.array(EffectSchema)),\n actions: v.optional(v.array(action)),\n subworkflows: v.optional(SubworkflowsSchema),\n /** Activity-scoped field entries. Resolved at activity activation time. */\n fields: v.optional(v.array(field)),\n }\n}\n\nexport type Activity = ActivityFields<FieldEntry, Action, Op, ManualTarget>\nconst StoredActivitySchema = pinned<Activity>()(\n v.strictObject(\n activityFields({\n field: FieldEntrySchema,\n action: StoredActionSchema,\n op: StoredOpSchema,\n target: StoredManualTargetSchema,\n }),\n ),\n)\n\nexport type AuthoringActivity = ActivityFields<\n AuthoringFieldEntry,\n AuthoringAction,\n AuthoringOp,\n AuthoringManualTarget\n>\nexport const AuthoringActivitySchema = pinned<AuthoringActivity>()(\n v.strictObject(\n activityFields({\n field: AuthoringFieldEntrySchema,\n action: AuthoringActionSchema,\n op: AuthoringOpSchema,\n target: AuthoringManualTargetSchema,\n }),\n ),\n)\n\n// Transitions — purely a condition over the rendered scope. Selection rule:\n// every transition is evaluated on every commit and cascade; the first truthy\n// `filter` in declaration order fires. No action coupling: a routing\n// difference is written into fields by the action and read by the filter.\n\n/** Type-mirror of {@link transitionFields} minus `filter` — stored requires it,\n * authoring omits it (desugar fills the default), so each variant declares it. */\ntype TransitionFields<TOp> = {\n name: string\n title?: string | undefined\n description?: string | undefined\n to: string\n ops?: TOp[] | undefined\n effects?: Effect[] | undefined\n}\n\nfunction transitionFields<TOp extends v.GenericSchema, TFilter extends v.GenericSchema>(\n op: TOp,\n filter: TFilter,\n) {\n return {\n name: NonEmpty,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n to: NonEmpty,\n filter,\n /** The `field.*` subset — field-write-on-move, the stage's EXIT/ARRIVAL payload. */\n ops: v.optional(v.array(op)),\n effects: v.optional(v.array(EffectSchema)),\n }\n}\n\nexport type Transition = TransitionFields<TransitionOp> & {\n filter: string\n}\nconst StoredTransitionSchema = pinned<Transition>()(\n v.strictObject(transitionFields(StoredTransitionOpSchema, ConditionSchema)),\n)\n\n/**\n * Authoring transitions may omit `filter`; desugar fills the safe,\n * overwhelmingly-common gate `\"$allActivitiesDone\"`. \"Fire unconditionally\"\n * stays spellable as an explicit `filter: \"true\"`.\n */\nconst AuthoringTransitionOpSchema = v.variant('type', [\n ...opSchemas(AuthoringFieldRefSchema),\n AuditOpSchema,\n])\ntype AuthoringTransitionOp = v.InferOutput<typeof AuthoringTransitionOpSchema>\n\nexport type AuthoringTransition = TransitionFields<AuthoringTransitionOp> & {\n filter?: string | undefined\n}\nexport const AuthoringTransitionSchema = pinned<AuthoringTransition>()(\n v.strictObject(transitionFields(AuthoringTransitionOpSchema, v.optional(ConditionSchema))),\n)\n\n// Guards — lake mutation guards. A FOREIGN CONTRACT mirrored 1:1: the\n// persisted guard doc's `match` / `predicate` / `metadata` fields are the\n// content lake's API, not engine surface, so the STORED form keeps the lake's\n// vocabulary verbatim. The engine adds exactly two things: `name` (authoring\n// identity — the lake `_id` derives from (instanceId, guard.name)) and the\n// deploy-time read VALUES on `match.idRefs` / `metadata` — typed\n// {@link GuardRead}s when authoring, printed to the stored string spellings\n// (see the block below), resolved at deploy into the bare values the contract\n// expects. The lake does not enforce the guard doc type yet — deployed guards\n// deny optimistically engine-side (see `GUARD_DOC_TYPE`); the lake ACL is the\n// only hard gate until guard enforcement ships.\n\nconst GuardActionSchema = picklist(MUTATION_GUARD_ACTIONS)\nexport type GuardAction = v.InferOutput<typeof GuardActionSchema>\n\n// Guard reads — the deploy-time value read on `match.idRefs` and `metadata`.\n// AUTHORING is typed like every expression: the arms mirror {@link ValueExpr}'s\n// `self`/`now`/`fieldRead` plus the guard-only `effectsRead` (a completed\n// effect's output). Reads are workflow-scope by nature (a guard outlives any\n// activity), so `fieldRead` here carries no `scope`. Desugar prints the STORED\n// string form the deploy resolver and guard refresh speak — `\"$self\"`,\n// `\"$now\"`, `\"$fields.<name>[.path]\"`, `\"$effects['<name>'][.path]\"` — so the\n// stored definition and the lake contract never see the typed authoring form.\n\n// The stored spellings are single-line strings parsed by anchored regexes, so\n// a line break in a path would print a read the deploy validator can't parse —\n// rejected here, like the `'` check on effect names.\nconst GuardReadPath = v.pipe(\n NonEmpty,\n v.check(\n (path) => !/[\\r\\n\\u2028\\u2029]/.test(path),\n 'a guard read path cannot contain a line break',\n ),\n)\n\nconst GuardReadSchema = v.variant('type', [\n v.strictObject({type: v.literal('self')}),\n v.strictObject({type: v.literal('now')}),\n v.strictObject({\n type: v.literal('fieldRead'),\n field: FieldEntryName,\n path: v.optional(GuardReadPath),\n }),\n v.strictObject({\n type: v.literal('effectsRead'),\n // The stored spelling bracket-quotes the name (`$effects['<name>']`), so a\n // quote inside it would corrupt the printed read.\n effect: v.pipe(\n NonEmpty,\n v.check((name) => !name.includes(\"'\"), \"an effect name cannot contain `'`\"),\n ),\n path: v.optional(GuardReadPath),\n }),\n])\nexport type GuardRead = v.InferOutput<typeof GuardReadSchema>\n\nfunction guardMatchFields<TRead extends v.GenericSchema>(read: TRead) {\n return {\n /** Subject `_type`(s); empty matches any type. */\n types: v.optional(v.array(NonEmpty)),\n /** Target docs as field reads (or the instance itself), resolved at deploy to bare ids + the resource. */\n idRefs: v.optional(v.array(read)),\n /** Glob id patterns (bare, resource-local). */\n idPatterns: v.optional(v.array(NonEmpty)),\n actions: v.pipe(\n v.array(GuardActionSchema),\n v.minLength(1, 'a guard must match at least one action'),\n ),\n }\n}\n\nfunction guardFields<TRead extends v.GenericSchema>(read: TRead) {\n return {\n name: NonEmpty,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n match: v.strictObject(guardMatchFields(read)),\n /**\n * Lake GROQ predicate — a distinct eval context reading\n * `document.before`/`document.after`, `mutation`, `guard`, and\n * `identity()`. Bare ids/fields only. Omitted or empty means\n * UNCONDITIONAL DENY.\n */\n predicate: v.optional(v.string()),\n /**\n * Projected workflow fields the predicate reads as `guard.metadata.*` —\n * the only bridge from the lake eval context (which cannot see `$fields`)\n * to workflow fields. Each value is a deploy-time read — a typed\n * {@link GuardRead} when authoring, the printed string spelling once\n * stored — resolved into a bare value at deploy and re-synced by the\n * post-field-op guard refresh.\n */\n metadata: v.optional(v.record(NonEmpty, read)),\n }\n}\n\n/** Stored guards carry the printed string reads (the deploy resolver's input). */\nconst GuardSchema = v.strictObject(guardFields(NonEmpty))\nexport type Guard = v.InferOutput<typeof GuardSchema>\nexport type GuardMatch = Guard['match']\n\nexport const AuthoringGuardSchema = v.strictObject(guardFields(GuardReadSchema))\nexport type AuthoringGuard = v.InferOutput<typeof AuthoringGuardSchema>\n\n// Stages — pure containers: name / fields / guards / activities / transitions, no\n// behaviour of their own. Activities own enter, transitions own exit and arrival.\n// `initial` is whatever `initialStage` names; a stage with no transitions IS\n// terminal (structural, nothing to declare or mis-declare).\n\n/** Type-mirror of {@link stageFields}, parameterised over field/activity/transition/guard/editable. */\ntype StageFields<TField, TActivity, TTransition, TGuard, TEditable> = {\n name: string\n title?: string | undefined\n description?: string | undefined\n activities?: TActivity[] | undefined\n transitions?: TTransition[] | undefined\n guards?: TGuard[] | undefined\n fields?: TField[] | undefined\n editable?: Record<string, TEditable> | undefined\n}\n\nfunction stageFields<\n TField extends v.GenericSchema,\n TActivity extends v.GenericSchema,\n TTransition extends v.GenericSchema,\n TGuard extends v.GenericSchema,\n TEditable extends v.GenericSchema,\n>({\n field,\n activity,\n transition,\n guard,\n editable,\n}: {\n field: TField\n activity: TActivity\n transition: TTransition\n guard: TGuard\n editable: TEditable\n}) {\n return {\n name: NonEmpty,\n title: v.optional(v.string()),\n description: v.optional(v.string()),\n activities: v.optional(v.array(activity)),\n transitions: v.optional(v.array(transition)),\n /**\n * Lake mutation guards active while this stage holds. Each compiles to a\n * persisted guard document deployed on stage entry and retracted on exit.\n */\n guards: v.optional(v.array(guard)),\n /** Stage-scoped field entries. Resolved at stage entry. */\n fields: v.optional(v.array(field)),\n /**\n * Tighten-only editability overrides for the time this stage holds, keyed\n * by an in-scope field name. The field's own `editable` is the ceiling; a\n * stage value is ANDed with it at runtime, so an override can only NARROW\n * (never open a field the baseline left closed). An unlisted field inherits\n * its baseline.\n */\n editable: v.optional(v.record(FieldEntryName, editable)),\n }\n}\n\nexport type Stage = StageFields<FieldEntry, Activity, Transition, Guard, Editable>\nconst StoredStageSchema = pinned<Stage>()(\n v.strictObject(\n stageFields({\n field: FieldEntrySchema,\n activity: StoredActivitySchema,\n transition: StoredTransitionSchema,\n guard: GuardSchema,\n editable: StoredEditableSchema,\n }),\n ),\n)\n\nexport type AuthoringStage = StageFields<\n AuthoringFieldEntry,\n AuthoringActivity,\n AuthoringTransition,\n AuthoringGuard,\n AuthoringEditable\n>\nexport const AuthoringStageSchema = pinned<AuthoringStage>()(\n v.strictObject(\n stageFields({\n field: AuthoringFieldEntrySchema,\n activity: AuthoringActivitySchema,\n transition: AuthoringTransitionSchema,\n guard: AuthoringGuardSchema,\n editable: AuthoringEditableSchema,\n }),\n ),\n)\n\n// Workflow definition (the root)\n\n/**\n * Role aliasing — the \"can be fulfilled by\" map, an authoring convenience.\n * A `roles` gate (or an `assignees` entry) names the role the author writes;\n * but the SAME capability is often carried by different role names depending\n * on how a given project deploys its Content Lake roles, and several roles may\n * legitimately do the job. Rather than enumerate every equivalent role inline\n * in each gate — or fork the definition per deployment — declare once here\n * which other roles also fulfill it.\n *\n * Each key is a role a gate/assignee names; its value lists the roles that\n * also satisfy it. The reserved key `\"*\"` lists roles that fulfill ANY gate\n * (e.g. `\"*\": [\"administrator\"]` — whatever this deployment's broad role is).\n * `\"*\"` is the spelling authors write; it is rewritten to a lake-safe stored\n * key before the definition is persisted, since the Content Lake rejects `\"*\"`\n * as a document attribute name (see {@link normalizeRoleAliases}).\n *\n * Applied as an in-place expansion of the REQUIRED side, never the actor's\n * roles: the `roles` gate bakes the expanded membership into its desugared\n * GROQ at define time; `$assigned` expands the assignee's role at match time\n * (see {@link expandRequiredRoles}). Carried into the stored definition for\n * that runtime half.\n *\n * Advisory, like every engine gate — an alias only predicts what the\n * deployment's Content Lake ACLs already allow, it never grants access. An\n * alias the lake won't honor makes the gate predict \"allowed\" for a write the\n * lake then rejects, so keep it true to what's actually deployed.\n */\nconst RoleAliasesSchema = v.record(\n NonEmpty,\n v.pipe(v.array(NonEmpty), v.minLength(1, 'a role alias must list at least one fulfilling role')),\n)\nexport type RoleAliases = v.InferOutput<typeof RoleAliasesSchema>\n\nconst WORKFLOW_LIFECYCLES = ['standalone', 'child'] as const\n/** How instances of a definition come to exist: started standalone (the\n * default) or spawned by a parent. `'child'` is spawn-only — see\n * {@link isStartableDefinition}. */\nexport type WorkflowLifecycle = (typeof WORKFLOW_LIFECYCLES)[number]\n\n/** Type-mirror of {@link workflowFields}, parameterised over field/stage. */\ntype WorkflowFields<TField, TStage> = {\n name: string\n title: string\n description?: string | undefined\n lifecycle?: WorkflowLifecycle | undefined\n initialStage: string\n fields?: TField[] | undefined\n stages: TStage[]\n predicates?: Record<string, string> | undefined\n roleAliases?: RoleAliases | undefined\n}\n\nfunction workflowFields<TField extends v.GenericSchema, TStage extends v.GenericSchema>(\n field: TField,\n stage: TStage,\n) {\n return {\n name: NonEmpty,\n title: NonEmpty,\n description: v.optional(v.string()),\n /**\n * How instances of this workflow come to exist. `'child'` marks a\n * spawn-only definition — instantiated by a parent via `activity.subworkflows`,\n * never started cold from a picker. Omitted ⇒ `'standalone'` (startable).\n * Advisory: consumers filter their start pickers on it (see\n * {@link isStartableDefinition}); the engine does NOT refuse a\n * `startInstance` on a `'child'` def — load-bearing `required` field is the\n * runtime backstop.\n */\n lifecycle: v.optional(picklist(WORKFLOW_LIFECYCLES)),\n /** Reference field: named for the target, holds the stage's `name`. */\n initialStage: NonEmpty,\n /** Workflow-scope field entries. Persist for the instance lifetime. */\n fields: v.optional(v.array(field)),\n stages: v.pipe(v.array(stage), v.minLength(1, 'must declare at least one stage')),\n /**\n * Nullary named conditions — each `name: groq` entry is pre-evaluated\n * and bound as the boolean `$name` var, composable with native GROQ.\n * Redefining a built-in var is a deploy error (never silently shadow).\n */\n predicates: v.optional(v.record(groqIdentifier('`$<name>`'), ConditionSchema)),\n /** Role aliasing for this definition — see {@link RoleAliasesSchema}. */\n roleAliases: v.optional(RoleAliasesSchema),\n }\n}\n\n/**\n * Structural schema for a STORED workflow definition — primitives only,\n * every reference scope resolved. Cross-field invariants (unique names,\n * transition targets, effect-name uniqueness, predicate shadowing) are\n * checked by `checkWorkflowInvariants` after desugar — see `defineWorkflow`.\n *\n * Carries NO `version` — the author never writes one. A definition's version\n * (and its content fingerprint) are stamped onto the deployed *document* at\n * deploy time, derived from the content itself; see `DeployedDefinition` and\n * `planDefinitionDeploy` in `api/deploy.ts`. The author's content is the sole\n * source of identity: redeploying identical content is a no-op, any change\n * mints the next version.\n */\n// Unlike every other node, nothing consumes this stored-root schema at runtime\n// (a stored definition is the trusted desugar output, never re-parsed — only the\n// authoring root is parsed, by `defineWorkflow`). So the type is taken FROM the\n// schema via `InferOutput` (which, because the schema is `pinned`, short-circuits\n// to the mirror rather than re-deriving the tree) — that keeps the drift pin live\n// without an unused const.\nconst WorkflowDefinitionSchema = pinned<WorkflowFields<FieldEntry, Stage>>()(\n v.strictObject(workflowFields(FieldEntrySchema, StoredStageSchema)),\n)\nexport type WorkflowDefinition = v.InferOutput<typeof WorkflowDefinitionSchema>\n\n/** The authoring surface: stored primitives plus the define-time sugar. */\nexport type AuthoringWorkflow = WorkflowFields<AuthoringFieldEntry, AuthoringStage>\nexport const AuthoringWorkflowSchema = pinned<AuthoringWorkflow>()(\n v.strictObject(workflowFields(AuthoringFieldEntrySchema, AuthoringStageSchema)),\n)\n\n/**\n * The lake document type for a deployed workflow definition. Engine-owned\n * standalone documents carry the platform namespace; in-array discriminators\n * stay bare. Mirrors {@link WORKFLOW_INSTANCE_TYPE}.\n */\nexport const WORKFLOW_DEFINITION_TYPE = 'sanity.workflow.definition'\n\n/**\n * Whether a human may start this definition standalone (the default). A\n * `lifecycle: 'child'` definition is spawn-only — instantiated by a parent via\n * `activity.subworkflows`, so consumers exclude it from top-level start pickers.\n * Advisory: the engine does not enforce it (see the `required`-field backstop\n * for load-bearing input fields). Accepts any definition-shaped value (authored,\n * stored, deployed, or a projected list row).\n */\nexport function isStartableDefinition(definition: {\n lifecycle?: WorkflowLifecycle | undefined\n}): boolean {\n return definition.lifecycle !== 'child'\n}\n\n// Error formatting — turn validation issues into a multi-line,\n// path-prefixed message that points at the exact field the author got\n// wrong. Shared by structural parse errors (via {@link issuesFromValibot})\n// and cross-field invariant issues.\n\nexport interface ValidationIssue {\n path: ReadonlyArray<PropertyKey>\n message: string\n}\n\n/** The buildable path form desugar and the invariants accumulate issues under. */\nexport type IssuePath = (string | number)[]\n\nexport function formatValidationError(label: string, issues: readonly ValidationIssue[]): string {\n const lines = issues.map((issue) => {\n const path = issue.path.length === 0 ? '(root)' : formatPath(issue.path)\n return ` - ${path}: ${issue.message}`\n })\n return `${label} failed validation (${issues.length} issue${\n issues.length === 1 ? '' : 's'\n }):\\n${lines.join('\\n')}`\n}\n\nexport function issuesFromValibot(issues: readonly v.BaseIssue<unknown>[]): ValidationIssue[] {\n return issues.map((issue) => ({\n path: issue.path ? issue.path.map((item) => item.key as PropertyKey) : [],\n message: issue.message,\n }))\n}\n\nfunction formatPath(path: ReadonlyArray<PropertyKey>): string {\n let out = ''\n for (const seg of path) {\n if (typeof seg === 'number') out += `[${seg}]`\n else out += out.length === 0 ? String(seg) : `.${String(seg)}`\n }\n return out\n}\n"],"names":["v"],"mappings":"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"}
|