@sanity/workflow-engine 0.9.0 → 0.11.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/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { parse, evaluate } from "groq-js";
2
2
  import { actorFulfillsRole, isTerminalTaskStatus, WORKFLOW_DEFINITION_TYPE, andConditions, DOCUMENT_VALUE_PERMISSIONS } from "./_chunks-es/schema.js";
3
- import { isStartableDefinition } from "./_chunks-es/schema.js";
3
+ import { DRIVER_KINDS, TASK_KINDS, isStartableDefinition } from "./_chunks-es/schema.js";
4
4
  import * as v from "valibot";
5
5
  function findOpenStageEntry(host) {
6
6
  return host.stages.find((s) => s.name === host.currentStage && s.exitedAt === void 0);
@@ -111,7 +111,7 @@ function buildParams(args) {
111
111
  const { instance, now, snapshot, extra } = args, currentTasks2 = findOpenStageEntry(instance)?.tasks ?? [];
112
112
  return {
113
113
  self: selfGdr(instance),
114
- state: renderedState(instance.state ?? [], snapshot),
114
+ fields: renderedFields(instance.fields ?? [], snapshot),
115
115
  parent: instance.ancestors.at(-1)?.id ?? null,
116
116
  ancestors: instance.ancestors.map((a) => a.id),
117
117
  stage: instance.currentStage,
@@ -126,7 +126,7 @@ function buildParams(args) {
126
126
  ...extra
127
127
  };
128
128
  }
129
- function renderedState(entries, snapshot) {
129
+ function renderedFields(entries, snapshot) {
130
130
  const out = {};
131
131
  for (const entry of entries) out[entry.name] = renderedValue(entry, snapshot);
132
132
  return out;
@@ -134,15 +134,15 @@ function renderedState(entries, snapshot) {
134
134
  function renderedValue(entry, snapshot) {
135
135
  return entry._type !== "doc.ref" || entry.value === null || snapshot === void 0 ? entry.value : snapshot.docs.find((d) => d._id === entry.value.id) ?? entry.value;
136
136
  }
137
- function scopedStateOverlay(instance, snapshot, taskName) {
137
+ function scopedFieldOverlay(instance, snapshot, taskName) {
138
138
  const stageEntry = findOpenStageEntry(instance);
139
139
  if (stageEntry === void 0) return {};
140
- const stageState = renderedState(stageEntry.state ?? [], snapshot), task = taskName ? stageEntry.tasks.find((t) => t.name === taskName) : void 0;
141
- return { ...stageState, ...renderedState(task?.state ?? [], snapshot) };
140
+ const stageFields = renderedFields(stageEntry.fields ?? [], snapshot), task = taskName ? stageEntry.tasks.find((t) => t.name === taskName) : void 0;
141
+ return { ...stageFields, ...renderedFields(task?.fields ?? [], snapshot) };
142
142
  }
143
143
  function assignedFor(instance, taskName, actor, roleAliases) {
144
144
  if (actor === void 0) return !1;
145
- const entry = findOpenStageEntry(instance)?.tasks.find((t) => t.name === taskName)?.state?.find((s) => s._type === "assignees");
145
+ const entry = findOpenStageEntry(instance)?.tasks.find((t) => t.name === taskName)?.fields?.find((s) => s._type === "assignees");
146
146
  return entry === void 0 ? !1 : entry.value.some(
147
147
  (a) => a.type === "user" ? a.id === actor.id : actorFulfillsRole(actor.roles, a.role, roleAliases)
148
148
  );
@@ -169,17 +169,17 @@ function paramsForLake(params) {
169
169
  self: typeof params.self == "string" ? bareId(params.self) : params.self,
170
170
  parent: typeof params.parent == "string" ? bareId(params.parent) : params.parent,
171
171
  ancestors: Array.isArray(params.ancestors) ? params.ancestors.map((a) => typeof a == "string" ? bareId(a) : a) : params.ancestors,
172
- state: stripStateForLake(params.state)
172
+ fields: stripFieldsForLake(params.fields)
173
173
  };
174
174
  }
175
- function stripStateForLake(value) {
175
+ function stripFieldsForLake(value) {
176
176
  if (value == null) return value;
177
177
  if (typeof value == "string") return bareId(value);
178
- if (Array.isArray(value)) return value.map(stripStateForLake);
178
+ if (Array.isArray(value)) return value.map(stripFieldsForLake);
179
179
  if (typeof value == "object") {
180
180
  const out = {};
181
181
  for (const [k, v2] of Object.entries(value))
182
- out[k] = stripStateForLake(v2);
182
+ out[k] = stripFieldsForLake(v2);
183
183
  return out;
184
184
  }
185
185
  return value;
@@ -198,17 +198,17 @@ function getPath(value, path) {
198
198
  function resourceOf(p) {
199
199
  return p.scheme === "dataset" ? { type: "dataset", id: `${p.projectId}.${p.dataset}` } : { type: p.scheme, id: p.resourceId ?? "" };
200
200
  }
201
- const STATE_READ = /^\$state\.(\w+)(?:\.(.+))?$/, EFFECTS_READ = /^\$effects\['([^']+)'\](?:\.(.+))?$/;
201
+ const FIELD_READ = /^\$fields\.(\w+)(?:\.(.+))?$/, EFFECTS_READ = /^\$effects\['([^']+)'\](?:\.(.+))?$/;
202
202
  function isGuardReadExpr(expr) {
203
- return expr === "$self" || expr === "$now" || STATE_READ.test(expr) || EFFECTS_READ.test(expr);
203
+ return expr === "$self" || expr === "$now" || FIELD_READ.test(expr) || EFFECTS_READ.test(expr);
204
204
  }
205
205
  function resolveGuardRead(expr, ctx) {
206
206
  if (expr === "$self") return selfGdr(ctx.instance);
207
207
  if (expr === "$now") return ctx.now;
208
- const stateRead = STATE_READ.exec(expr);
209
- if (stateRead !== null) {
210
- const value = (ctx.instance.state ?? []).find((s) => s.name === stateRead[1])?.value;
211
- return stateRead[2] !== void 0 ? getPath(value, stateRead[2]) : value;
208
+ const fieldRead = FIELD_READ.exec(expr);
209
+ if (fieldRead !== null) {
210
+ const value = (ctx.instance.fields ?? []).find((s) => s.name === fieldRead[1])?.value;
211
+ return fieldRead[2] !== void 0 ? getPath(value, fieldRead[2]) : value;
212
212
  }
213
213
  const effectsRead = EFFECTS_READ.exec(expr);
214
214
  if (effectsRead !== null) {
@@ -216,7 +216,7 @@ function resolveGuardRead(expr, ctx) {
216
216
  return effectsRead[2] !== void 0 ? getPath(outputs, effectsRead[2]) : outputs;
217
217
  }
218
218
  throw new Error(
219
- `Guard read "${expr}" is not a supported deploy-time value \u2014 use "$self", "$now", "$state.<name>[.path]", or "$effects['<name>'][.path]" (guards store resolved values; the lake cannot see $state or $effects)`
219
+ `Guard read "${expr}" is not a supported deploy-time value \u2014 use "$self", "$now", "$fields.<name>[.path]", or "$effects['<name>'][.path]" (guards store resolved values; the lake cannot see $fields or $effects)`
220
220
  );
221
221
  }
222
222
  function resolveIdRefTarget(expr, ctx) {
@@ -266,8 +266,8 @@ function resolveMetadata(metadata, ctx) {
266
266
  }
267
267
  function validateDefinition(definition) {
268
268
  const v2 = createDefinitionValidator();
269
- for (const entry of definition.state ?? [])
270
- v2.checkEntry(entry, `workflow.state "${entry.name}"`);
269
+ for (const entry of definition.fields ?? [])
270
+ v2.checkEntry(entry, `workflow.fields "${entry.name}"`);
271
271
  for (const [name, groq] of Object.entries(definition.predicates ?? {}))
272
272
  v2.checkCondition(groq, `predicate "${name}"`);
273
273
  for (const stage of definition.stages)
@@ -289,7 +289,7 @@ function createDefinitionValidator() {
289
289
  }
290
290
  }, rejectTypeScan = (groq, where) => {
291
291
  /\*\s*\[\s*_type\b/.test(groq) && errors.push(
292
- ` \xB7 ${where}: condition scans by \`_type\` \u2014 that's a discovery query, not a predicate. Conditions evaluate against the in-memory snapshot (instance + ancestors + state-declared docs). To bring extra docs in scope, declare a \`doc.ref\` (or \`doc.refs\`) state entry on the workflow or this stage. For lake scans like "all articles in this release", use \`subworkflows.forEach\` instead.`
292
+ ` \xB7 ${where}: condition scans by \`_type\` \u2014 that's a discovery query, not a predicate. Conditions evaluate against the in-memory snapshot (instance + ancestors + field-declared docs). To bring extra docs in scope, declare a \`doc.ref\` (or \`doc.refs\`) field entry on the workflow or this stage. For lake scans like "all articles in this release", use \`subworkflows.forEach\` instead.`
293
293
  );
294
294
  };
295
295
  return { errors, tryParse, checkCondition: (groq, where) => {
@@ -298,13 +298,13 @@ function createDefinitionValidator() {
298
298
  entry.source.type === "query" && tryParse(entry.source.query, `${label}.query`);
299
299
  }, checkGuardRead: (expr, where) => {
300
300
  isGuardReadExpr(expr) || errors.push(
301
- ` \xB7 ${where}: guard read "${expr}" is not a supported deploy-time value \u2014 use "$self", "$now", "$state.<name>[.path]", or "$effects['<name>'][.path]" (guards store resolved values; the lake cannot see $state or $effects)`
301
+ ` \xB7 ${where}: guard read "${expr}" is not a supported deploy-time value \u2014 use "$self", "$now", "$fields.<name>[.path]", or "$effects['<name>'][.path]" (guards store resolved values; the lake cannot see $fields or $effects)`
302
302
  );
303
303
  } };
304
304
  }
305
305
  function validateStage(v2, stage) {
306
- for (const entry of stage.state ?? [])
307
- v2.checkEntry(entry, `stage "${stage.name}".state "${entry.name}"`);
306
+ for (const entry of stage.fields ?? [])
307
+ v2.checkEntry(entry, `stage "${stage.name}".fields "${entry.name}"`);
308
308
  for (const guard of stage.guards ?? [])
309
309
  validateGuardReads(v2, stage.name, guard);
310
310
  for (const t of stage.transitions ?? []) {
@@ -324,8 +324,8 @@ function validateGuardReads(v2, stageName, guard) {
324
324
  }
325
325
  function validateTask(v2, stageName, task) {
326
326
  const where = `stage "${stageName}" task "${task.name}"`;
327
- for (const entry of task.state ?? [])
328
- v2.checkEntry(entry, `${where}.state "${entry.name}"`);
327
+ for (const entry of task.fields ?? [])
328
+ v2.checkEntry(entry, `${where}.fields "${entry.name}"`);
329
329
  task.filter !== void 0 && v2.checkCondition(task.filter, `${where}.filter`), task.completeWhen !== void 0 && v2.checkCondition(task.completeWhen, `${where}.completeWhen`), task.failWhen !== void 0 && v2.checkCondition(task.failWhen, `${where}.failWhen`);
330
330
  for (const [name, groq] of Object.entries(task.requirements ?? {}))
331
331
  v2.checkCondition(groq, `${where}.requirements "${name}"`);
@@ -497,7 +497,7 @@ function openStage(instance) {
497
497
  return findOpenStageEntry(instance);
498
498
  }
499
499
  function assigneesOf(stage, taskName) {
500
- return (stage?.tasks.find((t) => t.name === taskName)?.state ?? []).filter((s) => s._type === "assignees").flatMap((s) => s.value);
500
+ return (stage?.tasks.find((t) => t.name === taskName)?.fields ?? []).filter((s) => s._type === "assignees").flatMap((s) => s.value);
501
501
  }
502
502
  function isResolved(status) {
503
503
  return status === "done" || status === "skipped";
@@ -610,17 +610,17 @@ class ActionParamsInvalidError extends Error {
610
610
  ${lines}`), this.name = "ActionParamsInvalidError", this.action = args.action, this.task = args.task, this.issues = args.issues;
611
611
  }
612
612
  }
613
- class RequiredStateNotProvidedError extends Error {
613
+ class RequiredFieldNotProvidedError extends Error {
614
614
  definition;
615
615
  missing;
616
616
  constructor(args) {
617
617
  const lines = args.missing.map((m) => ` - ${m.name} (${m.type})`).join(`
618
618
  `), where = args.definition !== void 0 ? ` for workflow "${args.definition}"` : "";
619
619
  super(
620
- `Required init state${where} was not provided:
620
+ `Required init fields${where} was not provided:
621
621
  ${lines}
622
- Provide each via \`initialState\` when starting standalone, or via the parent's \`subworkflows.with\` when spawned.`
623
- ), this.name = "RequiredStateNotProvidedError", args.definition !== void 0 && (this.definition = args.definition), this.missing = args.missing;
622
+ Provide each via \`initialFields\` when starting standalone, or via the parent's \`subworkflows.with\` when spawned.`
623
+ ), this.name = "RequiredFieldNotProvidedError", args.definition !== void 0 && (this.definition = args.definition), this.missing = args.missing;
624
624
  }
625
625
  }
626
626
  class WorkflowStateDivergedError extends Error {
@@ -663,15 +663,15 @@ function isRevisionConflict(error) {
663
663
  const { statusCode, message } = error;
664
664
  return statusCode === 409 ? !0 : typeof message == "string" && message.includes("ifRevisionId check failed");
665
665
  }
666
- class ConcurrentEditStateError extends Error {
666
+ class ConcurrentEditFieldError extends Error {
667
667
  instanceId;
668
668
  target;
669
669
  attempts;
670
670
  constructor(args) {
671
- const where = args.target.task !== void 0 ? `${args.target.task}.${args.target.state}` : args.target.state;
671
+ const where = args.target.task !== void 0 ? `${args.target.task}.${args.target.field}` : args.target.field;
672
672
  super(
673
673
  `Edit of "${args.target.scope}:${where}" (instance ${args.instanceId}) lost the optimistic-locking race ${args.attempts} attempts running \u2014 a concurrent writer kept committing first. Re-read and retry, or investigate a write storm on this instance.`
674
- ), this.name = "ConcurrentEditStateError", this.instanceId = args.instanceId, this.target = args.target, this.attempts = args.attempts;
674
+ ), this.name = "ConcurrentEditFieldError", this.instanceId = args.instanceId, this.target = args.target, this.attempts = args.attempts;
675
675
  }
676
676
  }
677
677
  class CascadeLimitError extends Error {
@@ -719,10 +719,10 @@ function collectWatchRefs(instance) {
719
719
  return [
720
720
  gdrRef(instance.workflowResource, instance._id, instance._type),
721
721
  ...instance.ancestors,
722
- ...entryDocRefs(instance.state),
723
- ...entryDocRefs(stage?.state),
724
- ...entryReleaseRefs(instance.state),
725
- ...entryReleaseRefs(stage?.state)
722
+ ...entryDocRefs(instance.fields),
723
+ ...entryDocRefs(stage?.fields),
724
+ ...entryReleaseRefs(instance.fields),
725
+ ...entryReleaseRefs(stage?.fields)
726
726
  ];
727
727
  }
728
728
  function readsRaw(ref) {
@@ -746,21 +746,21 @@ function subscriptionDocumentsForInstance(instance) {
746
746
  ...instance.perspective !== void 0 ? { perspective: instance.perspective } : {}
747
747
  };
748
748
  }
749
- function entryDocRefs(state) {
750
- return stateEntries(state).flatMap((entry) => entry._type === "doc.ref" ? isGdr(entry.value) ? [entry.value] : [] : entry._type === "doc.refs" ? Array.isArray(entry.value) ? entry.value.filter(isGdr) : [] : []);
749
+ function entryDocRefs(entries) {
750
+ return fieldEntries(entries).flatMap((entry) => entry._type === "doc.ref" ? isGdr(entry.value) ? [entry.value] : [] : entry._type === "doc.refs" ? Array.isArray(entry.value) ? entry.value.filter(isGdr) : [] : []);
751
751
  }
752
- function entryReleaseRefs(state) {
753
- return stateEntries(state).flatMap(
752
+ function entryReleaseRefs(entries) {
753
+ return fieldEntries(entries).flatMap(
754
754
  (entry) => entry._type === "release.ref" && isGdr(entry.value) ? [entry.value] : []
755
755
  );
756
756
  }
757
- function entrySubjectRefs(state) {
758
- return stateEntries(state).flatMap(
757
+ function entrySubjectRefs(entries) {
758
+ return fieldEntries(entries).flatMap(
759
759
  (entry) => (entry._type === "doc.ref" || entry._type === "release.ref") && isGdr(entry.value) ? [entry.value] : []
760
760
  );
761
761
  }
762
- function stateEntries(state) {
763
- return Array.isArray(state) ? state.filter(
762
+ function fieldEntries(entries) {
763
+ return Array.isArray(entries) ? entries.filter(
764
764
  (entry) => !!entry && typeof entry == "object"
765
765
  ) : [];
766
766
  }
@@ -806,8 +806,8 @@ async function readDoc(client, id, perspective) {
806
806
  function resourceFromParsed(parsed) {
807
807
  return parsed.scheme === "dataset" ? { type: "dataset", id: `${parsed.projectId}.${parsed.dataset}` } : { type: parsed.scheme, id: parsed.resourceId ?? "" };
808
808
  }
809
- function collectEntryDocUris(resolvedStateEntries) {
810
- return entryDocRefs(resolvedStateEntries).map((ref) => ref.id);
809
+ function collectEntryDocUris(resolvedFieldEntries) {
810
+ return entryDocRefs(resolvedFieldEntries).map((ref) => ref.id);
811
811
  }
812
812
  const resourceKey = (r) => `${r.type}.${r.id}`;
813
813
  function guardsForResource(client) {
@@ -825,8 +825,8 @@ function verdictGuardsForInstance(client, instanceId) {
825
825
  }
826
826
  async function guardsForInstance(args) {
827
827
  const { client, clientForGdr, instance } = args, stateUris = [
828
- ...collectEntryDocUris(instance.state),
829
- ...instance.stages.flatMap((stage) => collectEntryDocUris(stage.state))
828
+ ...collectEntryDocUris(instance.fields),
829
+ ...instance.stages.flatMap((stage) => collectEntryDocUris(stage.fields))
830
830
  ], clients = resourceClientMap(
831
831
  instance.workflowResource,
832
832
  client,
@@ -858,16 +858,16 @@ function guardIdRefs(definition) {
858
858
  );
859
859
  }
860
860
  function staticIdRefGdr(idRef, stage, definition) {
861
- const read = /^\$state\.([\w-]+)/.exec(idRef);
861
+ const read = /^\$fields\.([\w-]+)/.exec(idRef);
862
862
  if (read === null) return;
863
863
  const source = entriesInScope(stage, definition).find((e) => e.name === read[1])?.source;
864
864
  return source?.type === "literal" ? gdrFromValue(source.value) : void 0;
865
865
  }
866
866
  function entriesInScope(stage, definition) {
867
867
  return [
868
- ...definition.state ?? [],
869
- ...stage.state ?? [],
870
- ...(stage.tasks ?? []).flatMap((task) => task.state ?? [])
868
+ ...definition.fields ?? [],
869
+ ...stage.fields ?? [],
870
+ ...(stage.tasks ?? []).flatMap((task) => task.fields ?? [])
871
871
  ];
872
872
  }
873
873
  function gdrFromValue(value) {
@@ -1017,15 +1017,15 @@ async function runGroq(groq, params, snapshot) {
1017
1017
  const tree = parse(groq, { params });
1018
1018
  return (await evaluate(tree, { dataset: snapshot.docs, params })).get();
1019
1019
  }
1020
- class StateValueShapeError extends Error {
1020
+ class FieldValueShapeError extends Error {
1021
1021
  entryType;
1022
1022
  entryName;
1023
1023
  issues;
1024
1024
  constructor(args) {
1025
1025
  const issueText = args.issues.join("; ");
1026
1026
  super(
1027
- `State entry ${args.mode} shape invalid for "${args.entryName}" (${args.entryType}): ${issueText}`
1028
- ), this.name = "StateValueShapeError", this.entryType = args.entryType, this.entryName = args.entryName, this.issues = args.issues;
1027
+ `Field entry ${args.mode} shape invalid for "${args.entryName}" (${args.entryType}): ${issueText}`
1028
+ ), this.name = "FieldValueShapeError", this.entryType = args.entryType, this.entryName = args.entryName, this.issues = args.issues;
1029
1029
  }
1030
1030
  }
1031
1031
  const GdrShape = v.looseObject({
@@ -1092,35 +1092,35 @@ const GdrShape = v.looseObject({
1092
1092
  function isAppendable(entryType) {
1093
1093
  return entryType in itemSchemas;
1094
1094
  }
1095
- function validateStateValue(args) {
1095
+ function validateFieldValue(args) {
1096
1096
  const schema = valueSchemas[args.entryType];
1097
1097
  if (schema === void 0)
1098
- throw new StateValueShapeError({
1098
+ throw new FieldValueShapeError({
1099
1099
  entryType: args.entryType,
1100
1100
  entryName: args.entryName,
1101
- issues: [`unknown state entry type ${args.entryType}`],
1101
+ issues: [`unknown field entry type ${args.entryType}`],
1102
1102
  mode: "value"
1103
1103
  });
1104
1104
  const result = v.safeParse(schema, args.value);
1105
1105
  if (!result.success)
1106
- throw new StateValueShapeError({
1106
+ throw new FieldValueShapeError({
1107
1107
  entryType: args.entryType,
1108
1108
  entryName: args.entryName,
1109
1109
  issues: formatIssues(result.issues),
1110
1110
  mode: "value"
1111
1111
  });
1112
1112
  }
1113
- function validateStateAppendItem(args) {
1113
+ function validateFieldAppendItem(args) {
1114
1114
  if (!isAppendable(args.entryType))
1115
- throw new StateValueShapeError({
1115
+ throw new FieldValueShapeError({
1116
1116
  entryType: args.entryType,
1117
1117
  entryName: args.entryName,
1118
- issues: [`state entry type ${args.entryType} does not support append`],
1118
+ issues: [`field entry type ${args.entryType} does not support append`],
1119
1119
  mode: "item"
1120
1120
  });
1121
1121
  const schema = itemSchemas[args.entryType], result = v.safeParse(schema, args.item);
1122
1122
  if (!result.success)
1123
- throw new StateValueShapeError({
1123
+ throw new FieldValueShapeError({
1124
1124
  entryType: args.entryType,
1125
1125
  entryName: args.entryName,
1126
1126
  issues: formatIssues(result.issues),
@@ -1133,7 +1133,7 @@ function formatIssues(issues) {
1133
1133
  return `${keys.length > 0 ? `at ${keys.join(".")}: ` : ""}${i.message}`;
1134
1134
  });
1135
1135
  }
1136
- function derivePerspectiveFromState(entries) {
1136
+ function derivePerspectiveFromFields(entries) {
1137
1137
  if (entries !== void 0) {
1138
1138
  for (const entry of entries)
1139
1139
  if (entry._type === "release.ref" && entry.value !== null) {
@@ -1143,24 +1143,24 @@ function derivePerspectiveFromState(entries) {
1143
1143
  }
1144
1144
  }
1145
1145
  }
1146
- async function resolveDeclaredState(args) {
1147
- const { entryDefs, initialState, ctx, randomKey: randomKey2 } = args;
1146
+ async function resolveDeclaredFields(args) {
1147
+ const { entryDefs, initialFields, ctx, randomKey: randomKey2 } = args;
1148
1148
  if (entryDefs === void 0 || entryDefs.length === 0) return [];
1149
- assertRequiredInitProvided(entryDefs, initialState, ctx.definitionName);
1149
+ assertRequiredInitProvided(entryDefs, initialFields, ctx.definitionName);
1150
1150
  const out = [];
1151
1151
  for (const entry of entryDefs) {
1152
- const scopedCtx = { ...ctx, resolvedState: out };
1153
- out.push(await resolveOneEntry(entry, initialState, scopedCtx, randomKey2));
1152
+ const scopedCtx = { ...ctx, resolvedFields: out };
1153
+ out.push(await resolveOneEntry(entry, initialFields, scopedCtx, randomKey2));
1154
1154
  }
1155
1155
  return out;
1156
1156
  }
1157
- function assertRequiredInitProvided(entryDefs, initialState, definitionName) {
1157
+ function assertRequiredInitProvided(entryDefs, initialFields, definitionName) {
1158
1158
  const missing = entryDefs.filter((entry) => entry.required === !0 && entry.source.type === "init").filter((entry) => {
1159
- const match = initialState.find((s) => s.name === entry.name && s.type === entry.type);
1159
+ const match = initialFields.find((s) => s.name === entry.name && s.type === entry.type);
1160
1160
  return match === void 0 || match.value === void 0 || match.value === null;
1161
1161
  }).map((entry) => ({ name: entry.name, type: entry.type }));
1162
1162
  if (missing.length !== 0)
1163
- throw new RequiredStateNotProvidedError({
1163
+ throw new RequiredFieldNotProvidedError({
1164
1164
  ...definitionName !== void 0 ? { definition: definitionName } : {},
1165
1165
  missing
1166
1166
  });
@@ -1174,18 +1174,18 @@ const ARRAY_SLOT_TYPES = /* @__PURE__ */ new Set([
1174
1174
  function defaultEntryValue(entryType) {
1175
1175
  return ARRAY_SLOT_TYPES.has(entryType) ? [] : null;
1176
1176
  }
1177
- function resolveInitValue(entry, initialState, defaultValue) {
1178
- const initMatch = initialState.find((s) => s.name === entry.name && s.type === entry.type);
1177
+ function resolveInitValue(entry, initialFields, defaultValue) {
1178
+ const initMatch = initialFields.find((s) => s.name === entry.name && s.type === entry.type);
1179
1179
  return initMatch === void 0 ? defaultValue : (assertInitValueShape(entry, initMatch.value), initMatch.value);
1180
1180
  }
1181
- function resolveStateReadValue(source, ctx, defaultValue) {
1182
- const target = (source.scope === "workflow" ? ctx.workflowState ?? [] : ctx.resolvedState ?? []).find((s) => s.name === source.state), targetValue = target === void 0 ? void 0 : target.value;
1181
+ function resolveFieldReadValue(source, ctx, defaultValue) {
1182
+ const target = (source.scope === "workflow" ? ctx.workflowFields ?? [] : ctx.resolvedFields ?? []).find((s) => s.name === source.field), targetValue = target === void 0 ? void 0 : target.value;
1183
1183
  return (source.path !== void 0 ? getPath(targetValue, source.path) : targetValue) ?? defaultValue;
1184
1184
  }
1185
1185
  async function resolveQueryValue(entry, source, ctx, client, defaultValue) {
1186
1186
  const params = paramsForLake({
1187
1187
  self: ctx.selfId ?? null,
1188
- state: stateMapFromResolved(ctx.resolvedState ?? []),
1188
+ fields: fieldMapFromResolved(ctx.resolvedFields ?? []),
1189
1189
  stage: ctx.stageName ?? null,
1190
1190
  task: ctx.taskName ?? null,
1191
1191
  now: ctx.now,
@@ -1201,9 +1201,9 @@ async function resolveQueryValue(entry, source, ctx, client, defaultValue) {
1201
1201
  );
1202
1202
  }
1203
1203
  }
1204
- async function resolveEntryValue(entry, initialState, ctx, defaultValue) {
1204
+ async function resolveEntryValue(entry, initialFields, ctx, defaultValue) {
1205
1205
  const source = entry.source;
1206
- return source.type === "init" ? resolveInitValue(entry, initialState, defaultValue) : source.type === "literal" ? source.value ?? defaultValue : source.type === "stateRead" ? resolveStateReadValue(source, ctx, defaultValue) : source.type === "query" && ctx.client !== void 0 ? resolveQueryValue(entry, source, ctx, ctx.client, defaultValue) : defaultValue;
1206
+ return source.type === "init" ? resolveInitValue(entry, initialFields, defaultValue) : source.type === "literal" ? source.value ?? defaultValue : source.type === "fieldRead" ? resolveFieldReadValue(source, ctx, defaultValue) : source.type === "query" && ctx.client !== void 0 ? resolveQueryValue(entry, source, ctx, ctx.client, defaultValue) : defaultValue;
1207
1207
  }
1208
1208
  function buildResolvedEntry(entry, value, _key, now) {
1209
1209
  const titleProp = entry.title !== void 0 ? { title: entry.title } : {}, descriptionProp = entry.description !== void 0 ? { description: entry.description } : {};
@@ -1224,36 +1224,36 @@ function buildResolvedEntry(entry, value, _key, now) {
1224
1224
  value
1225
1225
  };
1226
1226
  }
1227
- async function resolveOneEntry(entry, initialState, ctx, randomKey2) {
1228
- const defaultValue = defaultEntryValue(entry.type), value = await resolveEntryValue(entry, initialState, ctx, defaultValue);
1229
- return validateStateValue({ entryType: entry.type, entryName: entry.name, value }), buildResolvedEntry(entry, value, randomKey2(), ctx.now);
1227
+ async function resolveOneEntry(entry, initialFields, ctx, randomKey2) {
1228
+ const defaultValue = defaultEntryValue(entry.type), value = await resolveEntryValue(entry, initialFields, ctx, defaultValue);
1229
+ return validateFieldValue({ entryType: entry.type, entryName: entry.name, value }), buildResolvedEntry(entry, value, randomKey2(), ctx.now);
1230
1230
  }
1231
- function stateMapFromResolved(entries) {
1231
+ function fieldMapFromResolved(entries) {
1232
1232
  const out = {};
1233
1233
  for (const s of entries) out[s.name] = s.value;
1234
1234
  return out;
1235
1235
  }
1236
1236
  function assertInitValueShape(entry, value) {
1237
1237
  if (entry.type === "doc.ref") {
1238
- assertGdrShape(value, `state entry "${entry.name}" (doc.ref)`);
1238
+ assertGdrShape(value, `field entry "${entry.name}" (doc.ref)`);
1239
1239
  return;
1240
1240
  }
1241
1241
  if (entry.type === "release.ref") {
1242
- assertGdrShape(value, `state entry "${entry.name}" (release.ref)`);
1242
+ assertGdrShape(value, `field entry "${entry.name}" (release.ref)`);
1243
1243
  const v2 = value;
1244
1244
  if (typeof v2.releaseName != "string" || v2.releaseName.length === 0)
1245
1245
  throw new Error(
1246
- `Invalid init value for state entry "${entry.name}" (release.ref): \`releaseName\` must be a non-empty string. Got ${JSON.stringify(v2.releaseName)}.`
1246
+ `Invalid init value for field entry "${entry.name}" (release.ref): \`releaseName\` must be a non-empty string. Got ${JSON.stringify(v2.releaseName)}.`
1247
1247
  );
1248
1248
  return;
1249
1249
  }
1250
1250
  if (entry.type === "doc.refs") {
1251
1251
  if (!Array.isArray(value))
1252
1252
  throw new Error(
1253
- `Invalid init value for state entry "${entry.name}" (doc.refs): expected an array of GDRs, got ${typeof value}.`
1253
+ `Invalid init value for field entry "${entry.name}" (doc.refs): expected an array of GDRs, got ${typeof value}.`
1254
1254
  );
1255
1255
  for (const [i, item] of value.entries())
1256
- assertGdrShape(item, `state entry "${entry.name}" (doc.refs) item [${i}]`);
1256
+ assertGdrShape(item, `field entry "${entry.name}" (doc.refs) item [${i}]`);
1257
1257
  }
1258
1258
  }
1259
1259
  function assertGdrShape(value, context) {
@@ -1312,12 +1312,12 @@ async function loadContext(client, instanceId, options) {
1312
1312
  return { client, clientForGdr, clock, now: clock(), instance, definition, snapshot };
1313
1313
  }
1314
1314
  async function ctxConditionParams(ctx, opts) {
1315
- const base = buildParams({ instance: ctx.instance, now: ctx.now, snapshot: ctx.snapshot }), state = {
1316
- ...base.state,
1317
- ...scopedStateOverlay(ctx.instance, ctx.snapshot, opts?.taskName)
1315
+ const base = buildParams({ instance: ctx.instance, now: ctx.now, snapshot: ctx.snapshot }), fields = {
1316
+ ...base.fields,
1317
+ ...scopedFieldOverlay(ctx.instance, ctx.snapshot, opts?.taskName)
1318
1318
  }, params = {
1319
1319
  ...base,
1320
- state,
1320
+ fields,
1321
1321
  actor: opts?.actor,
1322
1322
  assigned: opts?.taskName !== void 0 ? assignedFor(ctx.instance, opts.taskName, opts?.actor, ctx.definition.roleAliases) : !1,
1323
1323
  ...opts?.vars
@@ -1356,11 +1356,11 @@ function findStage(definition, stageName) {
1356
1356
  throw new Error(`Stage "${stageName}" not found in definition ${definition.name}`);
1357
1357
  return stage;
1358
1358
  }
1359
- async function resolveStageStateEntries(args) {
1360
- const { client, instance, stage, now, initialState } = args;
1361
- return resolveDeclaredState({
1362
- entryDefs: stage.state,
1363
- initialState: initialState ?? [],
1359
+ async function resolveStageFieldEntries(args) {
1360
+ const { client, instance, stage, now, initialFields } = args;
1361
+ return resolveDeclaredFields({
1362
+ entryDefs: stage.fields,
1363
+ initialFields: initialFields ?? [],
1364
1364
  ctx: {
1365
1365
  client,
1366
1366
  now,
@@ -1368,19 +1368,19 @@ async function resolveStageStateEntries(args) {
1368
1368
  tag: instance.tag,
1369
1369
  stageName: stage.name,
1370
1370
  workflowResource: instance.workflowResource,
1371
- // Allow stage-scope entries' `source: { type: "stateRead", scope:
1372
- // "workflow", ... }` to see the already-resolved workflow-scope state.
1373
- workflowState: instance.state ?? [],
1371
+ // Allow stage-scope entries' `source: { type: "fieldRead", scope:
1372
+ // "workflow", ... }` to see the already-resolved workflow-scope fields.
1373
+ workflowFields: instance.fields ?? [],
1374
1374
  ...instance.perspective !== void 0 ? { perspective: instance.perspective } : {}
1375
1375
  },
1376
1376
  randomKey
1377
1377
  });
1378
1378
  }
1379
- async function resolveTaskStateEntries(args) {
1379
+ async function resolveTaskFieldEntries(args) {
1380
1380
  const { client, instance, stage, task, now } = args;
1381
- return resolveDeclaredState({
1382
- entryDefs: task.state,
1383
- initialState: [],
1381
+ return resolveDeclaredFields({
1382
+ entryDefs: task.fields,
1383
+ initialFields: [],
1384
1384
  ctx: {
1385
1385
  client,
1386
1386
  now,
@@ -1389,7 +1389,7 @@ async function resolveTaskStateEntries(args) {
1389
1389
  stageName: stage.name,
1390
1390
  workflowResource: instance.workflowResource,
1391
1391
  taskName: task.name,
1392
- workflowState: instance.state ?? [],
1392
+ workflowFields: instance.fields ?? [],
1393
1393
  ...instance.perspective !== void 0 ? { perspective: instance.perspective } : {}
1394
1394
  },
1395
1395
  randomKey
@@ -1471,15 +1471,15 @@ function stageTransitionHistory(args) {
1471
1471
  function startMutation(instance) {
1472
1472
  return {
1473
1473
  currentStage: instance.currentStage,
1474
- // Deep-ish copy. Per-scope state entry arrays need their own copies
1474
+ // Deep-ish copy. Per-scope field entry arrays need their own copies
1475
1475
  // so ops can mutate without leaking into the source.
1476
- state: (instance.state ?? []).map((s) => ({ ...s })),
1476
+ fields: (instance.fields ?? []).map((s) => ({ ...s })),
1477
1477
  stages: instance.stages.map((s) => ({
1478
1478
  ...s,
1479
- state: (s.state ?? []).map((entry) => ({ ...entry })),
1479
+ fields: (s.fields ?? []).map((entry) => ({ ...entry })),
1480
1480
  tasks: s.tasks.map((t) => ({
1481
1481
  ...t,
1482
- ...t.state !== void 0 ? { state: t.state.map((entry) => ({ ...entry })) } : {}
1482
+ ...t.fields !== void 0 ? { fields: t.fields.map((entry) => ({ ...entry })) } : {}
1483
1483
  }))
1484
1484
  })),
1485
1485
  pendingEffects: [...instance.pendingEffects],
@@ -1495,7 +1495,7 @@ function startMutation(instance) {
1495
1495
  function instanceStateFields(src) {
1496
1496
  const fields = {
1497
1497
  currentStage: src.currentStage,
1498
- state: src.state,
1498
+ fields: src.fields,
1499
1499
  stages: src.stages,
1500
1500
  pendingEffects: src.pendingEffects,
1501
1501
  effectHistory: src.effectHistory,
@@ -1508,7 +1508,7 @@ function materializeInstance(base, mutation) {
1508
1508
  return {
1509
1509
  ...base,
1510
1510
  currentStage: mutation.currentStage,
1511
- state: mutation.state,
1511
+ fields: mutation.fields,
1512
1512
  stages: mutation.stages,
1513
1513
  effectsContext: mutation.effectsContext
1514
1514
  };
@@ -1630,7 +1630,7 @@ function buildInstanceBase(args) {
1630
1630
  definition: args.definitionName,
1631
1631
  pinnedVersion: args.pinnedVersion,
1632
1632
  definitionSnapshot: JSON.stringify(args.definition),
1633
- state: args.state,
1633
+ fields: args.fields,
1634
1634
  effectsContext: args.effectsContext,
1635
1635
  ancestors: args.ancestors,
1636
1636
  ...perspective !== void 0 ? { perspective } : {},
@@ -1651,12 +1651,16 @@ function buildInstanceBase(args) {
1651
1651
  lastChangedAt: now
1652
1652
  };
1653
1653
  }
1654
- const MAX_SPAWN_DEPTH = 6, SUBWORKFLOWS_ALL_DONE = "count($subworkflows[status != 'done']) == 0", FAIL_WHEN_SYSTEM_ID = "engine.failWhen", COMPLETE_WHEN_SYSTEM_ID = "engine.completeWhen";
1654
+ const ENGINE_ACTOR_ID_PREFIX = "engine.";
1655
+ function engineSystemActor(name) {
1656
+ return { kind: "system", id: `${ENGINE_ACTOR_ID_PREFIX}${name}` };
1657
+ }
1658
+ function isEngineActor(actor) {
1659
+ return actor.kind === "system" && actor.id.startsWith(ENGINE_ACTOR_ID_PREFIX);
1660
+ }
1661
+ const MAX_SPAWN_DEPTH = 6, SUBWORKFLOWS_ALL_DONE = "count($subworkflows[status != 'done']) == 0";
1655
1662
  function gateActor(outcome) {
1656
- return {
1657
- kind: "system",
1658
- id: outcome === "failed" ? FAIL_WHEN_SYSTEM_ID : COMPLETE_WHEN_SYSTEM_ID
1659
- };
1663
+ return engineSystemActor(outcome === "failed" ? "failWhen" : "completeWhen");
1660
1664
  }
1661
1665
  function effectiveCompleteWhen(task) {
1662
1666
  return task.completeWhen ?? (task.subworkflows !== void 0 ? SUBWORKFLOWS_ALL_DONE : void 0);
@@ -1688,7 +1692,7 @@ async function spawnSubworkflows(ctx, mutation, task, sub, actor) {
1688
1692
  ...actor ? { actor } : {}
1689
1693
  }), { rows, discoveryResource } = await resolveSpawnRows(ctx, sub), effectsContext = await resolveContextHandoff(ctx, sub, parentScope), refs = [];
1690
1694
  for (const row of rows) {
1691
- const initialState = await projectRowState(
1695
+ const initialFields = await projectRowFields(
1692
1696
  ctx,
1693
1697
  sub,
1694
1698
  definition,
@@ -1699,7 +1703,7 @@ async function spawnSubworkflows(ctx, mutation, task, sub, actor) {
1699
1703
  client: ctx.client,
1700
1704
  parent: ctx.instance,
1701
1705
  definition,
1702
- initialState,
1706
+ initialFields,
1703
1707
  effectsContext,
1704
1708
  actor,
1705
1709
  now
@@ -1712,7 +1716,7 @@ async function resolveSpawnRows(ctx, sub) {
1712
1716
  const params = buildParams({ instance: ctx.instance, now: ctx.now, snapshot: ctx.snapshot }), groq = sub.forEach;
1713
1717
  let value, discoveryResource;
1714
1718
  if (groq.includes("*")) {
1715
- const routingUri = entrySubjectRefs(ctx.instance.state)[0]?.id, client = clientForDiscovery(ctx.client, ctx.clientForGdr, routingUri);
1719
+ const routingUri = entrySubjectRefs(ctx.instance.fields)[0]?.id, client = clientForDiscovery(ctx.client, ctx.clientForGdr, routingUri);
1716
1720
  client !== ctx.client && routingUri !== void 0 && (discoveryResource = resourceFromGdrUri(routingUri)), value = await discoverItems({
1717
1721
  client,
1718
1722
  groq,
@@ -1728,13 +1732,13 @@ async function resolveSpawnRows(ctx, sub) {
1728
1732
  }
1729
1733
  return Array.isArray(value) ? { rows: value, discoveryResource } : value == null ? { rows: [], discoveryResource } : { rows: [value], discoveryResource };
1730
1734
  }
1731
- async function projectRowState(ctx, sub, childDefinition, parentScope, row, discoveryResource) {
1735
+ async function projectRowFields(ctx, sub, childDefinition, parentScope, row, discoveryResource) {
1732
1736
  const out = [];
1733
1737
  for (const [name, groq] of Object.entries(sub.with ?? {})) {
1734
- const declared = (childDefinition.state ?? []).find((e) => e.name === name);
1738
+ const declared = (childDefinition.fields ?? []).find((e) => e.name === name);
1735
1739
  if (declared === void 0)
1736
1740
  throw new Error(
1737
- `subworkflows.with["${name}"]: subworkflow "${childDefinition.name}" declares no state entry "${name}"`
1741
+ `subworkflows.with["${name}"]: subworkflow "${childDefinition.name}" declares no field entry "${name}"`
1738
1742
  );
1739
1743
  const raw = await runGroq(groq, { ...parentScope, row }, ctx.snapshot), value = canonicaliseSpawnValue(declared.type, raw, {
1740
1744
  parentResource: ctx.instance.workflowResource,
@@ -1789,15 +1793,15 @@ async function resolveDefinitionRef(client, ref, tag) {
1789
1793
  ) ?? null;
1790
1794
  }
1791
1795
  async function prepareChildInstance(args) {
1792
- const { client, parent, definition, initialState, effectsContext, actor, now } = args, childTag = parent.tag, workflowResource = parent.workflowResource, childDocId = `${childTag}.wf-instance.${randomKey()}`, childRef = { id: gdrFromResource(workflowResource, childDocId), type: WORKFLOW_INSTANCE_TYPE }, ancestors = [
1796
+ const { client, parent, definition, initialFields, effectsContext, actor, now } = args, childTag = parent.tag, workflowResource = parent.workflowResource, childDocId = `${childTag}.wf-instance.${randomKey()}`, childRef = { id: gdrFromResource(workflowResource, childDocId), type: WORKFLOW_INSTANCE_TYPE }, ancestors = [
1793
1797
  ...parent.ancestors,
1794
1798
  {
1795
1799
  id: selfGdr(parent),
1796
1800
  type: WORKFLOW_INSTANCE_TYPE
1797
1801
  }
1798
- ], inheritedPerspective = parent.perspective, childState = await resolveDeclaredState({
1799
- entryDefs: definition.state,
1800
- initialState,
1802
+ ], inheritedPerspective = parent.perspective, childFields = await resolveDeclaredFields({
1803
+ entryDefs: definition.fields,
1804
+ initialFields,
1801
1805
  ctx: {
1802
1806
  client,
1803
1807
  now,
@@ -1808,7 +1812,7 @@ async function prepareChildInstance(args) {
1808
1812
  ...inheritedPerspective !== void 0 ? { perspective: inheritedPerspective } : {}
1809
1813
  },
1810
1814
  randomKey
1811
- }), childPerspective = derivePerspectiveFromState(childState) ?? inheritedPerspective, effectsContextEntries = Object.entries(effectsContext).map(
1815
+ }), childPerspective = derivePerspectiveFromFields(childFields) ?? inheritedPerspective, effectsContextEntries = Object.entries(effectsContext).map(
1812
1816
  ([key, value]) => {
1813
1817
  if (typeof value == "object" && value !== null && "id" in value && "type" in value) {
1814
1818
  if (!isGdrUri(value.id))
@@ -1827,7 +1831,7 @@ async function prepareChildInstance(args) {
1827
1831
  definitionName: definition.name,
1828
1832
  pinnedVersion: definition.version,
1829
1833
  definition,
1830
- state: childState,
1834
+ fields: childFields,
1831
1835
  effectsContext: effectsContextEntries,
1832
1836
  ancestors,
1833
1837
  perspective: childPerspective,
@@ -1992,15 +1996,15 @@ function resolveStaticSource(src, ctx) {
1992
1996
  return { handled: !1 };
1993
1997
  }
1994
1998
  }
1995
- const STATE_OP_TYPES = [
1996
- "state.set",
1997
- "state.unset",
1998
- "state.append",
1999
- "state.updateWhere",
2000
- "state.removeWhere"
1999
+ const FIELD_OP_TYPES = [
2000
+ "field.set",
2001
+ "field.unset",
2002
+ "field.append",
2003
+ "field.updateWhere",
2004
+ "field.removeWhere"
2001
2005
  ];
2002
- function isStateOp(summary) {
2003
- return STATE_OP_TYPES.includes(summary.opType);
2006
+ function isFieldOp(summary) {
2007
+ return FIELD_OP_TYPES.includes(summary.opType);
2004
2008
  }
2005
2009
  function validateActionParams(action, taskName, callerParams) {
2006
2010
  const declared = action.params ?? [], params = callerParams ?? {}, issues = [];
@@ -2073,23 +2077,23 @@ function opAppliedEntry(args) {
2073
2077
  }
2074
2078
  function applyOp(op, ctx) {
2075
2079
  switch (op.type) {
2076
- case "state.set":
2077
- return applyStateSet(op, ctx);
2078
- case "state.unset":
2079
- return applyStateUnset(op, ctx);
2080
- case "state.append":
2081
- return applyStateAppend(op, ctx);
2082
- case "state.updateWhere":
2083
- return applyStateUpdateWhere(op, ctx);
2084
- case "state.removeWhere":
2085
- return applyStateRemoveWhere(op, ctx);
2080
+ case "field.set":
2081
+ return applyFieldSet(op, ctx);
2082
+ case "field.unset":
2083
+ return applyFieldUnset(op, ctx);
2084
+ case "field.append":
2085
+ return applyFieldAppend(op, ctx);
2086
+ case "field.updateWhere":
2087
+ return applyFieldUpdateWhere(op, ctx);
2088
+ case "field.removeWhere":
2089
+ return applyFieldRemoveWhere(op, ctx);
2086
2090
  case "status.set":
2087
2091
  return applyStatusSet(op, ctx);
2088
2092
  }
2089
2093
  }
2090
- function applyStateSet(op, ctx) {
2094
+ function applyFieldSet(op, ctx) {
2091
2095
  const value = resolveOpSource(op.value, ctx), entry = locateEntry(ctx, op.target);
2092
- return validateStateValue({ entryType: entry._type, entryName: entry.name, value }), setEntryValue(entry, value), { opType: op.type, target: op.target, resolved: { value } };
2096
+ return validateFieldValue({ entryType: entry._type, entryName: entry.name, value }), setEntryValue(entry, value), { opType: op.type, target: op.target, resolved: { value } };
2093
2097
  }
2094
2098
  const EMPTY_BY_KIND = {
2095
2099
  "doc.refs": [],
@@ -2097,24 +2101,24 @@ const EMPTY_BY_KIND = {
2097
2101
  notes: [],
2098
2102
  assignees: []
2099
2103
  };
2100
- function applyStateUnset(op, ctx) {
2104
+ function applyFieldUnset(op, ctx) {
2101
2105
  const entry = locateEntry(ctx, op.target);
2102
2106
  return setEntryValue(entry, EMPTY_BY_KIND[entry._type] ?? null), { opType: op.type, target: op.target };
2103
2107
  }
2104
- function applyStateAppend(op, ctx) {
2108
+ function applyFieldAppend(op, ctx) {
2105
2109
  const item = resolveOpSource(op.value, ctx), entry = locateEntry(ctx, op.target);
2106
- validateStateAppendItem({ entryType: entry._type, entryName: entry.name, item });
2110
+ validateFieldAppendItem({ entryType: entry._type, entryName: entry.name, item });
2107
2111
  const current = Array.isArray(entry.value) ? entry.value : [];
2108
2112
  return setEntryValue(entry, [...current, withRowKey(item)]), { opType: op.type, target: op.target, resolved: { item } };
2109
2113
  }
2110
2114
  function withRowKey(item) {
2111
2115
  return typeof item == "object" && item !== null && !Array.isArray(item) && !("_key" in item) ? { _key: randomKey(), ...item } : item;
2112
2116
  }
2113
- function applyStateUpdateWhere(op, ctx) {
2117
+ function applyFieldUpdateWhere(op, ctx) {
2114
2118
  const entry = locateEntry(ctx, op.target), rows = requireArrayValue(entry, op), merge = resolveOpSource(op.value, ctx);
2115
2119
  if (merge === null || typeof merge != "object" || Array.isArray(merge))
2116
2120
  throw new Error(
2117
- `state.updateWhere value must resolve to an object of fields to merge (target "${op.target.state}")`
2121
+ `field.updateWhere value must resolve to an object of fields to merge (target "${op.target.field}")`
2118
2122
  );
2119
2123
  return setEntryValue(
2120
2124
  entry,
@@ -2123,7 +2127,7 @@ function applyStateUpdateWhere(op, ctx) {
2123
2127
  )
2124
2128
  ), { opType: op.type, target: op.target, resolved: { merge } };
2125
2129
  }
2126
- function applyStateRemoveWhere(op, ctx) {
2130
+ function applyFieldRemoveWhere(op, ctx) {
2127
2131
  const entry = locateEntry(ctx, op.target), rows = requireArrayValue(entry, op);
2128
2132
  return setEntryValue(
2129
2133
  entry,
@@ -2133,7 +2137,7 @@ function applyStateRemoveWhere(op, ctx) {
2133
2137
  function requireArrayValue(entry, op) {
2134
2138
  if (!Array.isArray(entry.value))
2135
2139
  throw new Error(
2136
- `${op.type} target ${op.target.scope}:"${op.target.state}" holds a non-array ${entry._type} value \u2014 where-ops operate on array entries`
2140
+ `${op.type} target ${op.target.scope}:"${op.target.field}" holds a non-array ${entry._type} value \u2014 where-ops operate on array entries`
2137
2141
  );
2138
2142
  return entry.value;
2139
2143
  }
@@ -2154,19 +2158,19 @@ function setEntryValue(entry, value) {
2154
2158
  entry.value = value;
2155
2159
  }
2156
2160
  function locateEntry(ctx, target) {
2157
- const entry = stateHost(ctx, target.scope)?.find((s) => s.name === target.state);
2161
+ const entry = fieldHost(ctx, target.scope)?.find((s) => s.name === target.field);
2158
2162
  if (entry === void 0)
2159
2163
  throw new Error(
2160
- `Op target ${target.scope}:"${target.state}" has no resolved state entry on this instance \u2014 the deployed definition and the instance state have diverged`
2164
+ `Op target ${target.scope}:"${target.field}" has no resolved field entry on this instance \u2014 the deployed definition and the instance state have diverged`
2161
2165
  );
2162
2166
  return entry;
2163
2167
  }
2164
- function stateHost(ctx, scope) {
2165
- if (scope === "workflow") return ctx.mutation.state;
2168
+ function fieldHost(ctx, scope) {
2169
+ if (scope === "workflow") return ctx.mutation.fields;
2166
2170
  const stageEntry = findOpenStageEntry(ctx.mutation);
2167
- if (scope === "stage") return stageEntry?.state;
2171
+ if (scope === "stage") return stageEntry?.fields;
2168
2172
  const task = stageEntry?.tasks.find((t) => t.name === ctx.taskName);
2169
- return task !== void 0 && task.state === void 0 && (task.state = []), task?.state;
2173
+ return task !== void 0 && task.fields === void 0 && (task.fields = []), task?.fields;
2170
2174
  }
2171
2175
  function resolveOpSource(src, ctx) {
2172
2176
  const staticValue = resolveStaticSource(src, ctx);
@@ -2176,7 +2180,7 @@ function resolveOpSource(src, ctx) {
2176
2180
  return ctx.self;
2177
2181
  case "stage":
2178
2182
  return ctx.stage;
2179
- case "stateRead": {
2183
+ case "fieldRead": {
2180
2184
  const value = readEntryFromMutation(ctx, src);
2181
2185
  return src.path !== void 0 ? getPath(value, src.path) : value;
2182
2186
  }
@@ -2187,7 +2191,7 @@ function resolveOpSource(src, ctx) {
2187
2191
  return out;
2188
2192
  }
2189
2193
  default:
2190
- throw new Error(`Source type "${src.type}" is a state-entry origin, not a value`);
2194
+ throw new Error(`Source type "${src.type}" is a field-entry origin, not a value`);
2191
2195
  }
2192
2196
  }
2193
2197
  function entryValue(entries, name) {
@@ -2196,7 +2200,7 @@ function entryValue(entries, name) {
2196
2200
  function readEntryFromMutation(ctx, src) {
2197
2201
  const scopes = src.scope !== void 0 ? [src.scope] : ["stage", "workflow"], stageEntry = findOpenStageEntry(ctx.mutation);
2198
2202
  for (const scope of scopes) {
2199
- const host = scope === "workflow" ? ctx.mutation.state : stageEntry?.state, value = entryValue(host, src.state);
2203
+ const host = scope === "workflow" ? ctx.mutation.fields : stageEntry?.fields, value = entryValue(host, src.field);
2200
2204
  if (value !== void 0) return value;
2201
2205
  }
2202
2206
  }
@@ -2228,9 +2232,9 @@ async function commitInvoke(ctx, taskName, actor) {
2228
2232
  }
2229
2233
  async function activateTask(ctx, mutation, task, entry, actor) {
2230
2234
  const now = ctx.now;
2231
- if (entry.status = "active", entry.startedAt = now, task.state !== void 0 && task.state.length > 0) {
2235
+ if (entry.status = "active", entry.startedAt = now, task.fields !== void 0 && task.fields.length > 0) {
2232
2236
  const stage = findStage(ctx.definition, mutation.currentStage);
2233
- entry.state = await resolveTaskStateEntries({
2237
+ entry.fields = await resolveTaskFieldEntries({
2234
2238
  client: ctx.client,
2235
2239
  instance: ctx.instance,
2236
2240
  stage,
@@ -2295,7 +2299,7 @@ function resolveMachineStep(mutation, task, entry, now) {
2295
2299
  stage: mutation.currentStage,
2296
2300
  to: "done",
2297
2301
  at: now,
2298
- actor: { kind: "system", id: "engine.machineStep" }
2302
+ actor: engineSystemActor("machineStep")
2299
2303
  });
2300
2304
  }
2301
2305
  async function buildStageTasks(ctx, stage) {
@@ -2335,7 +2339,7 @@ async function enterStage(ctx, mutation, nextStage, actor, at) {
2335
2339
  _key: randomKey(),
2336
2340
  name: nextStage.name,
2337
2341
  enteredAt: at,
2338
- state: await resolveStageStateEntries({
2342
+ fields: await resolveStageFieldEntries({
2339
2343
  client: ctx.client,
2340
2344
  instance: ctx.instance,
2341
2345
  stage: nextStage,
@@ -2475,7 +2479,7 @@ async function primeInitialStage(client, instanceId, actor, clientForGdr, clock)
2475
2479
  _key: randomKey(),
2476
2480
  name: stage.name,
2477
2481
  enteredAt: now,
2478
- state: await resolveStageStateEntries({ client, instance, stage, now }),
2482
+ fields: await resolveStageFieldEntries({ client, instance, stage, now }),
2479
2483
  tasks: await buildStageTasks(ctx, stage)
2480
2484
  }, committed = await client.patch(instance._id).set({
2481
2485
  stages: [initialStageEntry],
@@ -2713,10 +2717,10 @@ function effectiveEditable(baseline, override) {
2713
2717
  }
2714
2718
  function slotSites(definition, stage) {
2715
2719
  const sites = [];
2716
- for (const entry of definition.state ?? []) sites.push({ scope: "workflow", entry });
2717
- for (const entry of stage.state ?? []) sites.push({ scope: "stage", entry });
2720
+ for (const entry of definition.fields ?? []) sites.push({ scope: "workflow", entry });
2721
+ for (const entry of stage.fields ?? []) sites.push({ scope: "stage", entry });
2718
2722
  for (const task of stage.tasks ?? [])
2719
- for (const entry of task.state ?? []) sites.push({ scope: "task", task: task.name, entry });
2723
+ for (const entry of task.fields ?? []) sites.push({ scope: "task", task: task.name, entry });
2720
2724
  return sites;
2721
2725
  }
2722
2726
  function toResolvedSlot(site, stage) {
@@ -2726,7 +2730,7 @@ function toResolvedSlot(site, stage) {
2726
2730
  name: site.entry.name,
2727
2731
  type: site.entry.type,
2728
2732
  ...site.entry.title !== void 0 ? { title: site.entry.title } : {},
2729
- ref: { scope: site.scope, state: site.entry.name },
2733
+ ref: { scope: site.scope, field: site.entry.name },
2730
2734
  effective: effectiveEditable(site.entry.editable, stage.editable?.[site.entry.name])
2731
2735
  };
2732
2736
  }
@@ -2734,7 +2738,7 @@ function editableSlotsInStage(definition, stage) {
2734
2738
  return slotSites(definition, stage).filter((site) => site.entry.editable !== void 0).map((site) => toResolvedSlot(site, stage));
2735
2739
  }
2736
2740
  function editTargetMatches(slot, target) {
2737
- return slot.name !== target.state ? !1 : target.task !== void 0 ? slot.scope === "task" && slot.task === target.task : target.scope !== void 0 ? slot.scope === target.scope : !0;
2741
+ return slot.name !== target.field ? !1 : target.task !== void 0 ? slot.scope === "task" && slot.task === target.task : target.scope !== void 0 ? slot.scope === target.scope : !0;
2738
2742
  }
2739
2743
  const SCOPE_PRECEDENCE = { task: 0, stage: 1, workflow: 2 };
2740
2744
  function resolveEditTarget(args) {
@@ -2758,17 +2762,17 @@ function slotWindowOpen(instance, slot) {
2758
2762
  return status === "active" ? { open: !0 } : { open: !1, detail: `task "${slot.task}" is ${status ?? "not active"}` };
2759
2763
  }
2760
2764
  function readSlotValue(instance, slot) {
2761
- return slotStateHost(instance, slot)?.find((e) => e.name === slot.name)?.value;
2765
+ return slotFieldHost(instance, slot)?.find((e) => e.name === slot.name)?.value;
2762
2766
  }
2763
- function slotStateHost(instance, slot) {
2764
- if (slot.scope === "workflow") return instance.state;
2767
+ function slotFieldHost(instance, slot) {
2768
+ if (slot.scope === "workflow") return instance.fields;
2765
2769
  const stageEntry = findOpenStageEntry(instance);
2766
- return slot.scope === "stage" ? stageEntry?.state : stageEntry?.tasks.find((t) => t.name === slot.task)?.state;
2770
+ return slot.scope === "stage" ? stageEntry?.fields : stageEntry?.tasks.find((t) => t.name === slot.task)?.fields;
2767
2771
  }
2768
2772
  function slotProvenance(instance, ref) {
2769
2773
  let latest;
2770
2774
  for (const entry of instance.history)
2771
- entry._type === "opApplied" && (entry.target?.scope !== ref.scope || entry.target.state !== ref.state || (latest = { at: entry.at, ...entry.actor !== void 0 ? { actor: entry.actor } : {} }));
2775
+ entry._type === "opApplied" && (entry.target?.scope !== ref.scope || entry.target.field !== ref.field || (latest = { at: entry.at, ...entry.actor !== void 0 ? { actor: entry.actor } : {} }));
2772
2776
  return latest === void 0 ? {} : {
2773
2777
  ...latest.actor !== void 0 ? { setBy: latest.actor } : {},
2774
2778
  setAt: latest.at
@@ -2783,6 +2787,18 @@ function editDisabledReason(args) {
2783
2787
  if (!predicateSatisfied)
2784
2788
  return { kind: "editor-not-permitted", predicate: effective === !0 ? "true" : effective };
2785
2789
  }
2790
+ function hasItems(arr) {
2791
+ return arr !== void 0 && arr.length > 0;
2792
+ }
2793
+ function deriveTaskKind(task) {
2794
+ return hasItems(task.actions) ? "user" : hasItems(task.effects) ? "service" : task.completeWhen !== void 0 || task.subworkflows !== void 0 ? "receive" : "script";
2795
+ }
2796
+ function taskKind(task) {
2797
+ return task.kind ?? deriveTaskKind(task);
2798
+ }
2799
+ function driverKind(actor) {
2800
+ return actor.kind === "user" ? "person" : actor.kind === "ai" ? "agent" : isEngineActor(actor) ? "engine" : "service";
2801
+ }
2786
2802
  async function evaluateInstance(args) {
2787
2803
  const { client, tag, instanceId, resourceClients } = args, now = (args.clock ?? wallClock)();
2788
2804
  validateTag(tag);
@@ -2926,9 +2942,9 @@ function taskScopeFor(args) {
2926
2942
  const { scope, instance, snapshot, actor, taskName, roleAliases } = args;
2927
2943
  return {
2928
2944
  ...scope,
2929
- state: {
2930
- ...scope.state,
2931
- ...scopedStateOverlay(instance, snapshot, taskName)
2945
+ fields: {
2946
+ ...scope.fields,
2947
+ ...scopedFieldOverlay(instance, snapshot, taskName)
2932
2948
  },
2933
2949
  assigned: assignedFor(instance, taskName, actor, roleAliases)
2934
2950
  };
@@ -2972,10 +2988,11 @@ async function evaluateTask(args) {
2972
2988
  return {
2973
2989
  task,
2974
2990
  status,
2991
+ kind: taskKind(task),
2975
2992
  // "pending on actor" treats both `pending` and `active` as waiting on
2976
2993
  // the assignee — pending tasks just haven't been activated yet, but
2977
- // they're still inbox items. The inbox reads the assignees-kind state
2978
- // entry BY KIND (who-data is state).
2994
+ // they're still inbox items. The inbox reads the assignees-kind field
2995
+ // entry BY KIND (who-data is fields).
2979
2996
  pendingOnActor: (status === "active" || status === "pending") && assigned,
2980
2997
  ...unmetRequirements.length > 0 ? { unmetRequirements } : {},
2981
2998
  actions
@@ -3226,7 +3243,7 @@ async function commitAction(ctx, taskName, actionName, callerParams, options) {
3226
3243
  stage: stage.name,
3227
3244
  task: taskName,
3228
3245
  action: actionName,
3229
- ...actor !== void 0 ? { actor } : {}
3246
+ ...actor !== void 0 ? { actor, driverKind: driverKind(actor) } : {}
3230
3247
  });
3231
3248
  const statusBefore = mutEntry.status, ranOps = await runOps({
3232
3249
  ops: action.ops,
@@ -3244,7 +3261,7 @@ async function commitAction(ctx, taskName, actionName, callerParams, options) {
3244
3261
  }), await persistThenDeploy(
3245
3262
  ctx,
3246
3263
  mutation,
3247
- () => ranOps.some(isStateOp) ? refreshStageGuards(ctx, mutation, stage.name) : Promise.resolve()
3264
+ () => ranOps.some(isFieldOp) ? refreshStageGuards(ctx, mutation, stage.name) : Promise.resolve()
3248
3265
  ), {
3249
3266
  fired: !0,
3250
3267
  task: taskName,
@@ -3273,11 +3290,11 @@ function formatDisabledReason(task, action, reason) {
3273
3290
  const detail = disabledReasonDetail[reason.kind](reason);
3274
3291
  return `Action "${task}:${action}" is not allowed: ${detail}`;
3275
3292
  }
3276
- class EditStateDeniedError extends Error {
3293
+ class EditFieldDeniedError extends Error {
3277
3294
  reason;
3278
3295
  target;
3279
3296
  constructor(args) {
3280
- super(formatEditDisabledReason(args.target, args.reason)), this.name = "EditStateDeniedError", this.reason = args.reason, this.target = args.target;
3297
+ super(formatEditDisabledReason(args.target, args.reason)), this.name = "EditFieldDeniedError", this.reason = args.reason, this.target = args.target;
3281
3298
  }
3282
3299
  }
3283
3300
  const editDisabledReasonDetail = {
@@ -3290,10 +3307,10 @@ const editDisabledReasonDetail = {
3290
3307
  function formatEditDisabledReason(target, reason) {
3291
3308
  const detail = editDisabledReasonDetail[reason.kind](
3292
3309
  reason
3293
- ), where = target.task !== void 0 ? `${target.task}.${target.state}` : target.state;
3294
- return `State "${target.scope}:${where}" is not editable: ${detail}`;
3310
+ ), where = target.task !== void 0 ? `${target.task}.${target.field}` : target.field;
3311
+ return `Field "${target.scope}:${where}" is not editable: ${detail}`;
3295
3312
  }
3296
- async function editState(args) {
3313
+ async function editField(args) {
3297
3314
  const { client, instanceId, target, mode = "set", value, options } = args;
3298
3315
  for (let attempt = 1; attempt <= CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS; attempt++) {
3299
3316
  const ctx = await loadCallContext(client, instanceId, options);
@@ -3303,7 +3320,7 @@ async function editState(args) {
3303
3320
  if (!isRevisionConflict(error)) throw error;
3304
3321
  }
3305
3322
  }
3306
- throw new ConcurrentEditStateError({
3323
+ throw new ConcurrentEditFieldError({
3307
3324
  instanceId,
3308
3325
  target: labelTarget(target),
3309
3326
  attempts: CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS
@@ -3313,7 +3330,7 @@ async function commitEdit(ctx, target, mode, value, options) {
3313
3330
  const actor = options?.actor, stage = findStage(ctx.definition, ctx.instance.currentStage), slot = resolveEditTarget({ definition: ctx.definition, stage, target });
3314
3331
  if (slot === void 0)
3315
3332
  throw new Error(
3316
- `No state slot "${describeTarget(target)}" resolves in current stage "${stage.name}" of ${ctx.definition.name}`
3333
+ `No field slot "${describeTarget(target)}" resolves in current stage "${stage.name}" of ${ctx.definition.name}`
3317
3334
  );
3318
3335
  await assertSlotEditable(ctx, slot, options);
3319
3336
  const op = buildEditOp(slot, mode, value), mutation = startMutation(ctx.instance), ranOps = runOps({
@@ -3332,7 +3349,7 @@ async function commitEdit(ctx, target, mode, value, options) {
3332
3349
  return await persistThenDeploy(
3333
3350
  ctx,
3334
3351
  mutation,
3335
- () => ranOps.some(isStateOp) ? refreshStageGuards(ctx, mutation, stage.name) : Promise.resolve()
3352
+ () => ranOps.some(isFieldOp) ? refreshStageGuards(ctx, mutation, stage.name) : Promise.resolve()
3336
3353
  ), {
3337
3354
  edited: !0,
3338
3355
  target: slotTarget(slot),
@@ -3351,14 +3368,14 @@ async function assertSlotEditable(ctx, slot, options) {
3351
3368
  guardDenial: void 0,
3352
3369
  predicateSatisfied
3353
3370
  });
3354
- if (reason !== void 0) throw new EditStateDeniedError({ target: slotTarget(slot), reason });
3371
+ if (reason !== void 0) throw new EditFieldDeniedError({ target: slotTarget(slot), reason });
3355
3372
  }
3356
3373
  function buildEditOp(slot, mode, value) {
3357
- if (mode === "unset") return { type: "state.unset", target: slot.ref };
3374
+ if (mode === "unset") return { type: "field.unset", target: slot.ref };
3358
3375
  if (value === void 0)
3359
- throw new Error(`editState mode "${mode}" requires a value for slot "${slot.name}"`);
3376
+ throw new Error(`editField mode "${mode}" requires a value for slot "${slot.name}"`);
3360
3377
  return {
3361
- type: mode === "append" ? "state.append" : "state.set",
3378
+ type: mode === "append" ? "field.append" : "field.set",
3362
3379
  target: slot.ref,
3363
3380
  value: { type: "literal", value }
3364
3381
  };
@@ -3366,19 +3383,19 @@ function buildEditOp(slot, mode, value) {
3366
3383
  function slotTarget(slot) {
3367
3384
  return {
3368
3385
  scope: slot.scope,
3369
- state: slot.name,
3386
+ field: slot.name,
3370
3387
  ...slot.task !== void 0 ? { task: slot.task } : {}
3371
3388
  };
3372
3389
  }
3373
3390
  function labelTarget(target) {
3374
3391
  return {
3375
3392
  scope: target.scope ?? (target.task !== void 0 ? "task" : "workflow"),
3376
- state: target.state,
3393
+ field: target.field,
3377
3394
  ...target.task !== void 0 ? { task: target.task } : {}
3378
3395
  };
3379
3396
  }
3380
3397
  function describeTarget(target) {
3381
- const where = target.task !== void 0 ? `${target.task}.${target.state}` : target.state;
3398
+ const where = target.task !== void 0 ? `${target.task}.${target.field}` : target.field;
3382
3399
  return target.scope !== void 0 ? `${target.scope}:${where}` : where;
3383
3400
  }
3384
3401
  function bareIdFromSpawnRef(uri) {
@@ -3451,10 +3468,10 @@ function assertActionAllowed(evaluation, task, action) {
3451
3468
  function assertEditAllowed(evaluation, target) {
3452
3469
  const slot = evaluation.editableSlots.filter((s) => editTargetMatches(s, target)).sort((a, b) => SCOPE_PRECEDENCE[a.scope] - SCOPE_PRECEDENCE[b.scope])[0];
3453
3470
  if (slot !== void 0 && !slot.editable && slot.disabledReason !== void 0)
3454
- throw new EditStateDeniedError({
3471
+ throw new EditFieldDeniedError({
3455
3472
  target: {
3456
3473
  scope: slot.scope,
3457
- state: slot.name,
3474
+ field: slot.name,
3458
3475
  ...slot.task !== void 0 ? { task: slot.task } : {}
3459
3476
  },
3460
3477
  reason: slot.disabledReason
@@ -3462,7 +3479,7 @@ function assertEditAllowed(evaluation, target) {
3462
3479
  }
3463
3480
  async function applyEdit(args) {
3464
3481
  const { client, instance, target, mode, value, actor, grants, clock, clientForGdr } = args;
3465
- return (await editState({
3482
+ return (await editField({
3466
3483
  client,
3467
3484
  instanceId: instance._id,
3468
3485
  target,
@@ -3635,7 +3652,7 @@ const workflow = {
3635
3652
  workflowResource,
3636
3653
  definition: definitionName,
3637
3654
  version,
3638
- initialState,
3655
+ initialFields,
3639
3656
  ancestors,
3640
3657
  effectsContext,
3641
3658
  instanceId,
@@ -3645,9 +3662,9 @@ const workflow = {
3645
3662
  throw new Error(
3646
3663
  `Initial stage "${definition.initialStage}" missing in ${definitionName} v${definition.version}`
3647
3664
  );
3648
- const now = clock(), effectsContextEntries = effectsContext ? toEffectsContextEntries(effectsContext) : [], resolvedState = await resolveDeclaredState({
3649
- entryDefs: definition.state ?? [],
3650
- initialState: initialState ?? [],
3665
+ const now = clock(), effectsContextEntries = effectsContext ? toEffectsContextEntries(effectsContext) : [], resolvedFields = await resolveDeclaredFields({
3666
+ entryDefs: definition.fields ?? [],
3667
+ initialFields: initialFields ?? [],
3651
3668
  ctx: {
3652
3669
  client,
3653
3670
  now,
@@ -3658,7 +3675,7 @@ const workflow = {
3658
3675
  ...perspective !== void 0 ? { perspective } : {}
3659
3676
  },
3660
3677
  randomKey
3661
- }), effectivePerspective = perspective ?? derivePerspectiveFromState(resolvedState), base = buildInstanceBase({
3678
+ }), effectivePerspective = perspective ?? derivePerspectiveFromFields(resolvedFields), base = buildInstanceBase({
3662
3679
  id,
3663
3680
  now,
3664
3681
  tag,
@@ -3666,7 +3683,7 @@ const workflow = {
3666
3683
  definitionName: definition.name,
3667
3684
  pinnedVersion: definition.version,
3668
3685
  definition,
3669
- state: resolvedState,
3686
+ fields: resolvedFields,
3670
3687
  effectsContext: effectsContextEntries,
3671
3688
  ancestors: ancestors ?? [],
3672
3689
  perspective: effectivePerspective,
@@ -3720,11 +3737,11 @@ const workflow = {
3720
3737
  });
3721
3738
  },
3722
3739
  /**
3723
- * Edit a declared-editable state slot directly — reassign, reschedule,
3740
+ * Edit a declared-editable field slot directly — reassign, reschedule,
3724
3741
  * claim-by-hand, append to a running log — through the generic edit seam,
3725
3742
  * instead of a bespoke action per field. Soft-gates on the slot's declared
3726
3743
  * editability (the same projection a UI renders), applies the edit as a
3727
- * `state.*` op (so provenance + history are stamped by the op path),
3744
+ * `field.*` op (so provenance + history are stamped by the op path),
3728
3745
  * refreshes the stage's guards, then cascades — an edit to a value a
3729
3746
  * transition reads can and should move the instance. Advisory like every
3730
3747
  * engine gate; the lake ACL + guards are the only hard locks.
@@ -3734,7 +3751,7 @@ const workflow = {
3734
3751
  * UI must bind it to a deliberate boundary (blur / Enter / Save / debounce),
3735
3752
  * never an `onChange` per keystroke.
3736
3753
  */
3737
- editState: async (args) => {
3754
+ editField: async (args) => {
3738
3755
  const { client, tag, instanceId, target, mode, value, resourceClients } = args, { access, actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock, before = await reload(client, instanceId, tag);
3739
3756
  return dispatchGatedWrite({
3740
3757
  client,
@@ -3899,7 +3916,7 @@ const workflow = {
3899
3916
  * Hydrates the instance's snapshot (instance + ancestors + every doc
3900
3917
  * declared by a `doc.ref` / `doc.refs` entry in scope), then
3901
3918
  * evaluates the supplied GROQ in groq-js against that dataset. The
3902
- * rendered scope is auto-bound: `$self`, `$state`, `$parent`,
3919
+ * rendered scope is auto-bound: `$self`, `$fields`, `$parent`,
3903
3920
  * `$ancestors`, `$stage`, `$now`, `$effects`, `$tasks`,
3904
3921
  * `$allTasksDone`, `$anyTaskFailed` — ids in GDR URI form to match
3905
3922
  * the snapshot's keying.
@@ -4054,7 +4071,7 @@ async function drainEffectsInternal(args) {
4054
4071
  effectHandlers,
4055
4072
  missingHandler,
4056
4073
  logger
4057
- } = args, drainerActor = args.access?.actor ?? { kind: "system", id: "engine.drainEffects" }, completionAccess = {
4074
+ } = args, drainerActor = args.access?.actor ?? engineSystemActor("drainEffects"), completionAccess = {
4058
4075
  actor: drainerActor,
4059
4076
  ...args.access?.grants !== void 0 ? { grants: args.access.grants } : {}
4060
4077
  };
@@ -4232,7 +4249,7 @@ function createInstanceSession(args) {
4232
4249
  return settleAfterApply(actor, held, ranOps);
4233
4250
  });
4234
4251
  },
4235
- editState({ target, mode, value }) {
4252
+ editField({ target, mode, value }) {
4236
4253
  return commit(async (actor, held) => {
4237
4254
  assertEditAllowed(await evaluateWith(held, heldGuards), target);
4238
4255
  const { grants } = await access(), ranOps = await applyEdit({
@@ -4294,7 +4311,7 @@ function createEngine(args) {
4294
4311
  deployDefinitions: (rest) => workflow.deployDefinitions(bind(rest)),
4295
4312
  startInstance: (rest) => workflow.startInstance(bind(rest)),
4296
4313
  fireAction: (rest) => workflow.fireAction(bind(rest)),
4297
- editState: (rest) => workflow.editState(bind(rest)),
4314
+ editField: (rest) => workflow.editField(bind(rest)),
4298
4315
  completeEffect: (rest) => workflow.completeEffect(bind(rest)),
4299
4316
  tick: (rest) => workflow.tick(bind(rest)),
4300
4317
  evaluateInstance: (rest) => evaluateInstance(bind(rest)),
@@ -4453,9 +4470,9 @@ const HISTORY_DISPLAY = {
4453
4470
  },
4454
4471
  opApplied: {
4455
4472
  title: "Op applied",
4456
- description: "An inline state-mutation op (state.set / state.append / status.set / etc.) ran during an action commit."
4473
+ description: "An inline field-mutation op (field.set / field.append / status.set / etc.) ran during an action commit."
4457
4474
  }
4458
- }, STATE_SLOT_DISPLAY = {
4475
+ }, FIELD_SLOT_DISPLAY = {
4459
4476
  "doc.ref": {
4460
4477
  title: "Document reference",
4461
4478
  description: "Single GDR pointer at a document in this or another resource."
@@ -4509,23 +4526,23 @@ const HISTORY_DISPLAY = {
4509
4526
  description: "Ordered list of typed (user|role) assignees."
4510
4527
  }
4511
4528
  }, OP_DISPLAY = {
4512
- "state.set": {
4513
- title: "Set state entry",
4514
- description: "Overwrite a state entry's value with a resolved Source."
4529
+ "field.set": {
4530
+ title: "Set field entry",
4531
+ description: "Overwrite a field entry's value with a resolved Source."
4515
4532
  },
4516
- "state.unset": {
4517
- title: "Unset state entry",
4518
- description: "Reset a state entry to its default (null for scalars, [] for array kinds)."
4533
+ "field.unset": {
4534
+ title: "Unset field entry",
4535
+ description: "Reset a field entry to its default (null for scalars, [] for array kinds)."
4519
4536
  },
4520
- "state.append": {
4521
- title: "Append to state entry",
4537
+ "field.append": {
4538
+ title: "Append to field entry",
4522
4539
  description: "Push a resolved item onto an array-kind entry (notes, checklist, assignees, refs)."
4523
4540
  },
4524
- "state.updateWhere": {
4541
+ "field.updateWhere": {
4525
4542
  title: "Update matching rows",
4526
4543
  description: "Merge fields into rows of an array-kind entry that match the predicate."
4527
4544
  },
4528
- "state.removeWhere": {
4545
+ "field.removeWhere": {
4529
4546
  title: "Remove matching rows",
4530
4547
  description: "Drop rows of an array-kind entry that match the predicate."
4531
4548
  },
@@ -4569,11 +4586,40 @@ const HISTORY_DISPLAY = {
4569
4586
  },
4570
4587
  [WORKFLOW_INSTANCE_TYPE]: {
4571
4588
  title: "Workflow instance",
4572
- description: "A running (or finished) workflow against its declared state."
4589
+ description: "A running (or finished) workflow against its declared fields."
4590
+ }
4591
+ }, TASK_KIND_DISPLAY = {
4592
+ user: {
4593
+ title: "User task",
4594
+ description: "A person acts via the app \u2014 renders action buttons ranked by outcome."
4595
+ },
4596
+ service: {
4597
+ title: "Service task",
4598
+ description: "An automated system or effect does the work \u2014 renders effect drain status."
4599
+ },
4600
+ script: {
4601
+ title: "Script task",
4602
+ description: "The engine runs a step inline and resolves on activation \u2014 an audit row."
4603
+ },
4604
+ manual: {
4605
+ title: "Manual task",
4606
+ description: "Work done off-system, acknowledged by a person or verified by a predicate \u2014 renders an instruction card with a deep-link."
4607
+ },
4608
+ receive: {
4609
+ title: "Receive task",
4610
+ description: 'No actor; the engine waits on a condition \u2014 renders "waiting until \u2026", no buttons.'
4611
+ }
4612
+ }, DRIVER_KIND_DISPLAY = {
4613
+ person: { title: "Person", description: "A human fired this action." },
4614
+ agent: { title: "Agent", description: "An AI agent fired this action." },
4615
+ service: { title: "Service", description: "An external system or Function fired this action." },
4616
+ engine: {
4617
+ title: "Engine",
4618
+ description: "The workflow engine itself drove this \u2014 a gate, machine step, or housekeeping."
4573
4619
  }
4574
4620
  }, DISPLAY = {
4575
4621
  ...HISTORY_DISPLAY,
4576
- ...STATE_SLOT_DISPLAY,
4622
+ ...FIELD_SLOT_DISPLAY,
4577
4623
  ...OP_DISPLAY,
4578
4624
  ...EFFECTS_CONTEXT_DISPLAY,
4579
4625
  ...AUTHORING_DISPLAY
@@ -4590,12 +4636,15 @@ export {
4590
4636
  ActionDisabledError,
4591
4637
  ActionParamsInvalidError,
4592
4638
  CascadeLimitError,
4593
- ConcurrentEditStateError,
4639
+ ConcurrentEditFieldError,
4594
4640
  ConcurrentFireActionError,
4595
4641
  DEFAULT_CONTENT_PERSPECTIVE,
4596
4642
  DISPLAY,
4643
+ DRIVER_KINDS,
4644
+ DRIVER_KIND_DISPLAY,
4597
4645
  EFFECTS_CONTEXT_DISPLAY,
4598
- EditStateDeniedError,
4646
+ EditFieldDeniedError,
4647
+ FIELD_SLOT_DISPLAY,
4599
4648
  GUARD_DOC_TYPE,
4600
4649
  GUARD_LIFTED_PREDICATE,
4601
4650
  GUARD_OWNER,
@@ -4603,8 +4652,9 @@ export {
4603
4652
  MutationGuardDeniedError,
4604
4653
  OP_DISPLAY,
4605
4654
  PartialGuardDeployError,
4606
- RequiredStateNotProvidedError,
4607
- STATE_SLOT_DISPLAY,
4655
+ RequiredFieldNotProvidedError,
4656
+ TASK_KINDS,
4657
+ TASK_KIND_DISPLAY,
4608
4658
  WORKFLOW_DEFINITION_TYPE,
4609
4659
  WORKFLOW_INSTANCE_TYPE,
4610
4660
  WorkflowStateDivergedError,
@@ -4620,11 +4670,13 @@ export {
4620
4670
  defaultLoggerFactory,
4621
4671
  denyingGuards,
4622
4672
  deployStageGuards,
4673
+ deriveTaskKind,
4623
4674
  diagnoseInputFromEvaluation,
4624
4675
  diagnoseInstance,
4625
4676
  diffEntry,
4626
4677
  displayDescription,
4627
4678
  displayTitle,
4679
+ driverKind,
4628
4680
  effectsContextMap,
4629
4681
  evaluateFromSnapshot,
4630
4682
  evaluateMutationGuard,
@@ -4657,6 +4709,7 @@ export {
4657
4709
  subscriptionDocument,
4658
4710
  subscriptionDocumentsForInstance,
4659
4711
  tagScopeFilter,
4712
+ taskKind,
4660
4713
  validateDefinition,
4661
4714
  validateTag,
4662
4715
  verdictGuardsForInstance,