@sanity/workflow-engine 0.29.0 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/define.d.cts CHANGED
@@ -1,5 +1,20 @@
1
1
  import * as v from "valibot";
2
2
 
3
+ /**
4
+ * A stored action. `semantics` is engine-owned advisory meaning, independent
5
+ * of execution and presentation — an array so the vocabulary can grow without
6
+ * reshaping this field. `when`'s presence makes the action CASCADE-FIRED: the
7
+ * engine fires it the moment the condition turns true, at most once per stage
8
+ * visit, and it is never invocable via `fireAction`; absent, the action must
9
+ * be invoked via `fireAction` by any caller holding a token (fire-on-entry is
10
+ * `when: 'true'`). `filter` is existence with GROQ semantics — a non-matching
11
+ * action might as well not exist (invisible to UI and LLMs, never merely
12
+ * disabled); on a `when` action it composes: `filter` scopes whether the
13
+ * automation exists, `when` is its firing trigger. `roles` is kept VERBATIM
14
+ * only when cascade-fired (the pin on which identities may execute the
15
+ * trigger); a fireAction-fired action's `roles` folds into `filter` at
16
+ * desugar instead.
17
+ */
3
18
  declare type Action = ActionFields<Op, string[]> & {
4
19
  roles?: string[] | undefined;
5
20
  };
@@ -20,14 +35,14 @@ declare type ActionFields<TOp, TGroup> = {
20
35
  spawn?: Subworkflows | undefined;
21
36
  };
22
37
 
23
- declare type ActionParam = v.InferOutput<typeof ActionParamSchema>;
24
-
25
38
  /**
26
- * Caller-supplied params declared on an action. The engine validates
27
- * incoming `params` against this list before running ops or queuing
28
- * effects: missing required params ActionParamsInvalidError, action
29
- * does not commit. Resolved values feed `ValueExpr.param` lookups.
39
+ * Caller-supplied params declared on an action, validated before running ops
40
+ * or queuing effects: a missing required param throws
41
+ * `ActionParamsInvalidError` and the action does not commit. Resolved values
42
+ * feed `ValueExpr.param` lookups.
30
43
  */
44
+ declare type ActionParam = v.InferOutput<typeof ActionParamSchema>;
45
+
31
46
  declare const ActionParamSchema: v.SchemaWithPipe<
32
47
  readonly [
33
48
  v.StrictObjectSchema<
@@ -157,6 +172,20 @@ declare const ActionParamSchema: v.SchemaWithPipe<
157
172
 
158
173
  declare type ActionSemantic = DecisionSemantic | Semantic;
159
174
 
175
+ /**
176
+ * A unit of work carrying no payload of its own — every op, effect, and
177
+ * spawn lives on an action; an activity contributes scoped `fields`
178
+ * (resolved at stage entry), existence (`filter`), advisory readiness
179
+ * (`requirements`), and the off-system marker (`target`, a BPMN Manual Task
180
+ * deep-link, render-only and never gating). All in-scope activities are
181
+ * ACTIVE from stage entry until an action's terminal `status` resolves them —
182
+ * there is no activation moment. `filter` is existence with GROQ semantics,
183
+ * evaluated once against the stage's entry state: a definite `false`
184
+ * excludes the activity from UI, LLMs, and `$allActivitiesDone`.
185
+ * `requirements` are readiness gates orthogonal to `filter` — an unmet one
186
+ * keeps the activity visible but disables its actions with a
187
+ * `requirements-unmet` verdict; distinct from ACL and guards.
188
+ */
160
189
  declare type Activity = ActivityFields<
161
190
  FieldEntry,
162
191
  Action,
@@ -179,6 +208,18 @@ declare type ActivityFields<TField, TAction, TTarget, TGroup> = {
179
208
  fields?: TField[] | undefined;
180
209
  };
181
210
 
211
+ /**
212
+ * The stored action fields plus two authoring sugars, or the
213
+ * {@link ClaimAction} pair-half. `roles`: on a fireAction-fired action (no
214
+ * `when`) it desugars into a `count($actor.roles[@ in [...]]) > 0` condition
215
+ * ANDed with `filter`; on a CASCADE-FIRED action it stores VERBATIM instead —
216
+ * the pin on which identities may execute the trigger, since folding it into
217
+ * `filter` would make the action's existence depend on whose token cascades.
218
+ * `roleAliases` widens the membership either way. `status` compiles to a
219
+ * `status.set` op on the firing activity, appended AFTER the authored ops —
220
+ * deliberately never implied, so a forgotten `status` is a visible stall
221
+ * rather than a silently completed action.
222
+ */
182
223
  declare type AuthoringAction = AuthoringRawAction | ClaimAction;
183
224
 
184
225
  declare type AuthoringActivity = ActivityFields<
@@ -188,14 +229,14 @@ declare type AuthoringActivity = ActivityFields<
188
229
  GroupMembership
189
230
  >;
190
231
 
191
- declare type AuthoringEditable = v.InferOutput<typeof AuthoringEditableSchema>;
192
-
193
232
  /**
194
233
  * Authoring editability adds the `role[]` convenience: a non-empty role list
195
234
  * desugars to the same `count($actor.roles[@ in [...]]) > 0` membership
196
235
  * predicate `action.roles` produces. `true` opens the field to anyone in its
197
236
  * window; a bare string is a raw predicate.
198
237
  */
238
+ declare type AuthoringEditable = v.InferOutput<typeof AuthoringEditableSchema>;
239
+
199
240
  declare const AuthoringEditableSchema: v.UnionSchema<
200
241
  [
201
242
  v.LiteralSchema<true, undefined>,
@@ -224,6 +265,8 @@ declare type AuthoringFieldEntry =
224
265
  | TodoListField
225
266
  | NotesField;
226
267
 
268
+ /** A field reference with `scope` optional; desugar resolves it lexically
269
+ * (activity → stage → workflow) into {@link StoredFieldRef}. */
227
270
  declare type AuthoringFieldRef = v.InferOutput<typeof AuthoringFieldRefSchema>;
228
271
 
229
272
  declare const AuthoringFieldRefSchema: v.StrictObjectSchema<
@@ -242,15 +285,12 @@ declare const AuthoringFieldRefSchema: v.StrictObjectSchema<
242
285
  undefined
243
286
  >;
244
287
 
288
+ /** {@link Guard}'s contract as authored: `match.idRefs` and `metadata` carry
289
+ * typed {@link GuardRead} values that deploy resolves to bare ones. */
245
290
  declare type AuthoringGuard = v.InferOutput<typeof AuthoringGuardSchema>;
246
291
 
247
292
  declare const AuthoringGuardSchema: v.StrictObjectSchema<
248
293
  {
249
- /**
250
- * Lake-id-segment grammar (`^[a-z0-9][a-z0-9-]*$`, deploy-enforced): the
251
- * guard's lake `_id` derives from `(instanceId, name)` at stage entry.
252
- * Unique per definition.
253
- */
254
294
  name: v.SchemaWithPipe<
255
295
  readonly [
256
296
  v.StringSchema<undefined>,
@@ -261,7 +301,6 @@ declare const AuthoringGuardSchema: v.StrictObjectSchema<
261
301
  description: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
262
302
  match: v.StrictObjectSchema<
263
303
  {
264
- /** Subject `_type`(s); empty matches any type. */
265
304
  types: v.OptionalSchema<
266
305
  v.ArraySchema<
267
306
  v.SchemaWithPipe<
@@ -274,7 +313,6 @@ declare const AuthoringGuardSchema: v.StrictObjectSchema<
274
313
  >,
275
314
  undefined
276
315
  >;
277
- /** Target docs as field reads (or the instance itself), resolved at deploy to bare ids + the resource. */
278
316
  idRefs: v.OptionalSchema<
279
317
  v.ArraySchema<
280
318
  v.VariantSchema<
@@ -377,7 +415,6 @@ declare const AuthoringGuardSchema: v.StrictObjectSchema<
377
415
  >,
378
416
  undefined
379
417
  >;
380
- /** Glob id patterns (bare, resource-local). */
381
418
  idPatterns: v.OptionalSchema<
382
419
  v.ArraySchema<
383
420
  v.SchemaWithPipe<
@@ -409,22 +446,7 @@ declare const AuthoringGuardSchema: v.StrictObjectSchema<
409
446
  },
410
447
  undefined
411
448
  >;
412
- /**
413
- * Lake GROQ predicate — a distinct eval context: delta-mode GROQ
414
- * reading the `before()`/`after()` natives, `mutation`, `guard`, and
415
- * `identity()`. Bare ids/fields only. Polarity: a result of strictly
416
- * `true` ALLOWS the matched mutation; anything else (false, null, an
417
- * evaluation error) DENIES. Omitted or empty means UNCONDITIONAL DENY.
418
- */
419
449
  predicate: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
420
- /**
421
- * Projected workflow fields the predicate reads as `guard.metadata.*` —
422
- * the only bridge from the lake eval context (which cannot see `$fields`)
423
- * to workflow fields. Each value is a deploy-time read — a typed
424
- * {@link GuardRead} when authoring, the printed string spelling once
425
- * stored — resolved into a bare value at deploy and re-synced by the
426
- * post-field-op guard refresh.
427
- */
428
450
  metadata: v.OptionalSchema<
429
451
  v.RecordSchema<
430
452
  v.SchemaWithPipe<
@@ -534,6 +556,8 @@ declare const AuthoringGuardSchema: v.StrictObjectSchema<
534
556
  undefined
535
557
  >;
536
558
 
559
+ /** Like {@link ManualTarget}, but the `field` variant also accepts a bare
560
+ * field name; desugar normalises it into {@link AuthoringFieldRef}. */
537
561
  declare type AuthoringManualTarget = v.InferOutput<
538
562
  typeof AuthoringManualTargetSchema
539
563
  >;
@@ -593,6 +617,9 @@ declare const AuthoringManualTargetSchema: v.VariantSchema<
593
617
  undefined
594
618
  >;
595
619
 
620
+ /** Like {@link Op}, plus: `status.set`'s `activity` is optional (desugar fills
621
+ * the firing activity), and the `audit` sugar — a stamped append merging
622
+ * `actor`/`at` {@link ValueExpr} fields into its own value. */
596
623
  declare type AuthoringOp = v.InferOutput<typeof AuthoringOpSchema>;
597
624
 
598
625
  declare const AuthoringOpSchema: v.VariantSchema<
@@ -888,27 +915,6 @@ declare const AuthoringOpSchema: v.VariantSchema<
888
915
  undefined
889
916
  >;
890
917
 
891
- /**
892
- * Authoring action — the stored fields plus two field sugars with one
893
- * defined expansion each:
894
- *
895
- * - `roles` — on a fireAction-fired action (no `when`) it desugars to a
896
- * `count($actor.roles[@ in [...]]) > 0` membership condition ANDed with
897
- * the authored `filter` (for a caller, "not yours to fire" and "doesn't
898
- * exist for you" are the same advisory answer). On a CASCADE-FIRED
899
- * action it stores VERBATIM — the pin on which identities may execute
900
- * the trigger; folding it into `filter` would make the action's
901
- * existence depend on whose token happens to cascade. The definition's
902
- * `roleAliases` ({@link RoleAliasesSchema}) widen the membership either
903
- * way.
904
- * - `status` → a `status.set` op on the firing activity, appended **after**
905
- * the authored ops (deliberately never implied: a forgotten explicit
906
- * `status` is a visible stall, an implied default silently completes
907
- * claim-like actions). Status is the health axis: a decision action
908
- * (decline, send back) resolves `done` and writes the decision into a
909
- * field the transition trigger reads — `failed` is for work that
910
- * genuinely could not complete.
911
- */
912
918
  declare type AuthoringRawAction = ActionFields<AuthoringOp, GroupMembership> & {
913
919
  roles?: string[] | undefined;
914
920
  status?: TerminalActivityStatus | undefined;
@@ -958,14 +964,8 @@ declare interface ChoiceOptions {
958
964
 
959
965
  declare type ChoiceValue = string | number;
960
966
 
961
- /**
962
- * The action half of the mirrored claim pair. `field` references an
963
- * author-declared actor-valued entry (the pair's other half), resolved
964
- * lexically. Expansion, strictly within this action: a no-steal
965
- * `!defined($fields.<field>)` filter ANDed with `roles`/`filter`, plus a
966
- * `field.set` ← actor op. `ops` and `status` are reserved (the expansion
967
- * owns them) — strictObject rejects them as unknown keys.
968
- */
967
+ /** The action half of the mirrored claim pair: `field` names the actor-valued entry this action claims, resolved lexically, and the expansion
968
+ * adds a no-steal `!defined($fields.<field>)` filter ANDed with `roles`/`filter` plus a `field.set` actor op. `ops`/`status` are reserved (strictObject rejects them). */
969
969
  declare type ClaimAction = {
970
970
  type: "claim";
971
971
  name: string;
@@ -979,12 +979,8 @@ declare type ClaimAction = {
979
979
  effects?: Effect[] | undefined;
980
980
  };
981
981
 
982
- /**
983
- * Authoring fields accept the raw entries plus the `claim` sugar type the
984
- * field half of the mirrored claim pair. Expansion: an `actor` working-
985
- * memory field (no `initialValue`; the claim action's op fills it), strictly
986
- * within this entry.
987
- */
982
+ /** The field half of the mirrored claim pair, expanding strictly within this entry: an `actor`
983
+ * working-memory field with no `initialValue` the paired {@link ClaimAction}'s op fills it. */
988
984
  declare type ClaimField = {
989
985
  type: "claim";
990
986
  name: string;
@@ -994,10 +990,23 @@ declare type ClaimField = {
994
990
  };
995
991
 
996
992
  /**
997
- * Every variable the engine binds for conditions, in one place. The
998
- * deploy-time shadow check ({@link RESERVED_CONDITION_VARS}) and the docs on
999
- * {@link Condition} derive from this list — extend it here when the engine
1000
- * grows a binding, never in a comment elsewhere.
993
+ * Every variable the engine binds for the RENDERED condition scope (every
994
+ * condition site: transition `when`s, activity filters, action
995
+ * `when`s/filters, effect bindings, `spawn` reads, where-op `where`s,
996
+ * editability predicates, author predicates) the deploy-time shadow check
997
+ * ({@link RESERVED_CONDITION_VARS}) and the docs on {@link Condition} derive
998
+ * from this list; extend it here when the engine grows a binding, never in
999
+ * a comment elsewhere.
1000
+ *
1001
+ * Three other GROQ contexts read a definition and do NOT share this
1002
+ * inventory: cascade gates (transition/activity/cascade-action gates, which
1003
+ * must resolve identically regardless of caller — only the `'always'`-bound
1004
+ * subset carries values, {@link FILTER_SCOPE_VARS}); the start contexts
1005
+ * (`start.filter` is browse-time-pure over a candidate document,
1006
+ * {@link START_FILTER_VARS}; a start `groq` requirement binds `$fields`
1007
+ * instead, {@link START_REQUIREMENT_VARS}); and lake guard predicates, which
1008
+ * are not conditions at all — delta-mode GROQ over a mutation, binding
1009
+ * {@link GUARD_PREDICATE_VARS} instead.
1001
1010
  */
1002
1011
  export declare const CONDITION_VARS: readonly ConditionVar[];
1003
1012
 
@@ -1011,43 +1020,6 @@ export declare interface ConditionVar {
1011
1020
  label: string;
1012
1021
  }
1013
1022
 
1014
- /**
1015
- * The condition-variable inventory — the single source of truth for every
1016
- * `$var` the engine binds when it evaluates a {@link Condition}.
1017
- *
1018
- * Four evaluation contexts read a definition's GROQ:
1019
- *
1020
- * 1. **Rendered condition scope** — every condition site in a definition
1021
- * (transition `when`s, activity filters, action `when`s/filters, effect
1022
- * bindings, `spawn` reads, where-op `where`s, editability predicates,
1023
- * author predicates). {@link CONDITION_VARS} is its inventory; each
1024
- * entry's `binding` says when the var actually holds a value. The
1025
- * where-op context is the one closed subset — its bound set is statically
1026
- * fixed and deploy-enforced (see the op-where scope's param-name list in
1027
- * the op applier).
1028
- * 2. **Cascade gates** — transition `when`s, activity filters, and a
1029
- * cascade-fired action's `when`/`filter` must resolve identically no
1030
- * matter whose token drives the cascade, so only the `'always'`-bound
1031
- * subset carries values there ({@link FILTER_SCOPE_VARS}). Caller-bound
1032
- * vars fail closed — `$assigned` binds its caller-free constant `false`,
1033
- * the rest evaluate to `undefined` — and deploy rejects them at these
1034
- * sites; a cascade-fired action's per-token gate is `roles`, never its
1035
- * conditions.
1036
- * 3. **The start contexts** — a definition's `start.filter` and start GROQ
1037
- * requirements evaluate against a CANDIDATE (no instance exists yet):
1038
- * `*[...]` reads the engine-owned `{definition, subject, completedAt}`
1039
- * projection of the tag's instances and none of the rendered
1040
- * condition vars exist. The two split on what a surface can know:
1041
- * `filter` is browse-time-pure (candidate document as root,
1042
- * {@link START_FILTER_VARS} — no `$fields`, which cannot exist before
1043
- * inputs do), a `groq` requirement is the start-time readiness predicate
1044
- * ({@link START_REQUIREMENT_VARS} — `$fields` bound, never a root).
1045
- * 4. **Guard predicates** — NOT conditions. A lake mutation guard's
1046
- * `predicate` is groq-js **delta-mode** GROQ over a document mutation:
1047
- * `before()`/`after()`/`identity()` are dialect natives, and the wire
1048
- * format binds the identifiers in {@link GUARD_PREDICATE_VARS}. None of
1049
- * the condition vars exist there.
1050
- */
1051
1023
  /**
1052
1024
  * When a condition var holds a value:
1053
1025
  *
@@ -1063,15 +1035,6 @@ export declare type ConditionVarBinding = "always" | "caller" | "spawn";
1063
1035
  /** A define-time validated `custom.<camelCaseMeaning>` value. */
1064
1036
  declare type CustomSemantic = `custom.${string}`;
1065
1037
 
1066
- /**
1067
- * The maximum reader floor this writer can emit. Individual documents derive
1068
- * their `minReaderModel` from the compatibility-bearing features actually
1069
- * present; a document written at {@link DATA_MODEL_VERSION} may therefore
1070
- * carry a lower floor. Raising this maximum is a declared, DATAMODEL.md-logged
1071
- * decision that requires readers-first fleet sequencing.
1072
- */
1073
- declare const DATA_MODEL_MIN_READER = 4;
1074
-
1075
1038
  declare const DECISION_SEMANTICS: readonly [
1076
1039
  "decision.accept",
1077
1040
  "decision.decline",
@@ -1140,21 +1103,42 @@ export declare function defineWorkflow(
1140
1103
  * deployment's bindings via {@link resourceAliasesToMap} into the
1141
1104
  * `resourceAliases` map `deployDefinitions` expands against.
1142
1105
  *
1143
- * Validates shape only — NOT the reader-floor acknowledgement. That is a
1144
- * selected-deployment gate (`deployDefinitions`, the CLI's
1145
- * `deploymentToTarget` / `buildBatches` / `resolveContext`, and blueprint
1146
- * provision each assert the deployment they target), so a command that never
1147
- * selects a deployment loads a config with a stale or missing floor on an
1148
- * untargeted entry without failing. Authors must still acknowledge the floor
1149
- * at compile time each {@link WorkflowDeploymentInput} requires it; the
1150
- * returned {@link WorkflowConfig} is the looser parsed shape.
1106
+ * Validates shape only; reader-floor acknowledgement belongs to paths that
1107
+ * submit definitions (`deployDefinitions`, the CLI deploy and definition-diff
1108
+ * commands, and blueprint provision). Other commands may load a selected
1109
+ * deployment with a missing floor.
1110
+ *
1111
+ * Each `WorkflowDeploymentInput` carries an acknowledgement; definition-submission
1112
+ * paths compare it with the submitted definitions. The returned {@link WorkflowConfig}
1113
+ * is the looser parsed shape.
1151
1114
  */
1152
1115
  export declare function defineWorkflowConfig(
1153
1116
  config: WorkflowConfigInput,
1154
1117
  ): WorkflowConfig;
1155
1118
 
1119
+ /**
1120
+ * Declared editability of a field — the generic edit seam's gate. Default
1121
+ * (absent) is NOT editable: a field is op-only engine working memory unless the
1122
+ * modeler opens it. The stored form is `true` (editable by anyone within the
1123
+ * field's scope window) or an EDIT CONDITION — rendered-scope GROQ (`$actor`,
1124
+ * `$can`, `$attributes`, `$fields`, `$assigned`), checked like an action filter
1125
+ * to decide who-may-edit. ADVISORY like every engine gate — it disables the
1126
+ * inline field and explains; a {@link Guard} declares the intended write-lock.
1127
+ */
1156
1128
  declare type Editable = v.InferOutput<typeof StoredEditableSchema>;
1157
1129
 
1130
+ /**
1131
+ * A registered effect: `name` is its only identity (unique per definition,
1132
+ * read downstream as `$effects.<name>`) — the host app registers a handler
1133
+ * against it 1:1, and the stored definition never references code.
1134
+ * `bindings` are GROQ reads over the rendered scope, resolved to concrete
1135
+ * JSON at queue time; `input` is static config passed through verbatim.
1136
+ * `outputs` (typed {@link FieldShape}s) is a STRICT allowlist: at completion
1137
+ * an undeclared output key, or a value that doesn't fit its shape, fails the
1138
+ * completion and nothing is stored. Omitting `outputs` is an EMPTY allowlist,
1139
+ * so ANY returned output is rejected and fails the completion — the bound is
1140
+ * universal, not opt-in.
1141
+ */
1158
1142
  declare type Effect = v.InferOutput<typeof EffectSchema>;
1159
1143
 
1160
1144
  /**
@@ -1189,7 +1173,6 @@ declare const EffectSchema: v.StrictObjectSchema<
1189
1173
  v.StringSchema<undefined>,
1190
1174
  undefined
1191
1175
  >;
1192
- /** GROQ reads over the rendered scope, resolved to concrete JSON at queue time. */
1193
1176
  readonly bindings: v.OptionalSchema<
1194
1177
  v.RecordSchema<
1195
1178
  v.StringSchema<undefined>,
@@ -1203,28 +1186,10 @@ declare const EffectSchema: v.StrictObjectSchema<
1203
1186
  >,
1204
1187
  undefined
1205
1188
  >;
1206
- /** Static config, passed through to the handler verbatim. */
1207
1189
  readonly input: v.OptionalSchema<
1208
1190
  v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>,
1209
1191
  undefined
1210
1192
  >;
1211
- /**
1212
- * The outputs this effect is allowed to produce, as typed {@link FieldShape}s
1213
- * (each `name` is an output key, read downstream as `$effects['<name>'].<key>`;
1214
- * an `array` output is an array of objects shaped by `of`).
1215
- *
1216
- * A STRICT allowlist: at completion the handler's returned `outputs` are
1217
- * validated against these shapes and an undeclared key — or a value that
1218
- * doesn't fit its shape — fails the completion (nothing is stored). Omitting
1219
- * `outputs` is an EMPTY allowlist: the effect produces nothing, so any returned
1220
- * output is rejected — the bound is universal, not opt-in.
1221
- * Why strict: outputs land on the instance document's `effectHistory`, so
1222
- * the allowlist keeps it bounded — a handler can't accidentally spread a
1223
- * whole API response
1224
- * into the instance — and the declared shapes let tooling (e.g. the simulator's
1225
- * drain UI) suggest an effect's exact output keys. Declaring outputs also
1226
- * powers the advisory deploy-time producer/consumer lint.
1227
- */
1228
1193
  readonly outputs: v.OptionalSchema<
1229
1194
  v.ArraySchema<v.GenericSchema<FieldShape>, undefined>,
1230
1195
  undefined
@@ -1237,7 +1202,10 @@ declare const EffectSchema: v.StrictObjectSchema<
1237
1202
  * The kinds a VALUE can take — scalars aligned to Sanity's names, the
1238
1203
  * reference kinds, the actor/assignee identities, and the two compositional
1239
1204
  * kinds (`object` with named `fields`, `array` of objects shaped by `of`).
1240
- * This is also the set a nested {@link FieldShape} sub-field may use.
1205
+ * This is also the set a nested {@link FieldShape} sub-field may use. Kinds
1206
+ * are bare (unique within their union); namespacing lives only on
1207
+ * engine-owned lake document `_type`s ({@link WORKFLOW_DEFINITION_TYPE}, the
1208
+ * instance type).
1241
1209
  *
1242
1210
  * Exported (module-level, not package API) for the model-surface gate's
1243
1211
  * enum-value coverage test.
@@ -1276,6 +1244,7 @@ declare type FieldBase<TEditable, TGroup> = {
1276
1244
  editable?: TEditable | undefined;
1277
1245
  };
1278
1246
 
1247
+ /** One declared field entry as authored and stored: name, value kind, and its scope's sourcing and editability. */
1279
1248
  declare type FieldEntry = FieldEntryFields<Editable, string[]>;
1280
1249
 
1281
1250
  /** Type-mirror of {@link fieldEntryFields}: a raw field entry of the given
@@ -1288,6 +1257,8 @@ declare type FieldEntryFields<TEditable, TGroup> = FieldBase<
1288
1257
  options?: ChoiceOptions | undefined;
1289
1258
  validation?: ScalarValidation | undefined;
1290
1259
  types?: string[] | undefined;
1260
+ /** Non-empty assignment eligibility constraint. User roles apply aliases; collective roles match literally. */
1261
+ roles?: string[] | undefined;
1291
1262
  fields?: FieldShape[] | undefined;
1292
1263
  of?: FieldShape[] | undefined;
1293
1264
  };
@@ -1299,6 +1270,14 @@ declare type FieldReadExpr = {
1299
1270
  path?: string | undefined;
1300
1271
  };
1301
1272
 
1273
+ /**
1274
+ * A sub-field shape used inside an `object`'s `fields` or an `array`'s `of` —
1275
+ * lighter than {@link FieldEntry}: no `initialValue`/`editable`/`required`,
1276
+ * since a sub-field's value comes from the parent. An `object` kind requires
1277
+ * non-empty `fields` and no `of`; an `array` kind requires non-empty `of` and
1278
+ * no `fields`; every other kind requires neither — enforced at parse, not
1279
+ * visible in this type.
1280
+ */
1302
1281
  declare interface FieldShape {
1303
1282
  type: FieldValueKind;
1304
1283
  name: string;
@@ -1306,10 +1285,19 @@ declare interface FieldShape {
1306
1285
  description?: string | undefined;
1307
1286
  options?: ChoiceOptions | undefined;
1308
1287
  validation?: ScalarValidation | undefined;
1288
+ /** Non-empty assignment eligibility constraint. User roles apply aliases; collective roles match literally. */
1289
+ roles?: string[] | undefined;
1309
1290
  fields?: FieldShape[] | undefined;
1310
1291
  of?: FieldShape[] | undefined;
1311
1292
  }
1312
1293
 
1294
+ /**
1295
+ * How a field seeds its `initialValue`, once at materialisation (advisory
1296
+ * after — the field stays freely editable). Absent means working memory: the
1297
+ * field starts empty and an op fills it later, spelled by omission rather
1298
+ * than an arm. Distinct from {@link ValueExpr}, an op's write payload; they
1299
+ * overlap only on the literal and field-read arms.
1300
+ */
1313
1301
  declare type FieldSource = FieldSourceInternal;
1314
1302
 
1315
1303
  declare type FieldSourceInternal =
@@ -1352,12 +1340,22 @@ export declare function groq(
1352
1340
  ...values: unknown[]
1353
1341
  ): string;
1354
1342
 
1343
+ /** A named readiness condition. Activities accept only `'groq'`; workflow
1344
+ * `start.requirements` also accepts `'singleSubject'` — see {@link StartRequirement}. */
1355
1345
  declare type GroqRequirement = RequirementBase & {
1356
1346
  type: "groq";
1357
1347
  query: string;
1358
1348
  };
1359
1349
 
1360
- /** Type-mirror of {@link GroupSchema} — one declared group. */
1350
+ /**
1351
+ * A declared "what belongs together" tag: the workflow root, a stage, or an
1352
+ * activity declares named groups, and field entries, activities, and actions
1353
+ * opt in via `group`. Purely advisory — the engine stores and validates names
1354
+ * (unique per level, every reference resolves) and never acts on them; a
1355
+ * consumer decides what a group means for its medium. The same name declared
1356
+ * at several levels is intentional nesting, addressed per level; the engine
1357
+ * never merges them.
1358
+ */
1361
1359
  declare type Group = {
1362
1360
  name: string;
1363
1361
  title?: string | undefined;
@@ -1365,6 +1363,14 @@ declare type Group = {
1365
1363
  kind?: GroupKind | undefined;
1366
1364
  };
1367
1365
 
1366
+ /**
1367
+ * Advisory classification of a declared {@link Group} by its informational
1368
+ * ROLE, never a rendering treatment: `'core'` marks content central to
1369
+ * understanding the workflow (condensed views include these first);
1370
+ * `'details'` marks depth on demand. Unset = a plain group. Consumers
1371
+ * reading a definition as data MUST treat an unknown kind as unset — growing
1372
+ * this list is an engine version bump, like every stored enum.
1373
+ */
1368
1374
  declare const GROUP_KINDS: readonly ["core", "details"];
1369
1375
 
1370
1376
  declare type GroupKind = (typeof GROUP_KINDS)[number];
@@ -1381,6 +1387,27 @@ declare type GroupKind = (typeof GROUP_KINDS)[number];
1381
1387
  */
1382
1388
  declare type GroupMembership = string | string[];
1383
1389
 
1390
+ /**
1391
+ * A lake mutation guard. A FOREIGN CONTRACT mirrored 1:1: `match`,
1392
+ * `predicate`, and `metadata` are the content lake's persisted guard-document
1393
+ * API, not engine-invented surface — the stored form keeps the lake's
1394
+ * vocabulary verbatim. The engine adds exactly two things: `name` (a
1395
+ * lake-id-segment, `^[a-z0-9][a-z0-9-]*$`, unique per definition — the lake
1396
+ * `_id` derives from `(instanceId, name)` at stage entry) and the deploy-time
1397
+ * read VALUES on `match.idRefs` / `metadata` (a typed {@link GuardRead} when
1398
+ * authoring, resolved to bare values at deploy). `match` selects mutations by
1399
+ * `types` (empty matches any), `idRefs` (field reads resolved to bare ids),
1400
+ * `idPatterns` (bare glob ids), and `actions` (at least one). `predicate` is
1401
+ * lake GROQ in a distinct delta-mode eval context (`before()`/`after()`,
1402
+ * `mutation`, `guard`, `identity()`, bare ids/fields only): strictly `true`
1403
+ * ALLOWS the mutation; anything else — false, null, an evaluation error, or
1404
+ * an omitted/empty predicate — DENIES. `metadata` is the only bridge from
1405
+ * that eval context (which cannot see `$fields`) to workflow fields, read as
1406
+ * `guard.metadata.*` and re-synced by the post-field-op guard refresh. The
1407
+ * lake does not enforce the guard document type yet: a deployed guard denies
1408
+ * optimistically engine-side, and the lake ACL is the only hard gate until
1409
+ * guard enforcement ships.
1410
+ */
1384
1411
  declare type Guard = v.InferOutput<typeof GuardSchema>;
1385
1412
 
1386
1413
  /**
@@ -1395,14 +1422,8 @@ export declare const GUARD_PREDICATE_VARS: readonly {
1395
1422
  description: string;
1396
1423
  }[];
1397
1424
 
1398
- /** Stored guards carry the printed string reads (the deploy resolver's input). */
1399
1425
  declare const GuardSchema: v.StrictObjectSchema<
1400
1426
  {
1401
- /**
1402
- * Lake-id-segment grammar (`^[a-z0-9][a-z0-9-]*$`, deploy-enforced): the
1403
- * guard's lake `_id` derives from `(instanceId, name)` at stage entry.
1404
- * Unique per definition.
1405
- */
1406
1427
  name: v.SchemaWithPipe<
1407
1428
  readonly [
1408
1429
  v.StringSchema<undefined>,
@@ -1413,7 +1434,6 @@ declare const GuardSchema: v.StrictObjectSchema<
1413
1434
  description: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
1414
1435
  match: v.StrictObjectSchema<
1415
1436
  {
1416
- /** Subject `_type`(s); empty matches any type. */
1417
1437
  types: v.OptionalSchema<
1418
1438
  v.ArraySchema<
1419
1439
  v.SchemaWithPipe<
@@ -1426,7 +1446,6 @@ declare const GuardSchema: v.StrictObjectSchema<
1426
1446
  >,
1427
1447
  undefined
1428
1448
  >;
1429
- /** Target docs as field reads (or the instance itself), resolved at deploy to bare ids + the resource. */
1430
1449
  idRefs: v.OptionalSchema<
1431
1450
  v.ArraySchema<
1432
1451
  v.SchemaWithPipe<
@@ -1439,7 +1458,6 @@ declare const GuardSchema: v.StrictObjectSchema<
1439
1458
  >,
1440
1459
  undefined
1441
1460
  >;
1442
- /** Glob id patterns (bare, resource-local). */
1443
1461
  idPatterns: v.OptionalSchema<
1444
1462
  v.ArraySchema<
1445
1463
  v.SchemaWithPipe<
@@ -1471,22 +1489,7 @@ declare const GuardSchema: v.StrictObjectSchema<
1471
1489
  },
1472
1490
  undefined
1473
1491
  >;
1474
- /**
1475
- * Lake GROQ predicate — a distinct eval context: delta-mode GROQ
1476
- * reading the `before()`/`after()` natives, `mutation`, `guard`, and
1477
- * `identity()`. Bare ids/fields only. Polarity: a result of strictly
1478
- * `true` ALLOWS the matched mutation; anything else (false, null, an
1479
- * evaluation error) DENIES. Omitted or empty means UNCONDITIONAL DENY.
1480
- */
1481
1492
  predicate: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
1482
- /**
1483
- * Projected workflow fields the predicate reads as `guard.metadata.*` —
1484
- * the only bridge from the lake eval context (which cannot see `$fields`)
1485
- * to workflow fields. Each value is a deploy-time read — a typed
1486
- * {@link GuardRead} when authoring, the printed string spelling once
1487
- * stored — resolved into a bare value at deploy and re-synced by the
1488
- * post-field-op guard refresh.
1489
- */
1490
1493
  metadata: v.OptionalSchema<
1491
1494
  v.RecordSchema<
1492
1495
  v.SchemaWithPipe<
@@ -1514,17 +1517,22 @@ declare type LiteralExpr = {
1514
1517
  value: unknown;
1515
1518
  };
1516
1519
 
1517
- declare type ManualTarget = v.InferOutput<typeof StoredManualTargetSchema>;
1518
-
1519
1520
  /**
1520
- * `notes`an append-only audit/comment log. Sugar over `array of object
1521
- * { body, actor, at }` (the `actor`/`at` sub-fields match the `audit` op's
1522
- * stamp names, so it pairs with it). Never a stored kind.
1521
+ * Off-system deep-link target render-only metadata whose presence marks an
1522
+ * activity as off-system (BPMN Manual Task). Either a static URL, or a field
1523
+ * reference whose resolved document the consumer opens; deploy checks the
1524
+ * `field` variant points at a doc-valued entry.
1523
1525
  */
1526
+ declare type ManualTarget = v.InferOutput<typeof StoredManualTargetSchema>;
1527
+
1528
+ /** An append-only audit/comment log: sugar over `array of object {body, actor, at}` — the `actor`/`at`
1529
+ * names match the `audit` op's stamp fields, so it pairs with it. Never a stored kind. */
1524
1530
  declare type NotesField = FieldBase<AuthoringEditable, GroupMembership> & {
1525
1531
  type: "notes";
1526
1532
  };
1527
1533
 
1534
+ /** A `field.updateWhere` / `field.removeWhere` op's `where` selects rows to
1535
+ * mutate with rendered-scope GROQ (`$row`, `$params` bound) — row selection, not a gate; an unevaluable row never matches. */
1528
1536
  declare type Op = v.InferOutput<typeof StoredOpSchema>;
1529
1537
 
1530
1538
  declare type RequirementBase = {
@@ -1541,35 +1549,15 @@ declare type RequirementBase = {
1541
1549
  */
1542
1550
  export declare const RESERVED_CONDITION_VARS: readonly string[];
1543
1551
 
1544
- declare type RoleAliases = v.InferOutput<typeof RoleAliasesSchema>;
1545
-
1546
1552
  /**
1547
- * Role aliasing the "can be fulfilled by" map, an authoring convenience.
1548
- * A `roles` gate (or an `assignees` entry) names the role the author writes;
1549
- * but the SAME capability is often carried by different role names depending
1550
- * on how a given project deploys its Content Lake roles, and several roles may
1551
- * legitimately do the job. Rather than enumerate every equivalent role inline
1552
- * in each gate — or fork the definition per deployment — declare once here
1553
- * which other roles also fulfill it.
1554
- *
1555
- * Each key is a role a gate/assignee names; its value lists the roles that
1556
- * also satisfy it. The reserved key `"*"` lists roles that fulfill ANY gate
1557
- * (e.g. `"*": ["administrator"]` — whatever this deployment's broad role is).
1558
- * `"*"` is the spelling authors write; it is rewritten to a lake-safe stored
1559
- * key before the definition is persisted, since the Content Lake rejects `"*"`
1560
- * as a document attribute name (see {@link normalizeRoleAliases}).
1561
- *
1562
- * Applied as an in-place expansion of the REQUIRED side, never the actor's
1563
- * roles: the `roles` gate bakes the expanded membership into its desugared
1564
- * GROQ at define time; `$assigned` expands the assignee's role at match time
1565
- * (see {@link expandRequiredRoles}). Carried into the stored definition for
1566
- * that runtime half.
1567
- *
1568
- * Advisory, like every engine gate — an alias only predicts what the
1569
- * deployment's Content Lake ACLs already allow, it never grants access. An
1570
- * alias the lake won't honor makes the gate predict "allowed" for a write the
1571
- * lake then rejects, so keep it true to what's actually deployed.
1553
+ * Roles that may fulfil each authored role. Aliases widen action gates,
1554
+ * `$assigned`, and assignment-field user eligibility by expanding the required
1555
+ * side; they never alter an actor's roles. Collective role assignees remain
1556
+ * literal ownership values and are not widened by this map. The authored `"*"`
1557
+ * key lists universal fulfillers and is normalized before persistence.
1572
1558
  */
1559
+ declare type RoleAliases = v.InferOutput<typeof RoleAliasesSchema>;
1560
+
1573
1561
  declare const RoleAliasesSchema: v.RecordSchema<
1574
1562
  v.SchemaWithPipe<
1575
1563
  readonly [
@@ -1619,6 +1607,18 @@ declare type SingleSubjectRequirement = RequirementBase & {
1619
1607
  type: "singleSubject";
1620
1608
  };
1621
1609
 
1610
+ /**
1611
+ * A pure container — name, fields, guards, activities, transitions, no
1612
+ * behaviour of its own. Activities own enter, transitions own exit and
1613
+ * arrival; a stage with no transitions IS terminal (structural, nothing to
1614
+ * declare or mis-declare). `guards` are lake mutation guards active while
1615
+ * the stage holds, each compiling to a persisted guard document deployed on
1616
+ * stage entry and retracted on exit. `editable` is a tighten-only override
1617
+ * for the time the stage holds, keyed by an in-scope field name: the field's
1618
+ * own `editable` is the ceiling, ANDed with the stage value at runtime, so an
1619
+ * override can only NARROW — never open a field the baseline left closed. An
1620
+ * unlisted field inherits its baseline.
1621
+ */
1622
1622
  declare type Stage = StageFields<
1623
1623
  FieldEntry,
1624
1624
  Activity,
@@ -1643,13 +1643,23 @@ declare type StageFields<TField, TActivity, TTransition, TGuard, TEditable> = {
1643
1643
 
1644
1644
  declare const START_KINDS: readonly ["interactive", "autonomous"];
1645
1645
 
1646
+ /**
1647
+ * How standalone runs of this workflow begin. `filter` is a READ-SIDE
1648
+ * visibility predicate — "should a start surface offer this workflow for
1649
+ * this document?" — evaluated by `definitionsForDocument`/applicability in
1650
+ * the browse-time-pure start-filter context (`$tag`/`$definition`/`$now`
1651
+ * bound; `$fields` cannot exist before inputs do, so a `$fields` read here
1652
+ * is deploy-rejected). It is NOT a `startInstance` gate; the verb never
1653
+ * reads it. `requirements` are named readiness checks evaluated in author
1654
+ * order in the start-time context (GROQ nodes add `$fields`; `singleSubject`
1655
+ * is the one-in-flight-run-per-subject rule) — every node must pass before
1656
+ * `startInstance` commits. Both are advisory like every engine-side check;
1657
+ * the Content Lake remains the only enforcement point.
1658
+ */
1646
1659
  declare type StartBlock = StartFields & {
1647
1660
  kind: StartKind;
1648
1661
  };
1649
1662
 
1650
- /** Type-mirror of {@link startFields}: how standalone runs of this workflow
1651
- * begin. Stored requires `kind` (desugar fills the `'interactive'` default);
1652
- * authoring may omit it — so each variant declares it. */
1653
1663
  declare type StartFields = {
1654
1664
  filter?: string | undefined;
1655
1665
  requirements?: StartRequirement[] | undefined;
@@ -1666,17 +1676,9 @@ declare type StartFields = {
1666
1676
  */
1667
1677
  declare type StartKind = (typeof START_KINDS)[number];
1668
1678
 
1679
+ /** Every named readiness requirement accepted by workflow `start.requirements`. */
1669
1680
  declare type StartRequirement = GroqRequirement | SingleSubjectRequirement;
1670
1681
 
1671
- /**
1672
- * Declared editability of a field — the generic edit seam's gate. Default
1673
- * (absent) is NOT editable: a field is op-only engine working memory unless the
1674
- * modeler opens it. The stored form is `true` (editable by anyone within the
1675
- * field's scope window) or an EDIT CONDITION — rendered-scope GROQ (`$actor`,
1676
- * `$can`, `$attributes`, `$fields`, `$assigned`), checked like an action filter
1677
- * to decide who-may-edit. ADVISORY like every engine gate — it disables the
1678
- * inline field and explains; a {@link Guard} declares the intended write-lock.
1679
- */
1680
1682
  declare const StoredEditableSchema: v.UnionSchema<
1681
1683
  [
1682
1684
  v.LiteralSchema<true, undefined>,
@@ -1946,18 +1948,23 @@ declare const StoredOpSchema: v.VariantSchema<
1946
1948
  undefined
1947
1949
  >;
1948
1950
 
1951
+ /**
1952
+ * Fan-out declared as an action's `spawn`, read back as `$subworkflows`.
1953
+ * `forEach` is GROQ producing one row per subworkflow (bound as `$row`); each
1954
+ * row needs an identity the engine can adopt on re-entry (`_key` ?? `_id` ??
1955
+ * GDR `id`, or the value itself for a scalar row) or the spawn fails.
1956
+ * `definition` resolves by stable `name`, ordered `version desc` unless
1957
+ * pinned. `with` seeds each child's initial fields; `context` delivers extra
1958
+ * parent-scope values into the child's `$context`. `onExit` governs only
1959
+ * still-live children when the cohort's scope stops applying: `'detach'`
1960
+ * (default) lets them run to completion, `'abort'` kills them recursively —
1961
+ * always an authored choice, never automatic. Whether the PARENT may move at
1962
+ * all is a separate gate over `$subworkflows`.
1963
+ */
1949
1964
  declare type Subworkflows = v.InferOutput<typeof SubworkflowsSchema>;
1950
1965
 
1951
1966
  declare const SubworkflowsSchema: v.StrictObjectSchema<
1952
1967
  {
1953
- /**
1954
- * GROQ producing one row per subworkflow; each row binds as `$row`. Every
1955
- * row must carry an identity the engine can adopt against on re-entry:
1956
- * `_key` ?? `_id` ?? GDR `id` for object rows (a GDR value — `{id, type}`
1957
- * with a GDR-URI `id`, the rows a `doc.refs` field stores — keys on its
1958
- * `id`; mint a `_key` in the projection for synthetic rows), the value
1959
- * itself for scalar rows. A row without an identity fails the spawn.
1960
- */
1961
1968
  readonly forEach: v.SchemaWithPipe<
1962
1969
  readonly [
1963
1970
  v.StringSchema<undefined>,
@@ -1991,7 +1998,6 @@ declare const SubworkflowsSchema: v.StrictObjectSchema<
1991
1998
  },
1992
1999
  undefined
1993
2000
  >;
1994
- /** Initial fields for each subworkflow — entry name → GROQ over `$row` + the parent scope. */
1995
2001
  readonly with: v.OptionalSchema<
1996
2002
  v.RecordSchema<
1997
2003
  v.SchemaWithPipe<
@@ -2010,11 +2016,6 @@ declare const SubworkflowsSchema: v.StrictObjectSchema<
2010
2016
  >,
2011
2017
  undefined
2012
2018
  >;
2013
- /**
2014
- * Extra values evaluated in the parent's rendered scope at spawn time and
2015
- * delivered into each subworkflow's `$context` bag — the parent→child
2016
- * handoff.
2017
- */
2018
2019
  readonly context: v.OptionalSchema<
2019
2020
  v.RecordSchema<
2020
2021
  v.SchemaWithPipe<
@@ -2033,16 +2034,6 @@ declare const SubworkflowsSchema: v.StrictObjectSchema<
2033
2034
  >,
2034
2035
  undefined
2035
2036
  >;
2036
- /**
2037
- * What happens to still-live children when their cohort's scope stops
2038
- * applying — the spawning stage exits, or a re-fire's `forEach` no longer
2039
- * discovers their row. `'detach'` (the default) lets them run to
2040
- * completion outside the gate; `'abort'` kills them (recursively). The
2041
- * engine never destroys in-flight work implicitly — `'abort'` is always
2042
- * an authored choice. Note this governs only the CHILDREN's fate; whether
2043
- * the parent may move at all is what gates (conditions over
2044
- * `$subworkflows`) decide.
2045
- */
2046
2037
  readonly onExit: v.OptionalSchema<
2047
2038
  v.PicklistSchema<readonly ["detach", "abort"], string>,
2048
2039
  undefined
@@ -2051,6 +2042,14 @@ declare const SubworkflowsSchema: v.StrictObjectSchema<
2051
2042
  undefined
2052
2043
  >;
2053
2044
 
2045
+ /**
2046
+ * The statuses an activity can be resolved INTO — what `status.set` accepts.
2047
+ * A health axis, not a decision axis: a routine decision (decline, send back,
2048
+ * hold) resolves `done` and routes via a field write; `failed` means the work
2049
+ * genuinely could not complete. Only `done`/`skipped` satisfy
2050
+ * `$allActivitiesDone` — a `failed` activity blocks it permanently, surfacing
2051
+ * via `$anyActivityFailed`.
2052
+ */
2054
2053
  declare const TERMINAL_ACTIVITY_STATUSES: readonly [
2055
2054
  "done",
2056
2055
  "skipped",
@@ -2060,19 +2059,22 @@ declare const TERMINAL_ACTIVITY_STATUSES: readonly [
2060
2059
  declare type TerminalActivityStatus =
2061
2060
  (typeof TERMINAL_ACTIVITY_STATUSES)[number];
2062
2061
 
2063
- /**
2064
- * `todoList` ad-hoc, status-tracked work items. Sugar over `array of object
2065
- * { label, status, assignee?, dueDate? }`; a plain checklist is this used with
2066
- * `{label, status}` only (open ↔ done). Never a stored kind.
2067
- *
2068
- * The `dueDate` column is a `date` NAMED `dueDate`, not the {@link
2069
- * FieldValueMap.dueDate} kind — that kind reserves one deadline slot per level,
2070
- * and a repeating row has nothing to reserve.
2071
- */
2062
+ /** Ad-hoc, status-tracked work items: sugar over `array of object {label, status, assignee?, dueDate?}`; a plain checklist is that with `{label, status}` alone.
2063
+ * Its `dueDate` is a `date` column named `dueDate`, not the elevated `dueDate` kind, which reserves one deadline slot per level. Never a stored kind. */
2072
2064
  declare type TodoListField = FieldBase<AuthoringEditable, GroupMembership> & {
2073
2065
  type: "todoList";
2074
2066
  };
2075
2067
 
2068
+ /**
2069
+ * A pure edge — `{name, when, to}` plus presentation, no ops or effects
2070
+ * (structure never does; only actions do). Every transition is evaluated on
2071
+ * every commit and cascade; the first truthy `when` in declaration order
2072
+ * fires. No action coupling: a routing difference is written into fields by
2073
+ * an action and read by the trigger — arrival work is a `when: 'true'`
2074
+ * action in the destination stage, and exit work is an action in the source
2075
+ * stage whose `when` repeats this transition's condition (the hop rule
2076
+ * guarantees it commits before the move).
2077
+ */
2076
2078
  declare type Transition = TransitionFields & {
2077
2079
  when: string;
2078
2080
  };
@@ -2112,6 +2114,16 @@ declare type ValueExprInternal =
2112
2114
 
2113
2115
  declare const WORKFLOW_LIFECYCLES: readonly ["standalone", "child"];
2114
2116
 
2117
+ /**
2118
+ * `deployments` names must be unique (the selector deployment-targeted
2119
+ * commands resolve by), and each `(workflowResource, tag)` pair must be
2120
+ * unique — that pair is the storage partition, so two deployments sharing
2121
+ * both would fight over definition versions. `telemetry`, when set, replaces
2122
+ * the CLI's built-in Sanity-intake shell entirely: every event flows to this
2123
+ * logger unconditionally (CI and `DO_NOT_TRACK` included), and consent,
2124
+ * environment suppression, and transport become this implementation's
2125
+ * business.
2126
+ */
2115
2127
  declare type WorkflowConfig = v.InferOutput<typeof WorkflowConfigSchema>;
2116
2128
 
2117
2129
  /**
@@ -2735,14 +2747,6 @@ declare const WorkflowConfigSchema: v.ObjectSchema<
2735
2747
  >,
2736
2748
  ]
2737
2749
  >;
2738
- /**
2739
- * Custom telemetry destination for the CLI. When set, the CLI's built-in
2740
- * Sanity-intake shell is not constructed and none of its policy applies:
2741
- * every event — the command trace and the engine vocabulary — flows to
2742
- * this logger unconditionally (CI and `DO_NOT_TRACK` environments
2743
- * included). Consent, environment suppression, transport, and destination
2744
- * are wholly this implementation's business.
2745
- */
2746
2750
  readonly telemetry: v.OptionalSchema<
2747
2751
  v.CustomSchema<
2748
2752
  WorkflowTelemetryLogger,
@@ -2754,6 +2758,21 @@ declare const WorkflowConfigSchema: v.ObjectSchema<
2754
2758
  undefined
2755
2759
  >;
2756
2760
 
2761
+ /**
2762
+ * `name` is a lake-id-segment (`^[a-z0-9][a-z0-9-]*$`) that interpolates into
2763
+ * every deployed document id (`<tag>.<name>.v<version>`) — stable identity
2764
+ * that instances pin to and subworkflows resolve by. `lifecycle: 'child'`
2765
+ * marks a spawn-only definition, instantiated by a parent via an action's
2766
+ * `spawn`, never started cold from a picker (omitted ⇒ `'standalone'`,
2767
+ * startable); advisory only — consumers filter start pickers on it (see
2768
+ * {@link isStartableDefinition}), the engine does not itself refuse a
2769
+ * `startInstance` on a `'child'` definition. `start` is meaningless
2770
+ * (deploy-rejected) on a spawn-only definition; omitted, it means
2771
+ * interactive semantics with no predicates. `predicates` are nullary named
2772
+ * conditions — each `name: groq` entry is pre-evaluated and bound as the
2773
+ * boolean `$name` var; redefining a built-in var is a deploy error, never a
2774
+ * silent shadow.
2775
+ */
2757
2776
  declare type WorkflowDefinition = v.InferOutput<
2758
2777
  typeof WorkflowDefinitionSchema
2759
2778
  >;
@@ -2763,47 +2782,41 @@ declare type WorkflowDefinition = v.InferOutput<
2763
2782
  * every reference scope resolved. Cross-field invariants (unique names,
2764
2783
  * transition targets, effect-name uniqueness, predicate shadowing) are
2765
2784
  * checked by `checkWorkflowInvariants` after desugar — see `defineWorkflow`.
2785
+ * Carries NO `version`: a definition's version and content fingerprint are
2786
+ * stamped onto the deployed document at deploy time, derived from the
2787
+ * content itself, so redeploying identical content is a no-op and any
2788
+ * change mints the next version.
2766
2789
  *
2767
- * Carries NO `version` the author never writes one. A definition's version
2768
- * (and its content fingerprint) are stamped onto the deployed *document* at
2769
- * deploy time, derived from the content itself; see `DeployedDefinition` and
2770
- * `planDefinitionDeploy` in `api/deploy.ts`. The author's content is the sole
2771
- * source of identity: redeploying identical content is a no-op, any change
2772
- * mints the next version.
2790
+ * Exported (module-level, not package API) for the model-surface gate's
2791
+ * coverage test and for `parseStoredDefinition` the boundary parse for a
2792
+ * definition that did not come out of `defineWorkflow` in-process; trusted
2793
+ * in-process desugar output is never re-parsed.
2773
2794
  */
2774
2795
  declare const WorkflowDefinitionSchema: v.GenericSchema<
2775
2796
  WorkflowFields<FieldEntry, Stage, StartBlock>
2776
2797
  >;
2777
2798
 
2778
2799
  /** One deployment as loaded from a config: the floor is optional/unverified so
2779
- * a command that never selects a deployment can hold a stale or missing
2780
- * acknowledgement. Deployment-scoped paths assert before they act; authors
2781
- * write {@link WorkflowDeploymentInput}. */
2800
+ * commands that do not submit definitions can hold a missing acknowledgement.
2801
+ * Definition-submission paths compare it with their selected definitions; authors write
2802
+ * {@link WorkflowDeploymentInput}. */
2782
2803
  declare type WorkflowDeployment = WorkflowConfig["deployments"][number];
2783
2804
 
2784
2805
  /**
2785
- * What an author writes for one deployment: the current reader floor as the
2786
- * reviewed literal. Compile-time only omitting it or setting a wrong value
2787
- * is a type error in the editor. Runtime parse still tolerates a stale or
2788
- * missing floor on {@link WorkflowDeployment} so commands that never select a
2789
- * deployment still run; deployment-scoped paths assert the selected
2790
- * deployment (instance-id commands do not).
2806
+ * What an author writes for one deployment: the highest reader model verified
2807
+ * across runtimes sharing its workflow resource. Runtime validation compares
2808
+ * it with the submitted definitions, so a dependency upgrade alone does not
2809
+ * require changing the literal.
2791
2810
  */
2792
2811
  declare type WorkflowDeploymentInput = Omit<
2793
2812
  WorkflowDeployment,
2794
2813
  "expectedMinReaderModel"
2795
2814
  > & {
2796
- expectedMinReaderModel: typeof DATA_MODEL_MIN_READER;
2815
+ expectedMinReaderModel: number;
2797
2816
  };
2798
2817
 
2799
2818
  /** Type-mirror of {@link workflowFields}, parameterised over field/stage/start. */
2800
2819
  declare type WorkflowFields<TField, TStage, TStart> = {
2801
- /**
2802
- * Lake-id-segment grammar (`^[a-z0-9][a-z0-9-]*$`, deploy-enforced): the
2803
- * name interpolates into every deployed document id
2804
- * (`<tag>.<name>.v<version>`). Stable identity — instances pin to it,
2805
- * subworkflows resolve by it.
2806
- */
2807
2820
  name: string;
2808
2821
  semantics?: Semantic[] | undefined;
2809
2822
  title: string;