@sanity/workflow-engine 0.5.0 → 0.6.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
@@ -722,22 +722,6 @@ async function queryGuardsAcross(clients, query, params) {
722
722
  function dedupById(guards) {
723
723
  return [...new Map(guards.map((g) => [g._id, g])).values()].sort((a, b) => a._id.localeCompare(b._id));
724
724
  }
725
- const TAG_RE = /^[a-z0-9][a-z0-9-]*$/;
726
- function validateTags(tags) {
727
- if (tags.length === 0)
728
- throw new Error("tags: must be a non-empty array");
729
- for (const tag of tags)
730
- if (!TAG_RE.test(tag))
731
- throw new Error(
732
- `tags: invalid tag "${tag}" \u2014 must match ${TAG_RE.source} (ASCII lowercase + digits + dashes, no leading dash, no dots)`
733
- );
734
- }
735
- function canonicalTag(tags) {
736
- return tags[0];
737
- }
738
- function tagScopeFilter(param = "engineTags") {
739
- return `count(tags[@ in $${param}]) > 0`;
740
- }
741
725
  const GUARD_OWNER = "robot:workflow-engine", GUARD_LIFTED_PREDICATE = "true";
742
726
  function resolveGuard(guard, instance, stageName, now) {
743
727
  const ctx = { instance, now }, targets = resolveIdRefTargets(guard.match.idRefs, ctx);
@@ -795,13 +779,13 @@ async function retractStageGuards(args) {
795
779
  await client.getDocument(doc._id) && await client.patch(doc._id).set({ predicate: GUARD_LIFTED_PREDICATE }).commit();
796
780
  }
797
781
  async function deleteOrphanedDefinitionGuards(args) {
798
- const { client, clientForGdr, workflowResource, definition, definitions, tags } = args, perClient = await guardsForDefinitionByClient({
782
+ const { client, clientForGdr, workflowResource, definition, definitions, tag } = args, perClient = await guardsForDefinitionByClient({
799
783
  client,
800
784
  clientForGdr,
801
785
  workflowResource,
802
786
  definition,
803
787
  definitions
804
- }), ownPartitionPrefix = `${canonicalTag(tags)}.`;
788
+ }), ownPartitionPrefix = `${tag}.`;
805
789
  let count = 0;
806
790
  for (const { client: resourceClient, guards } of perClient) {
807
791
  const own = guards.filter((guard) => guard.sourceInstanceId.startsWith(ownPartitionPrefix));
@@ -990,7 +974,7 @@ async function resolveQueryValue(entry, source, ctx, client, defaultValue) {
990
974
  stage: ctx.stageName ?? null,
991
975
  task: ctx.taskName ?? null,
992
976
  now: ctx.now,
993
- engineTags: ctx.tags ?? []
977
+ tag: ctx.tag
994
978
  });
995
979
  try {
996
980
  const fetchOptions = ctx.perspective !== void 0 ? { perspective: ctx.perspective } : void 0, result = await client.fetch(source.query, params, fetchOptions);
@@ -1157,7 +1141,7 @@ async function resolveStageStateEntries(args) {
1157
1141
  client,
1158
1142
  now,
1159
1143
  selfId: instance._id,
1160
- tags: instance.tags ?? [],
1144
+ tag: instance.tag,
1161
1145
  stageName: stage.name,
1162
1146
  workflowResource: instance.workflowResource,
1163
1147
  // Allow stage-scope entries' `source: { type: "stateRead", scope:
@@ -1177,7 +1161,7 @@ async function resolveTaskStateEntries(args) {
1177
1161
  client,
1178
1162
  now,
1179
1163
  selfId: instance._id,
1180
- tags: instance.tags ?? [],
1164
+ tag: instance.tag,
1181
1165
  stageName: stage.name,
1182
1166
  workflowResource: instance.workflowResource,
1183
1167
  taskName: task.name,
@@ -1399,6 +1383,16 @@ function findCurrentStageEntry(instance) {
1399
1383
  function findCurrentTasks(instance) {
1400
1384
  return findCurrentStageEntry(instance)?.tasks ?? [];
1401
1385
  }
1386
+ const TAG_RE = /^[a-z0-9][a-z0-9-]*$/;
1387
+ function validateTag(tag) {
1388
+ if (!TAG_RE.test(tag))
1389
+ throw new Error(
1390
+ `tag: invalid tag "${tag}" \u2014 must match ${TAG_RE.source} (ASCII lowercase + digits + dashes, no leading dash, no dots)`
1391
+ );
1392
+ }
1393
+ function tagScopeFilter() {
1394
+ return "tag == $tag";
1395
+ }
1402
1396
  function definitionLookupGroq(explicit) {
1403
1397
  const scoped = `_type == "${WORKFLOW_DEFINITION_TYPE}" && name == $definition && ${tagScopeFilter()}`;
1404
1398
  return explicit ? `*[${scoped} && version == $version][0]` : `*[${scoped}] | order(version desc)[0]`;
@@ -1415,6 +1409,14 @@ function clientForDiscovery(defaultClient, clientForGdr, subjectGdrUri) {
1415
1409
  return defaultClient;
1416
1410
  }
1417
1411
  }
1412
+ async function reload(client, instanceId, tag) {
1413
+ const doc = await client.getDocument(instanceId);
1414
+ if (!doc)
1415
+ throw new Error(`Workflow instance ${instanceId} not found`);
1416
+ if (doc.tag !== tag)
1417
+ throw new Error(`Workflow instance ${instanceId} not visible to this engine (tag mismatch)`);
1418
+ return doc;
1419
+ }
1418
1420
  function effectsContextEntry(name, value) {
1419
1421
  const _key = randomKey();
1420
1422
  return typeof value == "string" ? { _key, _type: "effectsContext.string", name, value } : typeof value == "number" ? { _key, _type: "effectsContext.number", name, value } : typeof value == "boolean" ? { _key, _type: "effectsContext.boolean", name, value } : { _key, _type: "effectsContext.ref", name, value };
@@ -1430,7 +1432,7 @@ function buildInstanceBase(args) {
1430
1432
  _rev: "",
1431
1433
  _createdAt: now,
1432
1434
  _updatedAt: now,
1433
- tags: args.tags,
1435
+ tag: args.tag,
1434
1436
  workflowResource: args.workflowResource,
1435
1437
  definition: args.definitionName,
1436
1438
  pinnedVersion: args.pinnedVersion,
@@ -1481,7 +1483,7 @@ async function spawnSubworkflows(ctx, mutation, task, sub, actor) {
1481
1483
  `Subworkflow depth limit (${MAX_SPAWN_DEPTH}) exceeded on task "${task.name}" of ${ctx.instance._id}. Ancestor chain: ${chain}`
1482
1484
  );
1483
1485
  }
1484
- const now = ctx.now, definition = await resolveDefinitionRef(ctx.client, sub.definition, ctx.instance.tags ?? []);
1486
+ const now = ctx.now, definition = await resolveDefinitionRef(ctx.client, sub.definition, ctx.instance.tag);
1485
1487
  if (definition === null) {
1486
1488
  const versionLabel = sub.definition.version === void 0 || sub.definition.version === "latest" ? "latest" : `v${sub.definition.version}`;
1487
1489
  throw new Error(
@@ -1571,15 +1573,15 @@ function coerceSpawnGdr(raw, workflowResource) {
1571
1573
  }
1572
1574
  return typeof raw == "string" && raw.length > 0 ? { id: toUri(raw), type: "document" } : null;
1573
1575
  }
1574
- async function resolveDefinitionRef(client, ref, tags) {
1575
- const wantsExplicit = typeof ref.version == "number", params = { definition: ref.name, engineTags: tags };
1576
+ async function resolveDefinitionRef(client, ref, tag) {
1577
+ const wantsExplicit = typeof ref.version == "number", params = { definition: ref.name, tag };
1576
1578
  return wantsExplicit && (params.version = ref.version), await client.fetch(
1577
1579
  definitionLookupGroq(wantsExplicit),
1578
1580
  params
1579
1581
  ) ?? null;
1580
1582
  }
1581
1583
  async function prepareChildInstance(args) {
1582
- const { client, parent, definition, initialState, effectsContext, actor, now } = args, childTags = parent.tags ?? [], childPrefix = childTags[0] ?? "wf", workflowResource = parent.workflowResource, childDocId = `${childPrefix}.wf-instance.${randomKey()}`, childRef = { id: gdrFromResource(workflowResource, childDocId), type: WORKFLOW_INSTANCE_TYPE }, ancestors = [
1584
+ 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 = [
1583
1585
  ...parent.ancestors,
1584
1586
  {
1585
1587
  id: selfGdr(parent),
@@ -1592,7 +1594,7 @@ async function prepareChildInstance(args) {
1592
1594
  client,
1593
1595
  now,
1594
1596
  selfId: childDocId,
1595
- tags: childTags,
1597
+ tag: childTag,
1596
1598
  workflowResource,
1597
1599
  ...inheritedPerspective !== void 0 ? { perspective: inheritedPerspective } : {}
1598
1600
  },
@@ -1611,7 +1613,7 @@ async function prepareChildInstance(args) {
1611
1613
  ), base = buildInstanceBase({
1612
1614
  id: childDocId,
1613
1615
  now,
1614
- tags: childTags,
1616
+ tag: childTag,
1615
1617
  workflowResource,
1616
1618
  definitionName: definition.name,
1617
1619
  pinnedVersion: definition.version,
@@ -2477,17 +2479,12 @@ async function fetchGrantsCached(requestFn, resourcePath) {
2477
2479
  }
2478
2480
  }
2479
2481
  async function evaluateInstance(args) {
2480
- const { client, tags, instanceId, resourceClients } = args, now = (args.clock ?? wallClock)();
2481
- validateTags(tags);
2482
+ const { client, tag, instanceId, resourceClients } = args, now = (args.clock ?? wallClock)();
2483
+ validateTag(tag);
2482
2484
  const { actor, grants } = await resolveAccess(client, {
2483
2485
  ...args.access !== void 0 ? { override: args.access } : {},
2484
2486
  ...args.grantsFromPath !== void 0 ? { grantsFromPath: args.grantsFromPath } : {}
2485
- }), instance = await client.getDocument(instanceId);
2486
- if (!instance)
2487
- throw new Error(`Workflow instance "${instanceId}" not found`);
2488
- if (!tags.some((t) => instance.tags?.includes(t)))
2489
- throw new Error(`Workflow instance "${instanceId}" not visible to this engine (tag mismatch)`);
2490
- const definition = parseDefinitionSnapshot(instance), snapshot = await hydrateSnapshot({ client, clientForGdr: resourceClients !== void 0 ? (parsed) => resourceClients(parsed) ?? client : () => client, instance }), guards = await verdictGuardsForInstance(client, instance._id);
2487
+ }), instance = await reload(client, instanceId, tag), definition = parseDefinitionSnapshot(instance), snapshot = await hydrateSnapshot({ client, clientForGdr: resourceClients !== void 0 ? (parsed) => resourceClients(parsed) ?? client : () => client, instance }), guards = await verdictGuardsForInstance(client, instance._id);
2491
2488
  return evaluateFromSnapshot({
2492
2489
  instance,
2493
2490
  definition,
@@ -2628,22 +2625,21 @@ function lifecycleReason(instance, status, stageHasExits) {
2628
2625
  function disabled(action, reason) {
2629
2626
  return { action, allowed: !1, disabledReason: reason };
2630
2627
  }
2631
- function definitionDocId(_workflowResource, prefix, definition, version) {
2632
- return `${prefix}.${definition}.v${version}`;
2628
+ function definitionDocId(_workflowResource, tag, definition, version) {
2629
+ return `${tag}.${definition}.v${version}`;
2633
2630
  }
2634
- async function sortByDependencies(client, definitions, tags, workflowResource) {
2635
- const prefix = canonicalTag(tags), byName = /* @__PURE__ */ new Map();
2631
+ async function sortByDependencies(client, definitions, tag, workflowResource) {
2632
+ const byName = /* @__PURE__ */ new Map();
2636
2633
  for (const def of definitions) {
2637
2634
  const list = byName.get(def.name) ?? [];
2638
2635
  list.push(def), byName.set(def.name, list);
2639
2636
  }
2640
2637
  const findInBatch = (ref) => findRefInBatch(byName, ref);
2641
2638
  return await assertCrossBatchRefsDeployed(client, definitions, {
2642
- tags,
2639
+ tag,
2643
2640
  workflowResource,
2644
- prefix,
2645
2641
  findInBatch
2646
- }), topoSortDefinitions(definitions, { workflowResource, prefix, findInBatch });
2642
+ }), topoSortDefinitions(definitions, { workflowResource, tag, findInBatch });
2647
2643
  }
2648
2644
  function findRefInBatch(byName, ref) {
2649
2645
  const candidates = byName.get(ref.name);
@@ -2656,10 +2652,10 @@ function findRefInBatch(byName, ref) {
2656
2652
  async function assertCrossBatchRefsDeployed(client, definitions, ctx) {
2657
2653
  const missing = [];
2658
2654
  for (const def of definitions) {
2659
- const fromId = definitionDocId(ctx.workflowResource, ctx.prefix, def.name, def.version);
2655
+ const fromId = definitionDocId(ctx.workflowResource, ctx.tag, def.name, def.version);
2660
2656
  for (const ref of refsOf(def)) {
2661
2657
  if (ctx.findInBatch(ref) !== void 0) continue;
2662
- const label = await resolveDeployedRefLabel(client, ref, ctx.tags);
2658
+ const label = await resolveDeployedRefLabel(client, ref, ctx.tag);
2663
2659
  label !== void 0 && missing.push({ from: fromId, ref: label });
2664
2660
  }
2665
2661
  }
@@ -2671,8 +2667,8 @@ async function assertCrossBatchRefsDeployed(client, definitions, ctx) {
2671
2667
  `)
2672
2668
  );
2673
2669
  }
2674
- async function resolveDeployedRefLabel(client, ref, tags) {
2675
- const wantsExplicit = typeof ref.version == "number", params = { definition: ref.name, engineTags: tags };
2670
+ async function resolveDeployedRefLabel(client, ref, tag) {
2671
+ const wantsExplicit = typeof ref.version == "number", params = { definition: ref.name, tag };
2676
2672
  if (wantsExplicit && (params.version = ref.version), !await client.fetch(
2677
2673
  definitionLookupGroq(wantsExplicit),
2678
2674
  params
@@ -2681,7 +2677,7 @@ async function resolveDeployedRefLabel(client, ref, tags) {
2681
2677
  }
2682
2678
  function topoSortDefinitions(definitions, ctx) {
2683
2679
  const visited = /* @__PURE__ */ new Set(), visiting = /* @__PURE__ */ new Set(), ordered = [], visit = (def) => {
2684
- const id = definitionDocId(ctx.workflowResource, ctx.prefix, def.name, def.version);
2680
+ const id = definitionDocId(ctx.workflowResource, ctx.tag, def.name, def.version);
2685
2681
  if (!visited.has(id)) {
2686
2682
  if (visiting.has(id))
2687
2683
  throw new Error(`workflow.deployDefinitions: dependency cycle involving "${id}"`);
@@ -2722,11 +2718,11 @@ function stableStringify(value) {
2722
2718
  ([a], [b]) => a.localeCompare(b)
2723
2719
  ).map(([k, v2]) => `${JSON.stringify(k)}:${stableStringify(v2)}`).join(",")}}`;
2724
2720
  }
2725
- async function loadDefinition(client, definition, version, tags) {
2721
+ async function loadDefinition(client, definition, version, tag) {
2726
2722
  if (version !== void 0) {
2727
2723
  const doc = await client.fetch(
2728
2724
  definitionLookupGroq(!0),
2729
- { definition, version, engineTags: tags }
2725
+ { definition, version, tag }
2730
2726
  );
2731
2727
  if (!doc)
2732
2728
  throw new Error(`Workflow definition ${definition} v${version} not deployed`);
@@ -2734,16 +2730,16 @@ async function loadDefinition(client, definition, version, tags) {
2734
2730
  }
2735
2731
  const latest = await client.fetch(definitionLookupGroq(!1), {
2736
2732
  definition,
2737
- engineTags: tags
2733
+ tag
2738
2734
  });
2739
2735
  if (!latest)
2740
2736
  throw new Error(`No deployed definition for workflow ${definition}`);
2741
2737
  return latest;
2742
2738
  }
2743
- async function loadDefinitionVersions(client, definition, tags) {
2739
+ async function loadDefinitionVersions(client, definition, tag) {
2744
2740
  return client.fetch(
2745
- `*[_type == "${WORKFLOW_DEFINITION_TYPE}" && name == $definition && count(tags[@ in $engineTags]) > 0] | order(version desc)`,
2746
- { definition, engineTags: tags }
2741
+ `*[_type == "${WORKFLOW_DEFINITION_TYPE}" && name == $definition && ${tagScopeFilter()}] | order(version desc)`,
2742
+ { definition, tag }
2747
2743
  );
2748
2744
  }
2749
2745
  async function abortInstance(args) {
@@ -2894,7 +2890,7 @@ function bareIdFromSpawnRef(uri) {
2894
2890
  }
2895
2891
  }
2896
2892
  async function resolveOperationContext(args) {
2897
- validateTags(args.tags);
2893
+ validateTag(args.tag);
2898
2894
  const access = await resolveAccess(args.client, {
2899
2895
  ...args.access !== void 0 ? { override: args.access } : {},
2900
2896
  ...args.grantsFromPath !== void 0 ? { grantsFromPath: args.grantsFromPath } : {}
@@ -2928,16 +2924,6 @@ async function abortAndPropagate(args) {
2928
2924
  function buildClientForGdr(defaultClient, resolver) {
2929
2925
  return resolver === void 0 ? () => defaultClient : (parsed) => resolver(parsed) ?? defaultClient;
2930
2926
  }
2931
- async function reload(client, instanceId, tags) {
2932
- const doc = await client.getDocument(instanceId);
2933
- if (!doc) throw new Error(`Workflow instance ${instanceId} not found`);
2934
- if (!intersectsTags(doc.tags, tags))
2935
- throw new Error(`Workflow instance ${instanceId} not visible to this engine (tag mismatch)`);
2936
- return doc;
2937
- }
2938
- function intersectsTags(docTags, engineTags) {
2939
- return !docTags || docTags.length === 0 ? !1 : engineTags.some((t) => docTags.includes(t));
2940
- }
2941
2927
  function toEffectsContextEntries(ctx) {
2942
2928
  return Object.entries(ctx).map(([id, value]) => effectsContextEntry(id, value));
2943
2929
  }
@@ -2963,15 +2949,15 @@ async function applyAction(args) {
2963
2949
  })).ranOps;
2964
2950
  }
2965
2951
  async function deleteDefinition(args) {
2966
- const { client, tags, definition, version, cascade: cascade2, reason } = args, { actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock, versions = await loadDefinitionVersions(client, definition, tags);
2952
+ const { client, tag, definition, version, cascade: cascade2, reason } = args, { actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock, versions = await loadDefinitionVersions(client, definition, tag);
2967
2953
  if (versions.length === 0)
2968
2954
  throw new Error(`No deployed definition for workflow ${definition}`);
2969
2955
  const targets = version === void 0 ? versions : versions.filter((d) => d.version === version);
2970
2956
  if (targets.length === 0)
2971
2957
  throw new Error(`Workflow definition ${definition} v${version} not deployed`);
2972
2958
  const lastVersionGoes = targets.length === versions.length;
2973
- await assertNoSpawnReferrers(client, tags, definition, targets, lastVersionGoes);
2974
- const instanceIds = await nonTerminalInstanceIds(client, tags, definition, version);
2959
+ await assertNoSpawnReferrers(client, tag, definition, targets, lastVersionGoes);
2960
+ const instanceIds = await nonTerminalInstanceIds(client, tag, definition, version);
2975
2961
  if (instanceIds.length > 0 && cascade2 !== !0)
2976
2962
  throw new Error(
2977
2963
  `Cannot delete ${definition}: ${instanceIds.length} non-terminal instance(s) exist (${previewIds(instanceIds)}). Pass cascade to abort them first \u2014 instances are aborted in place, never deleted.`
@@ -2992,7 +2978,7 @@ async function deleteDefinition(args) {
2992
2978
  workflowResource: args.workflowResource,
2993
2979
  definition,
2994
2980
  definitions: versions,
2995
- tags
2981
+ tag
2996
2982
  }) : 0;
2997
2983
  return {
2998
2984
  name: definition,
@@ -3001,10 +2987,10 @@ async function deleteDefinition(args) {
3001
2987
  deletedGuardCount
3002
2988
  };
3003
2989
  }
3004
- async function assertNoSpawnReferrers(client, tags, definition, targets, lastVersionGoes) {
2990
+ async function assertNoSpawnReferrers(client, tag, definition, targets, lastVersionGoes) {
3005
2991
  const deployed = await client.fetch(
3006
2992
  `*[_type == "${WORKFLOW_DEFINITION_TYPE}" && ${tagScopeFilter()}]`,
3007
- { engineTags: tags }
2993
+ { tag }
3008
2994
  ), targetIds = new Set(targets.map((d) => d._id)), targetVersions = new Set(targets.map((d) => d.version)), referrers = deployed.filter((d) => !targetIds.has(d._id)).filter(
3009
2995
  (d) => refsOf(d).some(
3010
2996
  (ref) => ref.name === definition && (typeof ref.version == "number" ? targetVersions.has(ref.version) : lastVersionGoes)
@@ -3017,11 +3003,11 @@ async function assertNoSpawnReferrers(client, tags, definition, targets, lastVer
3017
3003
  );
3018
3004
  }
3019
3005
  }
3020
- async function nonTerminalInstanceIds(client, tags, definition, version) {
3006
+ async function nonTerminalInstanceIds(client, tag, definition, version) {
3021
3007
  const versionFilter = version === void 0 ? "" : " && pinnedVersion == $version";
3022
3008
  return (await client.fetch(
3023
3009
  `*[_type == "${WORKFLOW_INSTANCE_TYPE}" && definition == $definition && ${tagScopeFilter()} && !defined(completedAt)${versionFilter}] | order(_id asc){_id}`,
3024
- { definition, engineTags: tags, ...version !== void 0 ? { version } : {} }
3010
+ { definition, tag, ...version !== void 0 ? { version } : {} }
3025
3011
  )).map((doc) => doc._id);
3026
3012
  }
3027
3013
  async function abortInstances(args) {
@@ -3052,20 +3038,20 @@ const workflow = {
3052
3038
  * Cycles in the dependency graph error before any write happens.
3053
3039
  */
3054
3040
  deployDefinitions: async (args) => {
3055
- const { client, tags, workflowResource, definitions } = args;
3056
- validateTags(tags);
3041
+ const { client, tag, workflowResource, definitions } = args;
3042
+ validateTag(tag);
3057
3043
  for (const def of definitions)
3058
3044
  validateDefinition(def);
3059
- const ordered = await sortByDependencies(client, definitions, tags, workflowResource), results = [], prefix = canonicalTag(tags), tx = client.transaction();
3045
+ const ordered = await sortByDependencies(client, definitions, tag, workflowResource), results = [], tx = client.transaction();
3060
3046
  let hasWrites = !1;
3061
3047
  for (const def of ordered) {
3062
- const id = definitionDocId(workflowResource, prefix, def.name, def.version), expected = {
3048
+ const id = definitionDocId(workflowResource, tag, def.name, def.version), expected = {
3063
3049
  ...def,
3064
3050
  _id: id,
3065
3051
  _type: WORKFLOW_DEFINITION_TYPE,
3066
- tags
3052
+ tag
3067
3053
  }, existing = await client.getDocument(id);
3068
- if (existing && intersectsTags(existing.tags, tags) && isDefinitionUnchanged(existing, expected)) {
3054
+ if (existing && existing.tag === tag && isDefinitionUnchanged(existing, expected)) {
3069
3055
  results.push({ definition: def.name, version: def.version, status: "unchanged" });
3070
3056
  continue;
3071
3057
  }
@@ -3103,7 +3089,7 @@ const workflow = {
3103
3089
  startInstance: async (args) => {
3104
3090
  const {
3105
3091
  client,
3106
- tags,
3092
+ tag,
3107
3093
  workflowResource,
3108
3094
  definition: definitionName,
3109
3095
  version,
@@ -3112,7 +3098,7 @@ const workflow = {
3112
3098
  effectsContext,
3113
3099
  instanceId,
3114
3100
  perspective
3115
- } = args, { actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock, definition = await loadDefinition(client, definitionName, version, tags), id = instanceId ?? `${canonicalTag(tags)}.wf-instance.${randomKey()}`;
3101
+ } = args, { actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock, definition = await loadDefinition(client, definitionName, version, tag), id = instanceId ?? `${tag}.wf-instance.${randomKey()}`;
3116
3102
  if (definition.stages.find((s) => s.name === definition.initialStage) === void 0)
3117
3103
  throw new Error(
3118
3104
  `Initial stage "${definition.initialStage}" missing in ${definitionName} v${definition.version}`
@@ -3124,7 +3110,7 @@ const workflow = {
3124
3110
  client,
3125
3111
  now,
3126
3112
  selfId: id,
3127
- tags,
3113
+ tag,
3128
3114
  workflowResource,
3129
3115
  ...perspective !== void 0 ? { perspective } : {}
3130
3116
  },
@@ -3132,7 +3118,7 @@ const workflow = {
3132
3118
  }), effectivePerspective = perspective ?? derivePerspectiveFromState(resolvedState), base = buildInstanceBase({
3133
3119
  id,
3134
3120
  now,
3135
- tags,
3121
+ tag,
3136
3122
  workflowResource,
3137
3123
  definitionName: definition.name,
3138
3124
  pinnedVersion: definition.version,
@@ -3144,7 +3130,7 @@ const workflow = {
3144
3130
  initialStage: definition.initialStage,
3145
3131
  actor
3146
3132
  });
3147
- return await client.create(base), await primeInitialStage(client, id, actor, clientForGdr, clock), await cascade(client, id, actor, clientForGdr, clock), reload(client, id, tags);
3133
+ return await client.create(base), await primeInitialStage(client, id, actor, clientForGdr, clock), await cascade(client, id, actor, clientForGdr, clock), reload(client, id, tag);
3148
3134
  },
3149
3135
  /**
3150
3136
  * Fire an action against a task. If the task is pending, it is
@@ -3159,19 +3145,19 @@ const workflow = {
3159
3145
  fireAction: async (args) => {
3160
3146
  const {
3161
3147
  client,
3162
- tags,
3148
+ tag,
3163
3149
  instanceId,
3164
3150
  task,
3165
3151
  action,
3166
3152
  params,
3167
3153
  idempotent,
3168
3154
  resourceClients
3169
- } = args, { access, actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock, before = await reload(client, instanceId, tags);
3155
+ } = args, { access, actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock, before = await reload(client, instanceId, tag);
3170
3156
  if (findOpenStageEntry(before)?.tasks.find((t) => t.name === task) === void 0 && idempotent === !0)
3171
3157
  return { instance: before, cascaded: 0, fired: !1 };
3172
3158
  const evaluation = await evaluateInstance({
3173
3159
  client,
3174
- tags,
3160
+ tag,
3175
3161
  instanceId,
3176
3162
  access,
3177
3163
  clock,
@@ -3190,7 +3176,7 @@ const workflow = {
3190
3176
  ...params !== void 0 ? { params } : {}
3191
3177
  }), cascaded = await cascade(client, instanceId, actor, clientForGdr, clock);
3192
3178
  return {
3193
- instance: await reload(client, instanceId, tags),
3179
+ instance: await reload(client, instanceId, tag),
3194
3180
  cascaded,
3195
3181
  fired: !0,
3196
3182
  ...ranOps !== void 0 ? { ranOps } : {}
@@ -3204,7 +3190,7 @@ const workflow = {
3204
3190
  * reference them. Cascades after.
3205
3191
  */
3206
3192
  completeEffect: async (args) => {
3207
- const { client, tags, instanceId, effectKey, status, outputs, detail, error, durationMs } = args, { actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock;
3193
+ const { client, tag, instanceId, effectKey, status, outputs, detail, error, durationMs } = args, { actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock;
3208
3194
  await completeEffect({
3209
3195
  client,
3210
3196
  instanceId,
@@ -3218,7 +3204,7 @@ const workflow = {
3218
3204
  });
3219
3205
  const cascaded = await cascade(client, instanceId, actor, clientForGdr, clock);
3220
3206
  return {
3221
- instance: await reload(client, instanceId, tags),
3207
+ instance: await reload(client, instanceId, tag),
3222
3208
  cascaded,
3223
3209
  fired: !0
3224
3210
  };
@@ -3233,11 +3219,11 @@ const workflow = {
3233
3219
  * affected instances and the engine re-evaluates.
3234
3220
  */
3235
3221
  tick: async (args) => {
3236
- const { client, tags, instanceId } = args, { actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock, current = await reload(client, instanceId, tags), guards = await verdictGuardsForInstance(client, current._id);
3222
+ const { client, tag, instanceId } = args, { actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock, current = await reload(client, instanceId, tag), guards = await verdictGuardsForInstance(client, current._id);
3237
3223
  await assertInstanceWriteAllowed({ instance: current, guards, identity: actor.id });
3238
3224
  const cascaded = await cascade(client, instanceId, actor, clientForGdr, clock);
3239
3225
  return {
3240
- instance: await reload(client, instanceId, tags),
3226
+ instance: await reload(client, instanceId, tag),
3241
3227
  cascaded,
3242
3228
  fired: cascaded > 0
3243
3229
  };
@@ -3248,8 +3234,8 @@ const workflow = {
3248
3234
  * upstream; this verb performs the mechanical move.
3249
3235
  */
3250
3236
  setStage: async (args) => {
3251
- const { client, tags, instanceId, targetStage, reason } = args, { actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock;
3252
- await reload(client, instanceId, tags);
3237
+ const { client, tag, instanceId, targetStage, reason } = args, { actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock;
3238
+ await reload(client, instanceId, tag);
3253
3239
  const result = await setStage({
3254
3240
  client,
3255
3241
  instanceId,
@@ -3258,7 +3244,7 @@ const workflow = {
3258
3244
  options: { ...actor !== void 0 ? { actor } : {}, clock, clientForGdr }
3259
3245
  }), cascaded = result.fired ? await cascade(client, instanceId, actor, clientForGdr, clock) : 0;
3260
3246
  return {
3261
- instance: await reload(client, instanceId, tags),
3247
+ instance: await reload(client, instanceId, tag),
3262
3248
  cascaded,
3263
3249
  fired: result.fired
3264
3250
  };
@@ -3270,28 +3256,28 @@ const workflow = {
3270
3256
  * contract (propagated, not cascaded — the instance is terminal).
3271
3257
  */
3272
3258
  abortInstance: async (args) => {
3273
- const { client, tags, instanceId, reason } = args, { actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock;
3274
- await reload(client, instanceId, tags);
3259
+ const { client, tag, instanceId, reason } = args, { actor, clientForGdr } = await resolveOperationContext(args), clock = args.clock ?? wallClock;
3260
+ await reload(client, instanceId, tag);
3275
3261
  const fired = await abortAndPropagate({ client, instanceId, reason, actor, clientForGdr, clock });
3276
3262
  return {
3277
- instance: await reload(client, instanceId, tags),
3263
+ instance: await reload(client, instanceId, tag),
3278
3264
  cascaded: 0,
3279
3265
  fired
3280
3266
  };
3281
3267
  },
3282
3268
  /**
3283
- * Fetch a workflow instance by id, scoped to the engine's tags.
3269
+ * Fetch a workflow instance by id, scoped to the engine's tag.
3284
3270
  * Throws when the instance doesn't exist or isn't visible to this
3285
3271
  * engine.
3286
3272
  */
3287
3273
  getInstance: async (args) => {
3288
- const { client, tags, instanceId } = args;
3289
- return validateTags(tags), reload(client, instanceId, tags);
3274
+ const { client, tag, instanceId } = args;
3275
+ return validateTag(tag), reload(client, instanceId, tag);
3290
3276
  },
3291
3277
  guardsForInstance: async (args) => {
3292
- const { client, tags, instanceId, resourceClients } = args;
3293
- validateTags(tags);
3294
- const instance = await reload(client, instanceId, tags);
3278
+ const { client, tag, instanceId, resourceClients } = args;
3279
+ validateTag(tag);
3280
+ const instance = await reload(client, instanceId, tag);
3295
3281
  return guardsForInstance({
3296
3282
  client,
3297
3283
  clientForGdr: buildClientForGdr(client, resourceClients),
@@ -3299,9 +3285,9 @@ const workflow = {
3299
3285
  });
3300
3286
  },
3301
3287
  guardsForDefinition: async (args) => {
3302
- const { client, tags, workflowResource, definition, resourceClients } = args;
3303
- validateTags(tags);
3304
- const definitions = await loadDefinitionVersions(client, definition, tags);
3288
+ const { client, tag, workflowResource, definition, resourceClients } = args;
3289
+ validateTag(tag);
3290
+ const definitions = await loadDefinitionVersions(client, definition, tag);
3305
3291
  if (definitions.length === 0)
3306
3292
  throw new Error(`No deployed definition for workflow ${definition}`);
3307
3293
  return guardsForDefinition({
@@ -3313,22 +3299,21 @@ const workflow = {
3313
3299
  });
3314
3300
  },
3315
3301
  /**
3316
- * Run a caller-supplied GROQ query with the engine's tags bound as
3317
- * `$engineTags`. This does NOT rewrite the query — arbitrary GROQ
3302
+ * Run a caller-supplied GROQ query with the engine's tag bound as
3303
+ * `$tag`. This does NOT rewrite the query — arbitrary GROQ
3318
3304
  * can't be safely tag-scoped after the fact — so the CALLER MUST
3319
- * filter on `$engineTags` (e.g.
3320
- * `count(tags[@ in $engineTags]) > 0`). To guard against accidental
3321
- * cross-tenant reads, a query that never references `$engineTags` is
3305
+ * filter on `$tag` (e.g. `tag == $tag`). To guard against accidental
3306
+ * cross-partition reads, a query that never references `$tag` is
3322
3307
  * rejected before it reaches the lake. Caller is responsible for type
3323
3308
  * narrowing the result.
3324
3309
  */
3325
3310
  query: async (args) => {
3326
- const { client, tags, groq, params } = args;
3327
- if (validateTags(tags), !groq.includes("$engineTags"))
3311
+ const { client, tag, groq, params } = args;
3312
+ if (validateTag(tag), !/\$tag\b/.test(groq))
3328
3313
  throw new Error(
3329
- `workflow.query: query must filter on $engineTags to stay tag-scoped (e.g. "count(tags[@ in $engineTags]) > 0"); got: ${groq}`
3314
+ `workflow.query: query must filter on $tag to stay tag-scoped (e.g. "tag == $tag"); got: ${groq}`
3330
3315
  );
3331
- return client.fetch(groq, { ...params, engineTags: tags });
3316
+ return client.fetch(groq, { ...params, tag });
3332
3317
  },
3333
3318
  /**
3334
3319
  * Snapshot-aware GROQ — runs against the same in-memory view that
@@ -3347,9 +3332,9 @@ const workflow = {
3347
3332
  * without re-implementing hydration. Pure read — never writes.
3348
3333
  */
3349
3334
  queryInScope: async (args) => {
3350
- const { client, tags, instanceId, groq, params, resourceClients } = args, clock = args.clock ?? wallClock;
3351
- validateTags(tags);
3352
- const instance = await reload(client, instanceId, tags), clientForGdr = buildClientForGdr(client, resourceClients), snapshot = await hydrateSnapshot({ client, clientForGdr, instance }), reserved = buildParams({ instance, now: clock(), snapshot }), tree = parse(groq, { params: { ...reserved, ...params } });
3335
+ const { client, tag, instanceId, groq, params, resourceClients } = args, clock = args.clock ?? wallClock;
3336
+ validateTag(tag);
3337
+ const instance = await reload(client, instanceId, tag), clientForGdr = buildClientForGdr(client, resourceClients), snapshot = await hydrateSnapshot({ client, clientForGdr, instance }), reserved = buildParams({ instance, now: clock(), snapshot }), tree = parse(groq, { params: { ...reserved, ...params } });
3353
3338
  return await (await evaluate(tree, {
3354
3339
  dataset: snapshot.docs,
3355
3340
  params: { ...reserved, ...params }
@@ -3359,13 +3344,13 @@ const workflow = {
3359
3344
  * List every pending effect on the instance. Returns the same entries
3360
3345
  * the runtime would see — claimed and unclaimed alike.
3361
3346
  */
3362
- listPendingEffects: async (args) => (await reload(args.client, args.instanceId, args.tags)).pendingEffects,
3347
+ listPendingEffects: async (args) => (await reload(args.client, args.instanceId, args.tag)).pendingEffects,
3363
3348
  /**
3364
3349
  * Filter pending effects on the instance by criteria. `claimed`
3365
3350
  * filters on claim presence; `names` restricts to specific effect
3366
3351
  * names. Both filters compose (AND).
3367
3352
  */
3368
- findPendingEffects: async (args) => (await reload(args.client, args.instanceId, args.tags)).pendingEffects.filter((e) => !(args.claimed === !0 && e.claim === void 0 || args.claimed === !1 && e.claim !== void 0 || args.names !== void 0 && !args.names.includes(e.name))),
3353
+ findPendingEffects: async (args) => (await reload(args.client, args.instanceId, args.tag)).pendingEffects.filter((e) => !(args.claimed === !0 && e.claim === void 0 || args.claimed === !1 && e.claim !== void 0 || args.names !== void 0 && !args.names.includes(e.name))),
3369
3354
  /**
3370
3355
  * Project the instance from a given actor's perspective. Returns a
3371
3356
  * `WorkflowEvaluation` with per-action verdicts (`allowed` + a
@@ -3406,18 +3391,18 @@ const workflow = {
3406
3391
  * record. (The per-task `spawnedInstances` field on the active stage
3407
3392
  * only exists while that stage is current; history survives.) Strips
3408
3393
  * the GDR URI on each `instanceRef` to a bare `_id`, fetches the
3409
- * instances, drops any that aren't visible to this engine's tags, and
3394
+ * instances, drops any that aren't visible to this engine's tag, and
3410
3395
  * returns them sorted by `startedAt` ascending.
3411
3396
  *
3412
3397
  * Pass `task` to restrict to a single spawning task on the parent.
3413
3398
  */
3414
3399
  children: async (args) => {
3415
- const { client, tags, instanceId, task } = args;
3416
- validateTags(tags);
3417
- const parent = await reload(client, instanceId, tags), isSpawned = (h) => h._type === "spawned", ids = parent.history.filter(isSpawned).filter((h) => task === void 0 || h.task === task).flatMap((h) => bareIdFromSpawnRef(h.instanceRef.id));
3400
+ const { client, tag, instanceId, task } = args;
3401
+ validateTag(tag);
3402
+ const parent = await reload(client, instanceId, tag), isSpawned = (h) => h._type === "spawned", ids = parent.history.filter(isSpawned).filter((h) => task === void 0 || h.task === task).flatMap((h) => bareIdFromSpawnRef(h.instanceRef.id));
3418
3403
  return ids.length === 0 ? [] : client.fetch(
3419
3404
  `*[_id in $ids && ${tagScopeFilter()}] | order(startedAt asc)`,
3420
- { ids, engineTags: tags }
3405
+ { ids, tag }
3421
3406
  );
3422
3407
  },
3423
3408
  /**
@@ -3432,11 +3417,11 @@ const workflow = {
3432
3417
  }
3433
3418
  };
3434
3419
  async function verifyDeployedDefinitionsInternal(args) {
3435
- const { client, tags, effectHandlers, missingHandler, logger } = args;
3436
- validateTags(tags);
3420
+ const { client, tag, effectHandlers, missingHandler, logger } = args;
3421
+ validateTag(tag);
3437
3422
  const log = logger("verifyDeployedDefinitions"), definitions = await client.fetch(
3438
3423
  `*[_type == "${WORKFLOW_DEFINITION_TYPE}" && ${tagScopeFilter()}] | order(name asc, version asc)`,
3439
- { engineTags: tags }
3424
+ { tag }
3440
3425
  ), seen = [], missingByName = /* @__PURE__ */ new Map();
3441
3426
  for (const def of definitions)
3442
3427
  seen.push({ name: def.name, version: def.version, _id: def._id }), walkEffectNames(def, (name, location) => {
@@ -3485,7 +3470,7 @@ function walkEffectNames(def, visit) {
3485
3470
  async function drainEffectsInternal(args) {
3486
3471
  const {
3487
3472
  client,
3488
- tags,
3473
+ tag,
3489
3474
  workflowResource,
3490
3475
  resourceClients,
3491
3476
  instanceId,
@@ -3496,10 +3481,10 @@ async function drainEffectsInternal(args) {
3496
3481
  actor: drainerActor,
3497
3482
  ...args.access?.grants !== void 0 ? { grants: args.access.grants } : {}
3498
3483
  };
3499
- validateTags(tags);
3484
+ validateTag(tag);
3500
3485
  const log = logger("drainEffects"), drained = [], failed = [], skipped = [], skippedKeys = /* @__PURE__ */ new Set();
3501
3486
  for (; ; ) {
3502
- const before = await reload(client, instanceId, tags), candidate = before.pendingEffects.find(
3487
+ const before = await reload(client, instanceId, tag), candidate = before.pendingEffects.find(
3503
3488
  (e) => e.claim === void 0 && !skippedKeys.has(e._key)
3504
3489
  );
3505
3490
  if (candidate === void 0) break;
@@ -3516,7 +3501,7 @@ async function drainEffectsInternal(args) {
3516
3501
  });
3517
3502
  await reportEffectOutcome({
3518
3503
  client,
3519
- tags,
3504
+ tag,
3520
3505
  workflowResource,
3521
3506
  ...resourceClients !== void 0 ? { resourceClients } : {},
3522
3507
  instanceId,
@@ -3586,7 +3571,7 @@ async function applyMissingHandler(policy, info, log) {
3586
3571
  }
3587
3572
  }
3588
3573
  function createInstanceSession(args) {
3589
- const { client, tags, clock } = args, clientForGdr = buildClientForGdr(client, args.resourceClients);
3574
+ const { client, tag, clock } = args, clientForGdr = buildClientForGdr(client, args.resourceClients);
3590
3575
  let instance = asHeldInstance(args.instance), overlay = /* @__PURE__ */ new Map(), heldGuards = [], committing = !1, buffered;
3591
3576
  const selfUri = () => gdrFromResource(instance.workflowResource, instance._id), applyUpdate = (docs) => {
3592
3577
  const next = /* @__PURE__ */ new Map();
@@ -3647,7 +3632,7 @@ function createInstanceSession(args) {
3647
3632
  return commit(async (actor, held) => {
3648
3633
  await assertInstanceWriteAllowed({ instance, guards: heldGuards, identity: actor.id });
3649
3634
  const cascaded = await cascade(client, instance._id, actor, clientForGdr, clock, held);
3650
- return instance = await reload(client, instance._id, tags), { instance, cascaded, fired: cascaded > 0 };
3635
+ return instance = await reload(client, instance._id, tag), { instance, cascaded, fired: cascaded > 0 };
3651
3636
  });
3652
3637
  },
3653
3638
  fireAction({ task, action, params }) {
@@ -3664,7 +3649,7 @@ function createInstanceSession(args) {
3664
3649
  ...clock !== void 0 ? { clock } : {},
3665
3650
  ...params !== void 0 ? { params } : {}
3666
3651
  }), cascaded = await cascade(client, instance._id, actor, clientForGdr, clock, held);
3667
- return instance = await reload(client, instance._id, tags), { instance, cascaded, fired: !0, ...ranOps !== void 0 ? { ranOps } : {} };
3652
+ return instance = await reload(client, instance._id, tag), { instance, cascaded, fired: !0, ...ranOps !== void 0 ? { ranOps } : {} };
3668
3653
  });
3669
3654
  }
3670
3655
  };
@@ -3692,11 +3677,11 @@ const defaultLoggerFactory = (name) => ({
3692
3677
  }
3693
3678
  };
3694
3679
  function createEngine(args) {
3695
- const { client, workflowResource, tags, resourceClients, clock } = args;
3696
- validateTags(tags);
3680
+ const { client, workflowResource, resourceClients, clock, tag } = args;
3681
+ validateTag(tag);
3697
3682
  const effectHandlers = args.effectHandlers ?? {}, missingHandler = args.missingHandler ?? "fail", logger = args.loggerFactory ?? defaultLoggerFactory, bind = (rest) => ({
3698
3683
  client,
3699
- tags,
3684
+ tag,
3700
3685
  workflowResource,
3701
3686
  ...resourceClients !== void 0 ? { resourceClients } : {},
3702
3687
  ...clock !== void 0 ? { clock } : {},
@@ -3704,7 +3689,7 @@ function createEngine(args) {
3704
3689
  });
3705
3690
  return {
3706
3691
  client,
3707
- tags,
3692
+ tag,
3708
3693
  workflowResource,
3709
3694
  effectHandlers,
3710
3695
  missingHandler,
@@ -3720,11 +3705,11 @@ function createEngine(args) {
3720
3705
  setStage: (rest) => workflow.setStage(bind(rest)),
3721
3706
  abortInstance: (rest) => workflow.abortInstance(bind(rest)),
3722
3707
  deleteDefinition: (rest) => workflow.deleteDefinition(bind(rest)),
3723
- getInstance: ({ instanceId }) => workflow.getInstance({ client, tags, workflowResource, instanceId }),
3724
- subscriptionDocumentsForInstance: ({ instanceId }) => workflow.getInstance({ client, tags, workflowResource, instanceId }).then(subscriptionDocumentsForInstance),
3708
+ getInstance: ({ instanceId }) => workflow.getInstance({ client, tag, workflowResource, instanceId }),
3709
+ subscriptionDocumentsForInstance: ({ instanceId }) => workflow.getInstance({ client, tag, workflowResource, instanceId }).then(subscriptionDocumentsForInstance),
3725
3710
  instance: (instanceDoc, opts) => createInstanceSession({
3726
3711
  client,
3727
- tags,
3712
+ tag,
3728
3713
  instance: instanceDoc,
3729
3714
  ...resourceClients !== void 0 ? { resourceClients } : {},
3730
3715
  ...clock !== void 0 ? { clock } : {},
@@ -3733,45 +3718,45 @@ function createEngine(args) {
3733
3718
  }),
3734
3719
  guardsForInstance: ({ instanceId }) => workflow.guardsForInstance({
3735
3720
  client,
3736
- tags,
3721
+ tag,
3737
3722
  workflowResource,
3738
3723
  instanceId,
3739
3724
  ...resourceClients !== void 0 ? { resourceClients } : {}
3740
3725
  }),
3741
3726
  guardsForDefinition: ({ definition }) => workflow.guardsForDefinition({
3742
3727
  client,
3743
- tags,
3728
+ tag,
3744
3729
  workflowResource,
3745
3730
  definition,
3746
3731
  ...resourceClients !== void 0 ? { resourceClients } : {}
3747
3732
  }),
3748
3733
  children: ({ instanceId, task }) => workflow.children({
3749
3734
  client,
3750
- tags,
3735
+ tag,
3751
3736
  workflowResource,
3752
3737
  instanceId,
3753
3738
  ...task !== void 0 ? { task } : {}
3754
3739
  }),
3755
3740
  query: ({ groq, params }) => workflow.query({
3756
3741
  client,
3757
- tags,
3742
+ tag,
3758
3743
  workflowResource,
3759
3744
  groq,
3760
3745
  ...params !== void 0 ? { params } : {}
3761
3746
  }),
3762
3747
  queryInScope: ({ instanceId, groq, params }) => workflow.queryInScope({
3763
3748
  client,
3764
- tags,
3749
+ tag,
3765
3750
  workflowResource,
3766
3751
  instanceId,
3767
3752
  groq,
3768
3753
  ...params !== void 0 ? { params } : {},
3769
3754
  ...clock !== void 0 ? { clock } : {}
3770
3755
  }),
3771
- listPendingEffects: ({ instanceId }) => workflow.listPendingEffects({ client, tags, workflowResource, instanceId }),
3756
+ listPendingEffects: ({ instanceId }) => workflow.listPendingEffects({ client, tag, workflowResource, instanceId }),
3772
3757
  findPendingEffects: ({ instanceId, claimed, names }) => workflow.findPendingEffects({
3773
3758
  client,
3774
- tags,
3759
+ tag,
3775
3760
  workflowResource,
3776
3761
  instanceId,
3777
3762
  ...claimed !== void 0 ? { claimed } : {},
@@ -3779,7 +3764,7 @@ function createEngine(args) {
3779
3764
  }),
3780
3765
  drainEffects: ({ instanceId, access }) => drainEffectsInternal({
3781
3766
  client,
3782
- tags,
3767
+ tag,
3783
3768
  workflowResource,
3784
3769
  ...resourceClients !== void 0 ? { resourceClients } : {},
3785
3770
  instanceId,
@@ -3790,7 +3775,7 @@ function createEngine(args) {
3790
3775
  }),
3791
3776
  verifyDeployedDefinitions: () => verifyDeployedDefinitionsInternal({
3792
3777
  client,
3793
- tags,
3778
+ tag,
3794
3779
  effectHandlers,
3795
3780
  missingHandler,
3796
3781
  logger
@@ -3798,7 +3783,7 @@ function createEngine(args) {
3798
3783
  };
3799
3784
  }
3800
3785
  function docIdFor(def, target) {
3801
- return definitionDocId(target.workflowResource, canonicalTag(target.tags), def.name, def.version);
3786
+ return definitionDocId(target.workflowResource, target.tag, def.name, def.version);
3802
3787
  }
3803
3788
  function diffStatus(existing, expected) {
3804
3789
  return existing === void 0 ? "create" : isDefinitionUnchanged(existing, expected) ? "unchanged" : "update";
@@ -3808,7 +3793,7 @@ function diffEntry(def, existingRaw, target) {
3808
3793
  ...def,
3809
3794
  _id: docId,
3810
3795
  _type: WORKFLOW_DEFINITION_TYPE,
3811
- tags: target.tags
3796
+ tag: target.tag
3812
3797
  }, status = diffStatus(existingRaw, expected), existing = existingRaw ? stripSystemFields(existingRaw) : void 0;
3813
3798
  return {
3814
3799
  name: def.name,
@@ -4025,7 +4010,6 @@ export {
4025
4010
  assigneesOf,
4026
4011
  availableActions,
4027
4012
  buildSnapshot,
4028
- canonicalTag,
4029
4013
  compileGuard,
4030
4014
  computeDiffEntries,
4031
4015
  contentReleaseName,
@@ -4071,7 +4055,7 @@ export {
4071
4055
  subscriptionDocumentsForInstance,
4072
4056
  tagScopeFilter,
4073
4057
  validateDefinition,
4074
- validateTags,
4058
+ validateTag,
4075
4059
  verdictGuardsForInstance,
4076
4060
  wallClock,
4077
4061
  workflow