@sanity/workflow-engine 0.27.0 → 0.29.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.
@@ -6,6 +6,41 @@ import { parse } from "groq-js";
6
6
 
7
7
  import { isDraftId, isVersionId, getPublishedId } from "@sanity/id-utils";
8
8
 
9
+ function isCascadeFired(action) {
10
+ return action.when !== void 0;
11
+ }
12
+
13
+ function deriveActivityKind(activity) {
14
+ if (activity.target !== void 0) return "manual";
15
+ const actions = activity.actions ?? [];
16
+ return actions.some(a => !isCascadeFired(a)) ? "user" : actions.some(a => (a.effects ?? []).length > 0 || a.spawn !== void 0) ? "service" : actions.length > 0 ? "receive" : "script";
17
+ }
18
+
19
+ function deriveExecutorClassification(activity) {
20
+ if (activity.target !== void 0) return "off-system";
21
+ const actions = activity.actions ?? [], cascadeFired = actions.filter(isCascadeFired).length;
22
+ return cascadeFired === actions.length ? "autonomous" : cascadeFired === 0 ? "interactive" : "hybrid";
23
+ }
24
+
25
+ function driverKind(actor) {
26
+ return actor.kind === "person" || actor.kind === "agent" ? actor.kind : "service";
27
+ }
28
+
29
+ function errorMessage(err) {
30
+ return (err instanceof Error ? err.message : String(err)).replace(/[^\P{Cc}\n\t]/gu, "");
31
+ }
32
+
33
+ function rethrowWithContext(err, context) {
34
+ throw new Error(`${context}: ${errorMessage(err)}`, {
35
+ cause: err
36
+ });
37
+ }
38
+
39
+ function andConditions(parts) {
40
+ const present = parts.filter(p => p !== void 0);
41
+ if (present.length !== 0) return present.length === 1 ? present[0] : present.map(p => `(${p})`).join(" && ");
42
+ }
43
+
9
44
  class WorkflowError extends Error {
10
45
  kind;
11
46
  constructor(kind, message, options) {
@@ -79,322 +114,6 @@ function effectNotFoundMessage(args) {
79
114
  return args.settled.status === "cancelled" ? `${base} — it was cancelled at ${args.settled.ranAt}${cause}` : `${base} — it already settled "${args.settled.status}" at ${args.settled.ranAt}${cause}`;
80
115
  }
81
116
 
82
- function errorMessage(err) {
83
- return (err instanceof Error ? err.message : String(err)).replace(/[^\P{Cc}\n\t]/gu, "");
84
- }
85
-
86
- function rethrowWithContext(err, context) {
87
- throw new Error(`${context}: ${errorMessage(err)}`, {
88
- cause: err
89
- });
90
- }
91
-
92
- const WORKFLOW_INSTANCE_TYPE = "sanity.workflow.instance";
93
-
94
- function terminalState(instance) {
95
- return instance.abortedAt !== void 0 ? "aborted" : instance.completedAt !== void 0 ? "completed" : "in-flight";
96
- }
97
-
98
- function isUnprimed(instance) {
99
- return instance.stages.length === 0 && terminalState(instance) === "in-flight";
100
- }
101
-
102
- function parseDefinitionSnapshotValue(instance) {
103
- try {
104
- return normalizeLegacyActivityRequirements(JSON.parse(instance.definitionSnapshot));
105
- } catch (err) {
106
- rethrowWithContext(err, `Failed to parse definitionSnapshot on instance "${instance._id}"`);
107
- }
108
- }
109
-
110
- function normalizeLegacyActivityRequirements(value) {
111
- for (const stage of arrayMember(value, "stages")) for (const activity of arrayMember(stage, "activities")) normalizeLegacyRequirementMap(activity);
112
- return value;
113
- }
114
-
115
- function arrayMember(value, key) {
116
- if (typeof value != "object" || value === null) return [];
117
- const member = value[key];
118
- return Array.isArray(member) ? member : [];
119
- }
120
-
121
- function normalizeLegacyRequirementMap(value) {
122
- if (typeof value != "object" || value === null) return;
123
- const activity = value, requirements = activity.requirements;
124
- typeof requirements != "object" || requirements === null || Array.isArray(requirements) || (activity.requirements = Object.entries(requirements).map(([name, query]) => ({
125
- type: "groq",
126
- name: name,
127
- query: query
128
- })));
129
- }
130
-
131
- function parseDefinitionSnapshot(instance) {
132
- return parseDefinitionSnapshotValue(instance);
133
- }
134
-
135
- function parentRef(instance) {
136
- return instance.ancestors.at(-1);
137
- }
138
-
139
- const DATA_MODEL_VERSION = 5, DATA_MODEL_MIN_READER = 4, READER_MODEL_ROLLOUT_URL = "https://www.sanity.io/docs/editorial-workflows/prerelease";
140
-
141
- class ReaderModelAcknowledgementError extends WorkflowError {
142
- code="WORKFLOW_READER_MODEL_ACKNOWLEDGEMENT_MISMATCH";
143
- expectedMinReaderModel;
144
- engineMinReaderModel=DATA_MODEL_MIN_READER;
145
- engineModelVersion=DATA_MODEL_VERSION;
146
- documentationUrl=READER_MODEL_ROLLOUT_URL;
147
- constructor(expectedMinReaderModel, context = "Deployment") {
148
- const expected = expectedMinReaderModel === void 0 ? "missing" : String(expectedMinReaderModel);
149
- super("reader-model-acknowledgement", `${context} expected reader floor ${expected}; the installed engine requires acknowledgement ${DATA_MODEL_MIN_READER}. Do not change the acknowledgement yet: accepting ${DATA_MODEL_MIN_READER} authorizes this engine to write documents that older readers will refuse. Upgrade every Studio, CLI, MCP server, Function, and other runtime that reads engine-owned documents; verify that rollout in every environment sharing the workflow resource; then change the literal in deployment configuration and deploy the writer. Rollout guide: ${READER_MODEL_ROLLOUT_URL}`),
150
- this.name = "ReaderModelAcknowledgementError", this.expectedMinReaderModel = expectedMinReaderModel;
151
- }
152
- }
153
-
154
- function assertReaderModelAcknowledgement(expectedMinReaderModel, context) {
155
- if (typeof expectedMinReaderModel != "number" || !Number.isFinite(expectedMinReaderModel) || !Number.isInteger(expectedMinReaderModel) || expectedMinReaderModel < 0 || expectedMinReaderModel !== DATA_MODEL_MIN_READER) throw new ReaderModelAcknowledgementError(expectedMinReaderModel, context);
156
- }
157
-
158
- const DATA_MODEL_CHANGES = Object.freeze([ Object.freeze({
159
- id: "governed-model-stamps",
160
- introducedInModel: 1,
161
- minReaderModel: 0,
162
- documentTypes: Object.freeze([ "definition", "instance" ]),
163
- compatibility: "additive",
164
- applicability: "unconditional",
165
- summary: "Definition and instance documents carry model provenance and reader-floor stamps."
166
- }), Object.freeze({
167
- id: "subject-field-kind",
168
- introducedInModel: 2,
169
- minReaderModel: 0,
170
- documentTypes: Object.freeze([ "definition", "instance" ]),
171
- compatibility: "additive",
172
- applicability: "detectable",
173
- summary: "A workflow-level subject field identifies the document a workflow is about."
174
- }), Object.freeze({
175
- id: "typed-scalar-choice-lists",
176
- introducedInModel: 2,
177
- minReaderModel: 2,
178
- documentTypes: Object.freeze([ "definition", "instance" ]),
179
- compatibility: "reader-floor",
180
- applicability: "detectable",
181
- summary: "Scalar fields may constrain writes to a persisted typed choice list."
182
- }), Object.freeze({
183
- id: "action-semantics",
184
- introducedInModel: 2,
185
- minReaderModel: 0,
186
- documentTypes: Object.freeze([ "definition" ]),
187
- compatibility: "additive",
188
- applicability: "detectable",
189
- summary: "Ordinary actions may carry a closed bag of advisory workflow semantics."
190
- }), Object.freeze({
191
- id: "inclusive-scalar-bounds",
192
- introducedInModel: 2,
193
- minReaderModel: 2,
194
- documentTypes: Object.freeze([ "definition", "instance" ]),
195
- compatibility: "reader-floor",
196
- applicability: "detectable",
197
- summary: "String, text, and number values may carry persisted inclusive bounds."
198
- }), Object.freeze({
199
- id: "progress-field-kind",
200
- introducedInModel: 3,
201
- minReaderModel: 0,
202
- documentTypes: Object.freeze([ "definition", "instance" ]),
203
- compatibility: "additive",
204
- applicability: "detectable",
205
- summary: "A progress field kind carries application-defined 0–100 completion."
206
- }), Object.freeze({
207
- id: "effect-claim-tokens",
208
- introducedInModel: 3,
209
- minReaderModel: 0,
210
- documentTypes: Object.freeze([ "instance" ]),
211
- compatibility: "additive",
212
- applicability: "detectable",
213
- summary: "Pending-effect claims carry an exact-claim token gating mid-dispatch state reports."
214
- }), Object.freeze({
215
- id: "classified-principal-ids",
216
- introducedInModel: 4,
217
- minReaderModel: 4,
218
- documentTypes: Object.freeze([ "instance" ]),
219
- compatibility: "reader-floor",
220
- applicability: "unconditional",
221
- summary: "Principal ids are namespace-classified: actor and assignee writes carry the account-global user id only, and readers resolve legacy project-scoped ids through the prefix classifier at the instance read funnel."
222
- }), Object.freeze({
223
- id: "readiness-requirements",
224
- introducedInModel: 4,
225
- minReaderModel: 4,
226
- documentTypes: Object.freeze([ "definition" ]),
227
- compatibility: "reader-floor",
228
- applicability: "detectable",
229
- summary: "Start and activity readiness use named polymorphic requirement arrays."
230
- }), Object.freeze({
231
- id: "due-date-field-kinds",
232
- introducedInModel: 5,
233
- minReaderModel: 0,
234
- documentTypes: Object.freeze([ "definition", "instance" ]),
235
- compatibility: "additive",
236
- applicability: "detectable",
237
- summary: "Due-date field kinds (dueDate, dueDatetime) mark a level deadline, elevated aliases of date/datetime carrying the same stored value."
238
- }) ]);
239
-
240
- function recordOf(value) {
241
- return value !== null && typeof value == "object" && !Array.isArray(value) ? value : void 0;
242
- }
243
-
244
- function recordsAt(record, key) {
245
- const value = record[key];
246
- return Array.isArray(value) ? value.map(recordOf).filter(item => item !== void 0) : [];
247
- }
248
-
249
- function nestedFieldEntries(entries) {
250
- return entries.flatMap(entry => [ entry, ...nestedFieldEntries(recordsAt(entry, "fields")), ...nestedFieldEntries(recordsAt(entry, "of")) ]);
251
- }
252
-
253
- function parsedDefinitionSnapshot(root) {
254
- if (typeof root.definitionSnapshot == "string") return recordOf(parseDefinitionSnapshotValue({
255
- _id: typeof root._id == "string" ? root._id : "<unknown instance>",
256
- definitionSnapshot: root.definitionSnapshot
257
- }));
258
- }
259
-
260
- function persistedFieldEntries(document) {
261
- const root = recordOf(document);
262
- if (root === void 0) return [];
263
- const snapshot = parsedDefinitionSnapshot(root), roots = snapshot === void 0 ? [ root ] : [ root, snapshot ], stages = roots.flatMap(candidate => recordsAt(candidate, "stages")), activities = stages.flatMap(stage => recordsAt(stage, "activities")), actions = activities.flatMap(activity => recordsAt(activity, "actions")), effects = actions.flatMap(action => recordsAt(action, "effects"));
264
- return nestedFieldEntries([ ...roots.flatMap(candidate => recordsAt(candidate, "fields")), ...stages.flatMap(stage => recordsAt(stage, "fields")), ...activities.flatMap(activity => recordsAt(activity, "fields")), ...actions.flatMap(action => recordsAt(action, "params")), ...effects.flatMap(effect => recordsAt(effect, "outputs")) ]);
265
- }
266
-
267
- function hasChoiceList(document) {
268
- return persistedFieldEntries(document).some(entry => {
269
- const options = recordOf(entry.options);
270
- return options !== void 0 && Array.isArray(options.list);
271
- });
272
- }
273
-
274
- function hasFieldKind(document, kind) {
275
- return persistedFieldEntries(document).some(entry => entry.type === kind || entry._type === kind);
276
- }
277
-
278
- function hasActionSemantics(document) {
279
- const root = recordOf(document);
280
- return root === void 0 ? !1 : recordsAt(root, "stages").flatMap(stage => recordsAt(stage, "activities")).flatMap(activity => recordsAt(activity, "actions")).some(action => Array.isArray(action.semantics));
281
- }
282
-
283
- function hasScalarValidation(document) {
284
- return persistedFieldEntries(document).some(entry => {
285
- const validation = recordOf(entry.validation);
286
- return typeof validation?.min == "number" || typeof validation?.max == "number";
287
- });
288
- }
289
-
290
- function hasClaimTokens(document) {
291
- const root = recordOf(document);
292
- return root === void 0 ? !1 : recordsAt(root, "pendingEffects").some(entry => {
293
- const claim = recordOf(entry.claim);
294
- return claim !== void 0 && typeof claim.claimToken == "string";
295
- });
296
- }
297
-
298
- function hasReadinessRequirements(document) {
299
- const root = recordOf(document);
300
- return root === void 0 ? !1 : Array.isArray(recordOf(root.start)?.requirements) ? !0 : recordsAt(root, "stages").some(stage => recordsAt(stage, "activities").some(activity => Array.isArray(activity.requirements)));
301
- }
302
-
303
- const featureDetectors = {
304
- "governed-model-stamps": () => !0,
305
- "subject-field-kind": document => hasFieldKind(document, "subject"),
306
- "typed-scalar-choice-lists": hasChoiceList,
307
- "action-semantics": hasActionSemantics,
308
- "inclusive-scalar-bounds": hasScalarValidation,
309
- "progress-field-kind": document => hasFieldKind(document, "progress"),
310
- "effect-claim-tokens": hasClaimTokens,
311
- "classified-principal-ids": () => !0,
312
- "readiness-requirements": hasReadinessRequirements,
313
- "due-date-field-kinds": document => hasFieldKind(document, "dueDate") || hasFieldKind(document, "dueDatetime")
314
- };
315
-
316
- function requiredModelFeatures(documentType, document) {
317
- return DATA_MODEL_CHANGES.filter(change => change.documentTypes.some(candidate => candidate === documentType) && featureDetectors[change.id](document));
318
- }
319
-
320
- function requiredReaderModel(documentType, document) {
321
- return Math.max(0, ...requiredModelFeatures(documentType, document).map(change => change.minReaderModel));
322
- }
323
-
324
- function modelStampFor(args) {
325
- return {
326
- modelVersion: DATA_MODEL_VERSION,
327
- minReaderModel: Math.max(DATA_MODEL_MIN_READER, args.storedMinReaderModel ?? 0, requiredReaderModel(args.documentType, args.document))
328
- };
329
- }
330
-
331
- function fieldTreeShape(value) {
332
- if (Array.isArray(value)) return value.map(fieldTreeShape);
333
- if (value === null) return "null";
334
- if (typeof value == "object") {
335
- const record = value;
336
- return Object.fromEntries(Object.keys(record).toSorted().map(key => [ key, fieldTreeShape(record[key]) ]));
337
- }
338
- return typeof value;
339
- }
340
-
341
- function modelVersionOf(doc) {
342
- const stamp = doc.modelVersion;
343
- return typeof stamp == "number" ? stamp : 0;
344
- }
345
-
346
- function minReaderModelOf(doc) {
347
- const floor = doc.minReaderModel;
348
- return typeof floor == "number" ? floor : modelVersionOf(doc);
349
- }
350
-
351
- class ModelVersionAheadError extends WorkflowError {
352
- documentId;
353
- documentModelVersion;
354
- requiredReaderModel;
355
- engineModelVersion;
356
- constructor(args) {
357
- super("model-version-ahead", `Document "${args.documentId}" was written by engine data model ${args.documentModelVersion} and requires a reader at model ${args.requiredReaderModel} or newer; this engine reads up to model ${DATA_MODEL_VERSION}. Upgrade @sanity/workflow-engine to a version that understands it.`),
358
- this.name = "ModelVersionAheadError", this.documentId = args.documentId, this.documentModelVersion = args.documentModelVersion,
359
- this.requiredReaderModel = args.requiredReaderModel, this.engineModelVersion = DATA_MODEL_VERSION;
360
- }
361
- }
362
-
363
- function assertReadableModel(doc) {
364
- const documentReaderModel = minReaderModelOf(doc);
365
- if (documentReaderModel > DATA_MODEL_VERSION) throw new ModelVersionAheadError({
366
- documentId: doc._id,
367
- documentModelVersion: modelVersionOf(doc),
368
- requiredReaderModel: documentReaderModel
369
- });
370
- return doc;
371
- }
372
-
373
- function isCascadeFired(action) {
374
- return action.when !== void 0;
375
- }
376
-
377
- function deriveActivityKind(activity) {
378
- if (activity.target !== void 0) return "manual";
379
- const actions = activity.actions ?? [];
380
- return actions.some(a => !isCascadeFired(a)) ? "user" : actions.some(a => (a.effects ?? []).length > 0 || a.spawn !== void 0) ? "service" : actions.length > 0 ? "receive" : "script";
381
- }
382
-
383
- function deriveExecutorClassification(activity) {
384
- if (activity.target !== void 0) return "off-system";
385
- const actions = activity.actions ?? [], cascadeFired = actions.filter(isCascadeFired).length;
386
- return cascadeFired === actions.length ? "autonomous" : cascadeFired === 0 ? "interactive" : "hybrid";
387
- }
388
-
389
- function driverKind(actor) {
390
- return actor.kind === "person" || actor.kind === "agent" ? actor.kind : "service";
391
- }
392
-
393
- function andConditions(parts) {
394
- const present = parts.filter(p => p !== void 0);
395
- if (present.length !== 0) return present.length === 1 ? present[0] : present.map(p => `(${p})`).join(" && ");
396
- }
397
-
398
117
  const KNOWN_SCHEMES = /* @__PURE__ */ new Set([ "dataset", "canvas", "media-library", "dashboard" ]), KNOWN_SCHEMES_TEXT = [ ...KNOWN_SCHEMES ].join(", ");
399
118
 
400
119
  class VersionSpecificDatasetGdrError extends Error {
@@ -806,6 +525,7 @@ function desugarWorkflow(authoring) {
806
525
  return {
807
526
  ...stripUndefined({
808
527
  name: stage.name,
528
+ semantics: stage.semantics,
809
529
  title: stage.title,
810
530
  description: stage.description,
811
531
  groups: stage.groups,
@@ -829,6 +549,7 @@ function desugarWorkflow(authoring) {
829
549
  definition: {
830
550
  ...stripUndefined({
831
551
  name: authoring.name,
552
+ semantics: authoring.semantics,
832
553
  title: authoring.title,
833
554
  description: authoring.description,
834
555
  groups: authoring.groups,
@@ -1055,6 +776,7 @@ function desugarActivity({activity: activity, path: path, stageEnv: stageEnv, ct
1055
776
  return {
1056
777
  ...stripUndefined({
1057
778
  name: activity.name,
779
+ semantics: activity.semantics,
1058
780
  title: activity.title,
1059
781
  description: activity.description,
1060
782
  groups: activity.groups,
@@ -1526,7 +1248,58 @@ function isTerminalActivityStatus(status) {
1526
1248
  return TERMINAL_ACTIVITY_STATUSES.includes(status);
1527
1249
  }
1528
1250
 
1529
- const ACTION_SEMANTICS = [ "decision.accept", "decision.decline" ], FIELD_SCOPES = [ "workflow", "stage", "activity" ], DOCUMENT_VALUE_PERMISSIONS = [ "create", "read", "update" ], MUTATION_GUARD_ACTIONS = [ "create", "update", "delete", "publish", "unpublish" ], ACTIVITY_KINDS = [ "user", "service", "script", "manual", "receive" ], EXECUTOR_CLASSIFICATIONS = [ "autonomous", "interactive", "off-system", "hybrid" ], GROUP_KINDS = [ "core", "details" ], DRIVER_KINDS = [ "person", "agent", "service", "engine" ], CONDITION_VARS = [ {
1251
+ const SIGNAL_SEMANTICS = [ "signal.positive", "signal.caution", "signal.critical" ], DECISION_SEMANTICS = [ "decision.accept", "decision.decline" ], ACTION_SEMANTICS = [ ...DECISION_SEMANTICS, ...SIGNAL_SEMANTICS ], FIELD_SCOPES = [ "workflow", "stage", "activity" ], DOCUMENT_VALUE_PERMISSIONS = [ "create", "read", "update" ], MUTATION_GUARD_ACTIONS = [ "create", "update", "delete", "publish", "unpublish" ], ACTIVITY_KINDS = [ "user", "service", "script", "manual", "receive" ], EXECUTOR_CLASSIFICATIONS = [ "autonomous", "interactive", "off-system", "hybrid" ], GROUP_KINDS = [ "core", "details" ], DRIVER_KINDS = [ "person", "agent", "service", "engine" ];
1252
+
1253
+ function releaseDocId(releaseName) {
1254
+ return `_.releases.${releaseName}`;
1255
+ }
1256
+
1257
+ function releaseRef({res: res, releaseName: releaseName}) {
1258
+ if (releaseName.length === 0) throw new ContractViolationError("releaseRef: releaseName must be a non-empty release name");
1259
+ return {
1260
+ id: gdrFromResource(res, releaseDocId(releaseName)),
1261
+ type: "system.release",
1262
+ releaseName: releaseName
1263
+ };
1264
+ }
1265
+
1266
+ function isAlwaysArrayFieldKind(kind) {
1267
+ return kind === "doc.refs" || kind === "assignees" || kind === "array";
1268
+ }
1269
+
1270
+ function isSingleDocRefKind(kind) {
1271
+ return kind === "doc.ref" || kind === "subject";
1272
+ }
1273
+
1274
+ function refKindAcceptsTypes(kind) {
1275
+ return isSingleDocRefKind(kind) || kind === "doc.refs";
1276
+ }
1277
+
1278
+ function isSingleDocRefEntry(entry) {
1279
+ return isSingleDocRefKind(entry._type);
1280
+ }
1281
+
1282
+ function isTodoListItem(row) {
1283
+ if (typeof row != "object" || row === null) return !1;
1284
+ const candidate = row, status = candidate.status;
1285
+ return typeof candidate._key == "string" && typeof candidate.label == "string" && (status == null || typeof status == "string");
1286
+ }
1287
+
1288
+ function declaredRowColumns(entry) {
1289
+ if (("_type" in entry ? entry._type : entry.type) === "array") return new Set((("of" in entry ? entry.of : void 0) ?? []).map(shape => shape.name));
1290
+ }
1291
+
1292
+ function isTodoListEntry(entry) {
1293
+ const columns = declaredRowColumns(entry);
1294
+ return columns !== void 0 && columns.has("label") && columns.has("status");
1295
+ }
1296
+
1297
+ function isNotesEntry(entry) {
1298
+ const columns = declaredRowColumns(entry);
1299
+ return columns !== void 0 && columns.has("body") && columns.has("actor") && columns.has("at");
1300
+ }
1301
+
1302
+ const CONDITION_VARS = [ {
1530
1303
  name: "self",
1531
1304
  binding: "always",
1532
1305
  label: "this workflow instance",
@@ -1601,6 +1374,11 @@ const ACTION_SEMANTICS = [ "decision.accept", "decision.decline" ], FIELD_SCOPES
1601
1374
  binding: "caller",
1602
1375
  label: "your permissions",
1603
1376
  description: "Advisory per-permission booleans computed from the caller's grants; `undefined` without grants. Bound wherever grants ride the evaluation: the projection's rendered scope (fireAction-action filters, activity requirements, editability predicates) and the fireAction/editField commit gates. Deploy rejects it at every site that evaluates without grants: transition `when`s, activity filters, cascade-fired actions' `when`/`filter`, effect bindings, where-op `where`s, and the spawn `forEach`/`with`/`context` sites."
1377
+ }, {
1378
+ name: "attributes",
1379
+ binding: "caller",
1380
+ label: "your attributes",
1381
+ description: "Advisory org-level User Attributes for the caller (Enterprise — same values as lake `user::attributes()`), keyed by attribute name with each active scalar or array value. `undefined` on expected HTTP absence; unexpected fetch failures throw; empty page binds `{}`. Bound wherever grants ride the evaluation (same sites as `$can`). Soft-gate paths fetch at most 100 attributes (no further pages) and warn when the envelope reports `hasMore: true` (partial bag still binds). Not a security boundary — the Content Lake remains the only enforcement point."
1604
1382
  }, {
1605
1383
  name: "row",
1606
1384
  binding: "spawn",
@@ -1766,54 +1544,7 @@ function documentIdOf(doc) {
1766
1544
  return "(unknown id)";
1767
1545
  }
1768
1546
 
1769
- const ACTOR_KINDS = [ "person", "agent", "system" ];
1770
-
1771
- function releaseDocId(releaseName) {
1772
- return `_.releases.${releaseName}`;
1773
- }
1774
-
1775
- function releaseRef({res: res, releaseName: releaseName}) {
1776
- if (releaseName.length === 0) throw new ContractViolationError("releaseRef: releaseName must be a non-empty release name");
1777
- return {
1778
- id: gdrFromResource(res, releaseDocId(releaseName)),
1779
- type: "system.release",
1780
- releaseName: releaseName
1781
- };
1782
- }
1783
-
1784
- function isSingleDocRefKind(kind) {
1785
- return kind === "doc.ref" || kind === "subject";
1786
- }
1787
-
1788
- function refKindAcceptsTypes(kind) {
1789
- return isSingleDocRefKind(kind) || kind === "doc.refs";
1790
- }
1791
-
1792
- function isSingleDocRefEntry(entry) {
1793
- return isSingleDocRefKind(entry._type);
1794
- }
1795
-
1796
- function isTodoListItem(row) {
1797
- if (typeof row != "object" || row === null) return !1;
1798
- const candidate = row, status = candidate.status;
1799
- return typeof candidate._key == "string" && typeof candidate.label == "string" && (status == null || typeof status == "string");
1800
- }
1801
-
1802
- function declaredRowColumns(entry) {
1803
- if (("_type" in entry ? entry._type : entry.type) === "array") return new Set((("of" in entry ? entry.of : void 0) ?? []).map(shape => shape.name));
1804
- }
1805
-
1806
- function isTodoListEntry(entry) {
1807
- const columns = declaredRowColumns(entry);
1808
- return columns !== void 0 && columns.has("label") && columns.has("status");
1809
- }
1810
-
1811
- function isNotesEntry(entry) {
1812
- const columns = declaredRowColumns(entry);
1813
- return columns !== void 0 && columns.has("body") && columns.has("actor") && columns.has("at");
1814
- }
1815
-
1816
- const ANONYMOUS_IDENTITY = "<anonymous>", SYSTEM_IDENTITY = "<system>", E_PREFIXED_PROJECT_ID = /^e-(.+)$/;
1547
+ const ACTOR_KINDS = [ "person", "agent", "system" ], ANONYMOUS_IDENTITY = "<anonymous>", SYSTEM_IDENTITY = "<system>", E_PREFIXED_PROJECT_ID = /^e-(.+)$/;
1817
1548
 
1818
1549
  function classifyPrincipalId(id) {
1819
1550
  if (id === ANONYMOUS_IDENTITY || id === SYSTEM_IDENTITY) return {
@@ -2242,6 +1973,10 @@ function opSchemas(targetSchema) {
2242
1973
  type: v.literal("field.set"),
2243
1974
  target: targetSchema,
2244
1975
  value: ValueExprSchema
1976
+ }), v.strictObject({
1977
+ type: v.literal("field.setIfMissing"),
1978
+ target: targetSchema,
1979
+ value: ValueExprSchema
2245
1980
  }), v.strictObject({
2246
1981
  type: v.literal("field.unset"),
2247
1982
  target: targetSchema
@@ -2249,6 +1984,14 @@ function opSchemas(targetSchema) {
2249
1984
  type: v.literal("field.append"),
2250
1985
  target: targetSchema,
2251
1986
  value: ValueExprSchema
1987
+ }), v.strictObject({
1988
+ type: v.literal("field.inc"),
1989
+ target: targetSchema,
1990
+ value: v.optional(ValueExprSchema)
1991
+ }), v.strictObject({
1992
+ type: v.literal("field.dec"),
1993
+ target: targetSchema,
1994
+ value: v.optional(ValueExprSchema)
2252
1995
  }), v.strictObject({
2253
1996
  type: v.literal("field.updateWhere"),
2254
1997
  target: targetSchema,
@@ -2465,17 +2208,27 @@ const TodoListFieldSchema = pinned()(v.strictObject(listSugarFields("todoList"))
2465
2208
  required: v.optional(v.boolean()),
2466
2209
  options: v.optional(ChoiceOptionsSchema),
2467
2210
  validation: v.optional(ScalarValidationSchema)
2468
- }), choiceOptionsCheck(), scalarValidationCheck());
2211
+ }), choiceOptionsCheck(), scalarValidationCheck()), CUSTOM_SEMANTIC_HINT = "`custom.<camelCaseMeaning>`", CustomSemanticSchema = v.custom(input => typeof input == "string" && /^custom\.[a-z][a-zA-Z0-9]*$/.test(input)), SemanticSchema = v.union([ picklist(SIGNAL_SEMANTICS), CustomSemanticSchema ], `expected ${SIGNAL_SEMANTICS.join(", ")}, or ${CUSTOM_SEMANTIC_HINT}`), ActionSemanticSchema = v.union([ picklist(ACTION_SEMANTICS), CustomSemanticSchema ], `expected ${ACTION_SEMANTICS.join(", ")}, or ${CUSTOM_SEMANTIC_HINT}`);
2212
+
2213
+ function semanticNamespace(semantic) {
2214
+ return semantic.startsWith("custom.") ? semantic : semantic.split(".", 1)[0] ?? semantic;
2215
+ }
2469
2216
 
2470
2217
  function hasUniqueSemanticNamespaces(semantics) {
2471
- const namespaces = semantics.map(semantic => semantic.split(".", 1)[0]);
2218
+ const namespaces = semantics.map(semanticNamespace);
2472
2219
  return new Set(namespaces).size === namespaces.length;
2473
2220
  }
2474
2221
 
2222
+ function semanticsFieldSchema(semantic) {
2223
+ return v.optional(v.pipe(v.array(semantic), v.minLength(1, "declare at least one semantic, or omit `semantics`"), v.check(hasUniqueSemanticNamespaces, "declare at most one semantic from each namespace")));
2224
+ }
2225
+
2226
+ const SemanticsFieldSchema = semanticsFieldSchema(SemanticSchema), ActionSemanticsFieldSchema = semanticsFieldSchema(ActionSemanticSchema);
2227
+
2475
2228
  function actionFields(op, group) {
2476
2229
  return {
2477
2230
  name: NonEmpty,
2478
- semantics: v.optional(v.pipe(v.array(picklist(ACTION_SEMANTICS)), v.minLength(1, "declare at least one semantic, or omit `semantics`"), v.check(hasUniqueSemanticNamespaces, "declare at most one semantic from each namespace"))),
2231
+ semantics: ActionSemanticsFieldSchema,
2479
2232
  title: v.optional(v.string()),
2480
2233
  description: v.optional(v.string()),
2481
2234
  group: v.optional(group),
@@ -2522,6 +2275,7 @@ const StoredActionSchema = pinned()(v.strictObject({
2522
2275
  function activityFields({field: field, action: action, target: target, group: group}) {
2523
2276
  return {
2524
2277
  name: NonEmpty,
2278
+ semantics: SemanticsFieldSchema,
2525
2279
  title: v.optional(v.string()),
2526
2280
  description: v.optional(v.string()),
2527
2281
  groups: v.optional(v.array(GroupSchema)),
@@ -2595,6 +2349,7 @@ const GuardSchema = v.strictObject(guardFields(NonEmpty)), AuthoringGuardSchema
2595
2349
  function stageFields({field: field, activity: activity, transition: transition, guard: guard, editable: editable}) {
2596
2350
  return {
2597
2351
  name: NonEmpty,
2352
+ semantics: SemanticsFieldSchema,
2598
2353
  title: v.optional(v.string()),
2599
2354
  description: v.optional(v.string()),
2600
2355
  groups: v.optional(v.array(GroupSchema)),
@@ -2633,6 +2388,7 @@ const StoredStartSchema = pinned()(v.strictObject(startFields(picklist(START_KIN
2633
2388
  function workflowFields({field: field, stage: stage, start: start}) {
2634
2389
  return {
2635
2390
  name: NonEmpty,
2391
+ semantics: SemanticsFieldSchema,
2636
2392
  title: NonEmpty,
2637
2393
  description: v.optional(v.string()),
2638
2394
  groups: v.optional(v.array(GroupSchema)),
@@ -2829,11 +2585,20 @@ function checkStageReachability({def: def, stageNames: stageNames, issues: issue
2829
2585
  });
2830
2586
  }
2831
2587
 
2588
+ function actionSites(def) {
2589
+ return def.stages.flatMap((stage, i) => (stage.activities ?? []).flatMap((activity, j) => (activity.actions ?? []).map((action, a) => ({
2590
+ action: action,
2591
+ activity: activity,
2592
+ stage: stage,
2593
+ path: [ "stages", i, "activities", j, "actions", a ]
2594
+ }))));
2595
+ }
2596
+
2832
2597
  function effectNameSites(def) {
2833
2598
  const sites = [];
2834
- for (const [i, stage] of def.stages.entries()) for (const [j, activity] of (stage.activities ?? []).entries()) for (const [a, action] of (activity.actions ?? []).entries()) collectEffects({
2599
+ for (const {action: action, path: path} of actionSites(def)) collectEffects({
2835
2600
  effects: action.effects,
2836
- path: [ "stages", i, "activities", j, "actions", a, "effects" ],
2601
+ path: [ ...path, "effects" ],
2837
2602
  sites: sites
2838
2603
  });
2839
2604
  return sites;
@@ -2964,13 +2729,22 @@ function checkUnboundConditionVars(def, issues) {
2964
2729
  }
2965
2730
  }
2966
2731
 
2732
+ const SOFT_GATE_VARS = {
2733
+ can: {
2734
+ noun: "the caller's grants"
2735
+ },
2736
+ attributes: {
2737
+ noun: "the caller's org-level user attributes"
2738
+ }
2739
+ }, SOFT_GATE_VAR_NAMES = Object.keys(SOFT_GATE_VARS);
2740
+
2967
2741
  function unboundVarsAt(site) {
2968
2742
  const callerVars = unboundCallerVars(site.policy);
2969
2743
  return site.bindsRow === !0 ? callerVars : [ ...callerVars, "row" ];
2970
2744
  }
2971
2745
 
2972
2746
  function unboundCallerVars(policy) {
2973
- return policy === "cascade" ? CALLER_BOUND_VARS : policy === "caller-bound" ? [ "params" ] : policy === "triggered-payload" ? [ "can", "params" ] : [ "can" ];
2747
+ return policy === "cascade" ? CALLER_BOUND_VARS : policy === "caller-bound" ? [ "params" ] : policy === "triggered-payload" ? [ ...SOFT_GATE_VAR_NAMES, "params" ] : SOFT_GATE_VAR_NAMES;
2974
2748
  }
2975
2749
 
2976
2750
  const ROW_BINDING_CLAUSE = "$row (the discovered row in a spawn projection; the stored row under test in a where-op) is bound only while a spawn `with` projection or a where-op `where` evaluates";
@@ -2980,7 +2754,12 @@ function rowVarMessage(site) {
2980
2754
  }
2981
2755
 
2982
2756
  function callerVarMessage(site, name) {
2983
- return site.policy === "cascade" ? `${site.label} reads $${name} — cascade gates (transition \`when\`s, activity \`filter\`s, a cascade-fired action's \`when\`/\`filter\`) must resolve identically no matter whose token drives the cascade ($assigned is constant false, the other caller vars hold no value); gate on instance state (e.g. a field an action wrote), or pin executing identities with \`roles\`` : site.policy === "caller-bound" ? `${site.label} reads $${name} — $params (the firing action's args) is bound only while the action's effect bindings and where-op \`where\`s evaluate; this site never binds it, so the condition could never pass. Bind $params in an effect binding or a where-op instead, or gate on a field an action wrote` : site.policy === "triggered-payload" && name === "params" ? `${site.label} reads $params — a cascade-fired action has no caller to supply args, so $params never holds a value in its payload; read fields or effect outputs instead` : `${site.label} reads $can — $can (the caller's grants) is bound only in the caller-bound projection (action filters, requirements, editable predicates) and never holds a value in cascade conditions; move the check to one of those sites or drop $can`;
2757
+ if (site.policy === "cascade") return `${site.label} reads $${name} — cascade gates (transition \`when\`s, activity \`filter\`s, a cascade-fired action's \`when\`/\`filter\`) must resolve identically no matter whose token drives the cascade ($assigned is constant false, the other caller vars hold no value); gate on instance state (e.g. a field an action wrote), or pin executing identities with \`roles\``;
2758
+ if (site.policy === "caller-bound") return `${site.label} reads $${name} — $params (the firing action's args) is bound only while the action's effect bindings and where-op \`where\`s evaluate; this site never binds it, so the condition could never pass. Bind $params in an effect binding or a where-op instead, or gate on a field an action wrote`;
2759
+ if (site.policy === "triggered-payload" && name === "params") return `${site.label} reads $params — a cascade-fired action has no caller to supply args, so $params never holds a value in its payload; read fields or effect outputs instead`;
2760
+ const softGate = SOFT_GATE_VARS[name];
2761
+ if (softGate !== void 0) return `${site.label} reads $${name} — $${name} (${softGate.noun}) is bound only in the caller-bound projection (action filters, requirements, editable predicates); this site never binds it. Move the check to one of those sites or drop $${name}`;
2762
+ throw new Error(`callerVarMessage: unreachable for $${name} at ${site.label} (policy ${site.policy})`);
2984
2763
  }
2985
2764
 
2986
2765
  function conditionSites(def) {
@@ -3235,9 +3014,9 @@ function belowScopeNestedSites(args) {
3235
3014
  }
3236
3015
 
3237
3016
  function checkLevelKindEffectOutputs(def, issues) {
3238
- for (const [i, stage] of def.stages.entries()) for (const [j, activity] of (stage.activities ?? []).entries()) for (const [a, action] of (activity.actions ?? []).entries()) pushOutputIssues({
3017
+ for (const {action: action, path: path} of actionSites(def)) pushOutputIssues({
3239
3018
  action: action,
3240
- path: [ "stages", i, "activities", j, "actions", a ],
3019
+ path: path,
3241
3020
  issues: issues
3242
3021
  });
3243
3022
  }
@@ -3319,18 +3098,18 @@ function storedRolesIssue(action) {
3319
3098
  }
3320
3099
 
3321
3100
  function checkStoredRolesPlacement(def, issues) {
3322
- for (const [i, stage] of def.stages.entries()) for (const [j, activity] of (stage.activities ?? []).entries()) for (const [a, action] of (activity.actions ?? []).entries()) {
3101
+ for (const {action: action, path: path} of actionSites(def)) {
3323
3102
  const message = storedRolesIssue(action);
3324
3103
  message !== void 0 && issues.push({
3325
- path: [ "stages", i, "activities", j, "actions", a, "roles" ],
3104
+ path: [ ...path, "roles" ],
3326
3105
  message: message
3327
3106
  });
3328
3107
  }
3329
3108
  }
3330
3109
 
3331
3110
  function checkTriggeredActionParams(def, issues) {
3332
- for (const [i, stage] of def.stages.entries()) for (const [j, activity] of (stage.activities ?? []).entries()) for (const [a, action] of (activity.actions ?? []).entries()) action.when === void 0 || (action.params ?? []).length === 0 || issues.push({
3333
- path: [ "stages", i, "activities", j, "actions", a, "params" ],
3111
+ for (const {action: action, path: path} of actionSites(def)) action.when === void 0 || (action.params ?? []).length === 0 || issues.push({
3112
+ path: [ ...path, "params" ],
3334
3113
  message: `action "${action.name}" declares params but is cascade-fired (\`when\`) — no caller ever supplies args to a trigger. Drop the params, or drop \`when\` to make it a fireAction-fired action`
3335
3114
  });
3336
3115
  }
@@ -3375,13 +3154,20 @@ function checkSingleSubjectRequirements(def, issues) {
3375
3154
 
3376
3155
  function checkStartFilterReads(def, issues) {
3377
3156
  const filter = def.start?.filter;
3378
- filter !== void 0 && (conditionParameterNames(filter).has("fields") && issues.push({
3157
+ if (filter === void 0) return;
3158
+ const params = conditionParameterNames(filter);
3159
+ params.has("fields") && issues.push({
3379
3160
  path: [ "start", "filter" ],
3380
3161
  message: "start.filter reads $fields, but the filter is browse-time-pure — a start surface evaluates it per document, before any inputs exist, so $fields cannot be bound. Move the input-dependent rule to a start requirement, the start-time readiness predicate that binds $fields and is enforced by startInstance"
3381
- }), readsRootDocument(filter) && !(def.fields ?? []).some(isSubjectEntry) && issues.push({
3162
+ });
3163
+ for (const name of CALLER_BOUND_VARS) params.has(name) && issues.push({
3164
+ path: [ "start", "filter" ],
3165
+ message: `start.filter reads $${name} — start.filter is a read-side document-visibility rule (definitionsForDocument / start controls); startInstance never evaluates it, and no caller bag binds there, so the read is GROQ null and the filter can never match. Drop $${name} from start.filter. A "who may start" rule belongs in a start requirement, not in the browse-time filter`
3166
+ });
3167
+ readsRootDocument(filter) && !(def.fields ?? []).some(isSubjectEntry) && issues.push({
3382
3168
  path: [ "start", "filter" ],
3383
3169
  message: "start.filter reads the candidate document (its root), but the definition declares no `subject` entry — a read surface would never have a document to bind as root, so every root read is GROQ null and the filter silently misevaluates. Declare a `subject` entry (the document the workflow is about), or gate on the dataset instead"
3384
- }));
3170
+ });
3385
3171
  }
3386
3172
 
3387
3173
  function checkStartRequirementReads(def, issues) {
@@ -3677,15 +3463,13 @@ function seedEarlierSiblingTarget(args) {
3677
3463
  }
3678
3464
 
3679
3465
  function opSites(def) {
3680
- const sites = [];
3681
- for (const [i, stage] of def.stages.entries()) for (const [j, activity] of (stage.activities ?? []).entries()) for (const [a, action] of (activity.actions ?? []).entries()) sites.push({
3466
+ return actionSites(def).map(({action: action, activity: activity, stage: stage, path: path}) => ({
3682
3467
  ops: action.ops,
3683
- path: [ "stages", i, "activities", j, "actions", a, "ops" ],
3468
+ path: [ ...path, "ops" ],
3684
3469
  label: `action "${action.name}"`,
3685
3470
  stage: stage,
3686
3471
  activity: activity
3687
- });
3688
- return sites;
3472
+ }));
3689
3473
  }
3690
3474
 
3691
3475
  function checkFieldReadOpValues(def, issues) {
@@ -3702,7 +3486,7 @@ function checkFieldReadOpValues(def, issues) {
3702
3486
  }
3703
3487
 
3704
3488
  function checkOpsFieldReads({ops: ops, path: path, label: label, ...ctx}) {
3705
- for (const [o, op] of (ops ?? []).entries()) if ("value" in op) for (const {read: read, path: readPath} of fieldReadsIn(op.value, [ ...path, o, "value" ])) checkOpFieldRead({
3489
+ for (const [o, op] of (ops ?? []).entries()) if (!(!("value" in op) || op.value === void 0)) for (const {read: read, path: readPath} of fieldReadsIn(op.value, [ ...path, o, "value" ])) checkOpFieldRead({
3706
3490
  ...ctx,
3707
3491
  read: read,
3708
3492
  path: readPath,
@@ -3753,35 +3537,55 @@ function opFieldReadMissMessage({read: read, where: where, hosts: hosts}) {
3753
3537
  return `${where} reads field "${read.field}", which is not declared at ${searched} — the read resolves to undefined at op time, so the write silently lands empty. Known: ${known.join(", ") || "(none)"}`;
3754
3538
  }
3755
3539
 
3756
- function checkUpdateWhereOps(def, issues) {
3540
+ function checkFieldTargetOps(def, issues) {
3757
3541
  const workflow = def.fields ?? [];
3758
3542
  for (const site of opSites(def)) for (const [o, op] of (site.ops ?? []).entries()) {
3759
- if (op.type !== "field.updateWhere") continue;
3760
- const scopes = {
3761
- workflow: workflow,
3762
- stage: site.stage.fields ?? [],
3763
- activity: site.activity.fields ?? []
3764
- };
3765
- checkUpdateWhereTargetKind({
3543
+ const path = [ ...site.path, o ], rule = TARGET_KIND_RULES[op.type];
3544
+ rule !== void 0 && "target" in op && checkTargetKind({
3766
3545
  op: op,
3767
- path: [ ...site.path, o ],
3546
+ path: [ ...path, "target" ],
3768
3547
  label: site.label,
3769
- scopes: scopes,
3548
+ scopes: opTargetScopes(workflow, site),
3549
+ rule: rule,
3770
3550
  issues: issues
3771
- }), checkUpdateWhereMergeKeys({
3551
+ }), op.type === "field.updateWhere" && checkUpdateWhereMergeKeys({
3772
3552
  op: op,
3773
- path: [ ...site.path, o ],
3553
+ path: path,
3774
3554
  label: site.label,
3775
3555
  issues: issues
3776
3556
  });
3777
3557
  }
3778
3558
  }
3779
3559
 
3780
- function checkUpdateWhereTargetKind({op: op, path: path, label: label, scopes: scopes, issues: issues}) {
3560
+ const arithmeticTargetRule = {
3561
+ accepts: target => target.type === "number",
3562
+ issue: () => "arithmetic ops target `number` entries only"
3563
+ }, TARGET_KIND_RULES = {
3564
+ "field.inc": arithmeticTargetRule,
3565
+ "field.dec": arithmeticTargetRule,
3566
+ "field.setIfMissing": {
3567
+ accepts: target => !isAlwaysArrayFieldKind(target.type),
3568
+ issue: () => "setIfMissing applies to nullable entries only; an empty array entry already holds []"
3569
+ },
3570
+ "field.updateWhere": {
3571
+ accepts: target => target.type === "array",
3572
+ issue: target => "updateWhere merges declared row sub-fields, so its target must be an `array` entry" + rowOpsHint(target.type)
3573
+ }
3574
+ };
3575
+
3576
+ function opTargetScopes(workflow, site) {
3577
+ return {
3578
+ workflow: workflow,
3579
+ stage: site.stage.fields ?? [],
3580
+ activity: site.activity.fields ?? []
3581
+ };
3582
+ }
3583
+
3584
+ function checkTargetKind({op: op, path: path, label: label, scopes: scopes, rule: rule, issues: issues}) {
3781
3585
  const target = scopes[op.target.scope]?.find(entry => entry.name === op.target.field);
3782
- target === void 0 || target.type === "array" || issues.push({
3783
- path: [ ...path, "target" ],
3784
- message: `${label} field.updateWhere targets ${op.target.scope}-scope "${op.target.field}" (${target.type}) — updateWhere merges declared row sub-fields, so its target must be an \`array\` entry${rowOpsHint(target.type)}`
3586
+ target === void 0 || rule.accepts(target) || issues.push({
3587
+ path: path,
3588
+ message: `${label} ${op.type} targets ${op.target.scope}-scope "${op.target.field}" (${target.type}) — ${rule.issue(target)}`
3785
3589
  });
3786
3590
  }
3787
3591
 
@@ -4013,11 +3817,11 @@ function checkWorkflowInvariants(def) {
4013
3817
  }), checkEffectNames(def, issues), checkGuardNames(def, issues), checkFieldEntryNames(def, issues),
4014
3818
  checkRequiredField(def, issues), checkStart(def, issues), checkPredicates(def, issues),
4015
3819
  checkUnboundConditionVars(def, issues), checkConditionFieldReads(def, issues), checkFieldReadSeeds(def, issues),
4016
- checkFieldReadOpValues(def, issues), checkUpdateWhereOps(def, issues), checkGuardFieldReads(def, issues),
3820
+ checkFieldReadOpValues(def, issues), checkFieldTargetOps(def, issues), checkGuardFieldReads(def, issues),
4017
3821
  checkAssigneesEntries(def, issues), checkDueDateEntries(def, issues), checkSubjectEntries(def, issues),
4018
3822
  checkLevelKindEffectOutputs(def, issues), checkActivityTerminalPaths(def, issues),
4019
3823
  checkTerminalStageActivities(def, issues), checkTriggeredActionParams(def, issues),
4020
3824
  checkStoredRolesPlacement(def, issues), checkGroups(def, issues), issues;
4021
3825
  }
4022
3826
 
4023
- export { ACTION_SEMANTICS, ACTIVITY_KINDS, ACTIVITY_STATUSES, ACTOR_KINDS, ANONYMOUS_IDENTITY, ActorShape, AuthoringActionSchema, AuthoringActivitySchema, AuthoringFieldEntrySchema, AuthoringGuardSchema, AuthoringOpSchema, AuthoringStageSchema, AuthoringTransitionSchema, AuthoringWorkflowSchema, CALLER_BOUND_VARS, CONDITION_VARS, ContractViolationError, DATA_MODEL_CHANGES, DATA_MODEL_MIN_READER, DATA_MODEL_VERSION, DEFAULT_TRANSITION_WHEN, DOCUMENT_VALUE_PERMISSIONS, DRIVER_KINDS, DefinitionInUseError, DefinitionNotFoundError, EFFECTS_READ, EXECUTOR_CLASSIFICATIONS, EffectNotFoundError, EffectSchema, FIELD_READ, FIELD_SCOPES, FIELD_VALUE_KINDS, FILTER_SCOPE_VARS, FieldValueShapeError, GROUP_KINDS, GUARD_PREDICATE_VARS, GdrShape, GroupSchema, InstanceNotFoundError, IsoTimestamp, MUTATION_GUARD_ACTIONS, ModelVersionAheadError, NonEmptyString, PersistedDocShapeError, READER_MODEL_ROLLOUT_URL, RESERVED_CONDITION_VARS, RESOURCE_ALIAS_NAME_SOURCE, ReaderModelAcknowledgementError, START_FILTER_VARS, START_REQUIREMENT_VARS, SYSTEM_IDENTITY, SpawnContractsInvalidError, StoredFieldOpSchema, VersionSpecificDatasetGdrError, WORKFLOW_DEFINITION_TYPE, WORKFLOW_INSTANCE_TYPE, WorkflowConfigSchema, WorkflowError, actorFulfillsRole, andConditions, assertReadableModel, assertReaderModelAcknowledgement, checkWorkflowInvariants, choiceValueIssues, classifyPrincipalId, clientConfigFromResource, conditionEffectReads, conditionFieldReadNames, conditionParameterNames, conditionSyntaxIssues, datasetResourceParts, definitionDocId, deriveActivityKind, deriveExecutorClassification, desugarWorkflow, directoryBridgeId, driverKind, errorMessage, evaluateCondition, evaluateConditionOutcome, evaluatePredicates, extractDocumentId, fieldTreeShape, fieldValueSchemas, firstCarriedGlobalId, formatIssuePath, formatIssues, formatValidationError, gdrFromResource, gdrRef, gdrResourcePrefix, gdrUri, groq, groupMembershipNames, isBareSeedId, isCascadeFired, isGdr, isGdrUri, isGuardReadExpr, isInputSourced, isNotesEntry, isParseableInstant, isSingleDocRefEntry, isSingleDocRefKind, isStartableDefinition, isSubjectEntry, isTerminalActivityStatus, isTodoListEntry, isTodoListItem, isUnevaluable, isUnprimed, labelFor, lakePrincipalId, minReaderModelOf, modelStampFor, modelVersionOf, parentRef, parseDefinitionSnapshot, parseDefinitionSnapshotValue, parseFieldValue, parseGdr, parseOrThrow, parsePersistedDoc, parseResourceGdr, parseStoredDefinition, readsRootDocument, refCanvas, refDashboard, refDataset, refKindAcceptsTypes, refMediaLibrary, refTypeIssues, rejectedRefTypes, releaseDocId, releaseRef, requiredModelFeatures, requiredReaderModel, resourceAliasesToMap, resourceFromGdrUri, resourceFromParsed, resourceGdr, rethrowWithContext, runGroq, sameResource, scalarValidationIssues, schemaTreeShape, selfGdr, startKindOf, tagScopeFilter, terminalState, toBareId, toPhysicalGdr, tolerantEntries, tolerantObject, tryParseGdr, validateFieldAppendItem, validateFieldValue, validateResourceAliasName, validateTag };
3827
+ export { ACTION_SEMANTICS, ACTIVITY_KINDS, ACTIVITY_STATUSES, ACTOR_KINDS, ANONYMOUS_IDENTITY, ActorShape, AuthoringActionSchema, AuthoringActivitySchema, AuthoringFieldEntrySchema, AuthoringGuardSchema, AuthoringOpSchema, AuthoringStageSchema, AuthoringTransitionSchema, AuthoringWorkflowSchema, CALLER_BOUND_VARS, CONDITION_VARS, ContractViolationError, DECISION_SEMANTICS, DEFAULT_TRANSITION_WHEN, DOCUMENT_VALUE_PERMISSIONS, DRIVER_KINDS, DefinitionInUseError, DefinitionNotFoundError, EFFECTS_READ, EXECUTOR_CLASSIFICATIONS, EffectNotFoundError, EffectSchema, FIELD_READ, FIELD_SCOPES, FIELD_VALUE_KINDS, FILTER_SCOPE_VARS, FieldValueShapeError, GROUP_KINDS, GUARD_PREDICATE_VARS, GdrShape, GroupSchema, InstanceNotFoundError, IsoTimestamp, MUTATION_GUARD_ACTIONS, NonEmptyString, PersistedDocShapeError, RESERVED_CONDITION_VARS, RESOURCE_ALIAS_NAME_SOURCE, SIGNAL_SEMANTICS, START_FILTER_VARS, START_REQUIREMENT_VARS, SYSTEM_IDENTITY, SpawnContractsInvalidError, StoredFieldOpSchema, VersionSpecificDatasetGdrError, WORKFLOW_DEFINITION_TYPE, WorkflowConfigSchema, WorkflowError, actorFulfillsRole, andConditions, checkWorkflowInvariants, choiceValueIssues, classifyPrincipalId, clientConfigFromResource, conditionEffectReads, conditionFieldReadNames, conditionParameterNames, conditionSyntaxIssues, datasetResourceParts, definitionDocId, deriveActivityKind, deriveExecutorClassification, desugarWorkflow, directoryBridgeId, driverKind, errorMessage, evaluateCondition, evaluateConditionOutcome, evaluatePredicates, extractDocumentId, fieldValueSchemas, firstCarriedGlobalId, formatIssuePath, formatIssues, formatValidationError, gdrFromResource, gdrRef, gdrResourcePrefix, gdrUri, groq, groupMembershipNames, isAlwaysArrayFieldKind, isBareSeedId, isCascadeFired, isGdr, isGdrUri, isGuardReadExpr, isInputSourced, isNotesEntry, isParseableInstant, isSingleDocRefEntry, isSingleDocRefKind, isStartableDefinition, isSubjectEntry, isTerminalActivityStatus, isTodoListEntry, isTodoListItem, isUnevaluable, labelFor, lakePrincipalId, parseFieldValue, parseGdr, parseOrThrow, parsePersistedDoc, parseResourceGdr, parseStoredDefinition, readsRootDocument, refCanvas, refDashboard, refDataset, refKindAcceptsTypes, refMediaLibrary, refTypeIssues, rejectedRefTypes, releaseDocId, releaseRef, resourceAliasesToMap, resourceFromGdrUri, resourceFromParsed, resourceGdr, rethrowWithContext, runGroq, sameResource, scalarValidationIssues, schemaTreeShape, selfGdr, startKindOf, tagScopeFilter, toBareId, toPhysicalGdr, tolerantEntries, tolerantObject, tryParseGdr, validateFieldAppendItem, validateFieldValue, validateResourceAliasName, validateTag };