@sanity/workflow-engine 0.4.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.d.cts CHANGED
@@ -6,6 +6,11 @@ export declare interface AbortInstanceArgs extends OperationArgs {
6
6
  reason?: string;
7
7
  }
8
8
 
9
+ /** The free-text reason recorded on the aborted history entry, if any. */
10
+ export declare function abortReason(
11
+ instance: Pick<WorkflowInstance, "history">,
12
+ ): string | undefined;
13
+
9
14
  export declare type Action = v.InferOutput<typeof StoredActionSchema>;
10
15
 
11
16
  export declare class ActionDisabledError extends Error {
@@ -90,6 +95,17 @@ export declare class ActionParamsInvalidError extends Error {
90
95
  });
91
96
  }
92
97
 
98
+ /** The fireable-action verdict for one action on a task — its `allowed`
99
+ * state, structured `disabledReason`, and declared params, tagged with the
100
+ * owning task. The per-action atom both projections share:
101
+ * {@link availableActions} flattens it across a stage's tasks; a consumer
102
+ * that keeps per-task nesting (e.g. the MCP) maps it over a task's actions
103
+ * directly, so the verdict shape has a single source. */
104
+ export declare function actionVerdict(
105
+ task: TaskEvaluation,
106
+ action: ActionEvaluation,
107
+ ): AvailableAction;
108
+
93
109
  export declare interface Actor {
94
110
  kind: "user" | "ai" | "system";
95
111
  id: string;
@@ -120,6 +136,13 @@ export declare type Assignee =
120
136
  role: string;
121
137
  };
122
138
 
139
+ /** The assignees recorded for a task in a stage — the runtime half of the
140
+ * "who is this waiting on" answer. Empty when the task is unassigned. */
141
+ export declare function assigneesOf(
142
+ stage: StageEntry | undefined,
143
+ taskName: string,
144
+ ): Assignee[];
145
+
123
146
  /**
124
147
  * Persisted document and effect-queue `_type` discriminators.
125
148
  */
@@ -6497,13 +6520,37 @@ declare const AuthoringWorkflowSchema: v.StrictObjectSchema<
6497
6520
  undefined
6498
6521
  >;
6499
6522
 
6523
+ export declare interface AvailableAction {
6524
+ task: string;
6525
+ taskStatus: TaskStatus;
6526
+ action: string;
6527
+ title: string | undefined;
6528
+ allowed: boolean;
6529
+ disabledReason: DisabledReason | undefined;
6530
+ params: ActionParam[];
6531
+ }
6532
+
6533
+ /** Flatten an evaluation's current-stage tasks into the actions the actor
6534
+ * could fire, each carrying whether it's allowed (and why not). */
6535
+ export declare function availableActions(
6536
+ tasks: TaskEvaluation[],
6537
+ ): AvailableAction[];
6538
+
6539
+ /** The `workflow.availableActions` result — the projected actions plus the
6540
+ * evaluation they came from, so a consumer can read the instance/stage
6541
+ * context without a second projection. */
6542
+ export declare interface AvailableActionsResult {
6543
+ evaluation: WorkflowEvaluation;
6544
+ actions: AvailableAction[];
6545
+ }
6546
+
6500
6547
  declare type Bound<
6501
6548
  Args extends {
6502
6549
  client: WorkflowClient;
6503
- tags: string[];
6550
+ tag: string;
6504
6551
  workflowResource: WorkflowResource;
6505
6552
  },
6506
- > = Omit<Args, "client" | "tags" | "workflowResource">;
6553
+ > = Omit<Args, "client" | "tag" | "workflowResource">;
6507
6554
 
6508
6555
  /**
6509
6556
  * Build a snapshot from a set of loaded docs. Pure transform.
@@ -6523,8 +6570,6 @@ export declare function buildSnapshot(args: {
6523
6570
  docs: LoadedDoc[];
6524
6571
  }): HydratedSnapshot;
6525
6572
 
6526
- export declare function canonicalTag(tags: string[]): string;
6527
-
6528
6573
  /**
6529
6574
  * Thrown when auto-transitions on an instance fail to stabilise within
6530
6575
  * {@link CascadeLimitError.limit} passes — the signature of a runaway
@@ -6612,6 +6657,13 @@ export declare interface CompleteEffectArgs extends OperationArgs {
6612
6657
  durationMs?: number;
6613
6658
  }
6614
6659
 
6660
+ /** Compare each definition against the deployed doc at its own docId. */
6661
+ export declare function computeDiffEntries(
6662
+ client: Pick<WorkflowClient, "getDocument">,
6663
+ defs: WorkflowDefinition[],
6664
+ target: DeployTarget,
6665
+ ): Promise<DiffEntry[]>;
6666
+
6615
6667
  /**
6616
6668
  * Thrown when a `fireAction` commit loses the optimistic-locking race on
6617
6669
  * all {@link CONCURRENT_FIRE_ACTION_MAX_ATTEMPTS} attempts — every reload +
@@ -6659,10 +6711,11 @@ export declare function contentReleaseName(args: {
6659
6711
  }): string | undefined;
6660
6712
 
6661
6713
  /**
6662
- * Construct an engine bound to a workflow resource + tags. The returned
6714
+ * Construct an engine bound to a workflow resource + tag. The returned
6663
6715
  * object exposes the same verbs as the `workflow.*` namespace, minus
6664
- * the boilerplate config arguments (client / tags / workflowResource)
6665
- * which are pinned at construction.
6716
+ * the boilerplate config arguments (client / tag / workflowResource)
6717
+ * which are pinned at construction. The `tag` is required — see
6718
+ * {@link validateTag} for the accepted shape.
6666
6719
  *
6667
6720
  * Effect handlers + missingHandler are stored for future drain wiring
6668
6721
  * (Step 10). They have no effect on `fireAction` / `tick` /
@@ -6674,7 +6727,14 @@ export declare function createEngine(args: CreateEngineArgs): Engine;
6674
6727
  export declare interface CreateEngineArgs {
6675
6728
  client: WorkflowClient;
6676
6729
  workflowResource: WorkflowResource;
6677
- tags: string[];
6730
+ /**
6731
+ * Engine-scope environment partition (e.g. `"test"`, `"prod"`). Every
6732
+ * definition/instance the engine writes is stamped with this tag and
6733
+ * every read is scoped to it. Required and never defaulted — the engine
6734
+ * enforces nothing, so the partition is the only thing keeping reads and
6735
+ * writes off the wrong environment.
6736
+ */
6737
+ tag: string;
6678
6738
  /**
6679
6739
  * Optional routing for cross-resource reads. When the engine needs
6680
6740
  * a doc whose GDR points at a resource other than its own, it calls
@@ -6718,6 +6778,49 @@ export declare function datasetResourceParts(id: string): {
6718
6778
  */
6719
6779
  export declare const defaultLoggerFactory: LoggerFactory;
6720
6780
 
6781
+ export declare interface DeleteDefinitionArgs {
6782
+ client: WorkflowClient;
6783
+ /** Engine-scope environment partition — required. See {@link validateTag} + `tags.ts`. */
6784
+ tag: string;
6785
+ /** The Sanity resource the engine's own data lives in. */
6786
+ workflowResource: WorkflowResource;
6787
+ /** Cross-resource routing — see `StartInstanceArgs.resourceClients`. */
6788
+ resourceClients?: ResourceClientResolver;
6789
+ /** The definition's `name` — delete addresses the workflow, not a doc id. */
6790
+ definition: string;
6791
+ /** Delete only this deployed version. Default: every deployed version. */
6792
+ version?: number;
6793
+ /**
6794
+ * Abort every non-terminal instance pinned to the targeted versions
6795
+ * before deleting. Instances are ONLY aborted — instance documents are
6796
+ * never deleted; they stay in the lake as the audit record. Without
6797
+ * this flag the delete refuses when such instances exist.
6798
+ */
6799
+ cascade?: boolean;
6800
+ /** Free-text reason stamped on each cascade-abort history entry. */
6801
+ reason?: string;
6802
+ /** Optional access-state override — see `StartInstanceArgs.access`. */
6803
+ access?: WorkflowAccessOverride;
6804
+ /** URL path for grant resolution — see `StartInstanceArgs.grantsFromPath`. */
6805
+ grantsFromPath?: string;
6806
+ }
6807
+
6808
+ export declare interface DeleteDefinitionResult {
6809
+ /** The definition's `name`. */
6810
+ name: string;
6811
+ /** Versions actually removed, newest first. */
6812
+ deletedVersions: number[];
6813
+ /** Instances hard-stopped by `cascade`, in abort order. Empty without it. */
6814
+ abortedInstanceIds: string[];
6815
+ /**
6816
+ * Orphaned guard docs removed across the definition's statically-named
6817
+ * datasources. Only populated when the LAST version goes — guard docs
6818
+ * are stamped with the version-less `name`, so they stay while any
6819
+ * version remains deployed.
6820
+ */
6821
+ deletedGuardCount: number;
6822
+ }
6823
+
6721
6824
  /**
6722
6825
  * Run every guard whose `match` applies and collect those that DENY. Empty
6723
6826
  * result ⇒ allowed (optimistically).
@@ -6740,8 +6843,8 @@ export declare interface DeployDefinitionResult {
6740
6843
 
6741
6844
  export declare interface DeployDefinitionsArgs {
6742
6845
  client: WorkflowClient;
6743
- /** Engine-scope tags — required. See `validateTags` + `tags.ts`. */
6744
- tags: string[];
6846
+ /** Engine-scope environment partition — required. See {@link validateTag} + `tags.ts`. */
6847
+ tag: string;
6745
6848
  /**
6746
6849
  * The Sanity resource the engine's own data lives in. Used to mint
6747
6850
  * GDR URIs for every doc the engine writes (definitions, instances,
@@ -6771,6 +6874,103 @@ export declare interface DeployDefinitionsResult {
6771
6874
  */
6772
6875
  export declare function deployStageGuards(args: StageGuardArgs): Promise<void>;
6773
6876
 
6877
+ /** Where a definition deploys: the engine tag it partitions under, and the
6878
+ * workflow resource it belongs to. Structurally what `deployDefinitions`
6879
+ * receives, minus the definitions themselves. */
6880
+ export declare interface DeployTarget {
6881
+ tag: string;
6882
+ workflowResource: WorkflowResource;
6883
+ }
6884
+
6885
+ /**
6886
+ * The slice of an instance + its {@link WorkflowEvaluation} the classifier
6887
+ * reads. Narrowed so callers (and tests) can craft an exact stuck permutation
6888
+ * without standing up a full evaluation; {@link diagnoseInputFromEvaluation}
6889
+ * builds it from a real {@link WorkflowEvaluation}.
6890
+ */
6891
+ export declare interface DiagnoseInput {
6892
+ instance: Pick<
6893
+ WorkflowInstance,
6894
+ | "currentStage"
6895
+ | "stages"
6896
+ | "completedAt"
6897
+ | "abortedAt"
6898
+ | "effectHistory"
6899
+ | "pendingEffects"
6900
+ | "history"
6901
+ >;
6902
+ tasks: TaskEvaluation[];
6903
+ transitions: TransitionEvaluation[];
6904
+ }
6905
+
6906
+ /** Narrow a full {@link WorkflowEvaluation} to the {@link DiagnoseInput} the
6907
+ * classifier reads. */
6908
+ export declare function diagnoseInputFromEvaluation(
6909
+ evaluation: WorkflowEvaluation,
6910
+ ): DiagnoseInput;
6911
+
6912
+ /**
6913
+ * Classify an instance. Terminal states win first; then the genuine stuck
6914
+ * causes (nothing advances on its own or via a normal action); then `waiting`
6915
+ * (an action is available — healthy); else `progressing` (a transition is
6916
+ * already satisfied and will cascade).
6917
+ */
6918
+ export declare function diagnoseInstance(input: DiagnoseInput): Diagnosis;
6919
+
6920
+ /** The `workflow.diagnose` result — the verdict plus the evaluation it was
6921
+ * derived from, so a consumer can render the supporting evidence (current
6922
+ * stage tasks + transitions) without a second projection. */
6923
+ export declare interface DiagnoseResult {
6924
+ evaluation: WorkflowEvaluation;
6925
+ diagnosis: Diagnosis;
6926
+ }
6927
+
6928
+ export declare type Diagnosis =
6929
+ | {
6930
+ state: "progressing";
6931
+ }
6932
+ | {
6933
+ state: "waiting";
6934
+ task: string;
6935
+ assignees: Assignee[];
6936
+ actions: string[];
6937
+ }
6938
+ | {
6939
+ state: "completed";
6940
+ at: string;
6941
+ }
6942
+ | {
6943
+ state: "aborted";
6944
+ at: string;
6945
+ reason?: string;
6946
+ }
6947
+ | {
6948
+ state: "stuck";
6949
+ cause: StuckCause;
6950
+ };
6951
+
6952
+ export declare interface DiffEntry {
6953
+ name: string;
6954
+ version: number;
6955
+ status: "create" | "update" | "unchanged";
6956
+ docId: string;
6957
+ expected: Record<string, unknown>;
6958
+ existing?: Record<string, unknown>;
6959
+ }
6960
+
6961
+ /**
6962
+ * Compare one local definition against a deployed document (or its
6963
+ * absence), classifying it as create / update / unchanged using the
6964
+ * engine's own no-op verdict. Pure — callers own the fetch, so the same
6965
+ * comparison serves both deploy's exact-docId lookup and `definition
6966
+ * diff`'s latest-version query.
6967
+ */
6968
+ export declare function diffEntry(
6969
+ def: WorkflowDefinition,
6970
+ existingRaw: Record<string, unknown> | undefined,
6971
+ target: DeployTarget,
6972
+ ): DiffEntry;
6973
+
6774
6974
  export declare type DisabledReason =
6775
6975
  | {
6776
6976
  /**
@@ -7045,7 +7245,7 @@ export declare interface Engine {
7045
7245
  * (e.g. test bench, drain workers) that need them; the verbs already
7046
7246
  * thread them through internally. */
7047
7247
  readonly client: WorkflowClient;
7048
- readonly tags: readonly string[];
7248
+ readonly tag: string;
7049
7249
  readonly workflowResource: WorkflowResource;
7050
7250
  readonly effectHandlers: Readonly<Record<string, EffectHandler>>;
7051
7251
  readonly missingHandler: MissingHandlerPolicy;
@@ -7060,10 +7260,22 @@ export declare interface Engine {
7060
7260
  evaluateInstance: (
7061
7261
  args: Bound<EvaluateArgs>,
7062
7262
  ) => ReturnType<typeof evaluateInstance>;
7263
+ /** Diagnose why an instance is or isn't progressing — a classified
7264
+ * {@link DiagnoseResult} plus the evaluation it was derived from. */
7265
+ diagnose: (args: Bound<EvaluateArgs>) => Promise<DiagnoseResult>;
7266
+ /** The actions firable on the instance's current stage, each flagged
7267
+ * allowed/disabled, plus the evaluation they came from. */
7268
+ availableActions: (
7269
+ args: Bound<EvaluateArgs>,
7270
+ ) => Promise<AvailableActionsResult>;
7063
7271
  /** Admin override — bypass filters/transitions and force the stage. */
7064
7272
  setStage: (args: Bound<SetStageArgs>) => Promise<DispatchResult>;
7065
7273
  /** Admin override — hard-stop an in-flight instance where it stands. */
7066
7274
  abortInstance: (args: Bound<AbortInstanceArgs>) => Promise<DispatchResult>;
7275
+ /** Admin override — remove a deployed definition (instances are only ever aborted, never deleted). */
7276
+ deleteDefinition: (
7277
+ args: Bound<DeleteDefinitionArgs>,
7278
+ ) => Promise<DeleteDefinitionResult>;
7067
7279
  /** Fetch a workflow instance by id. */
7068
7280
  getInstance: (args: { instanceId: string }) => Promise<WorkflowInstance>;
7069
7281
  /** The reactive {@link WatchSet} for an instance — every document whose
@@ -7110,8 +7322,8 @@ export declare interface Engine {
7110
7322
  instanceId: string;
7111
7323
  task?: string;
7112
7324
  }) => Promise<WorkflowInstance[]>;
7113
- /** GROQ query against the engine's workflow resource. `$engineTags`
7114
- * is bound for tag-aware filtering. */
7325
+ /** GROQ query against the engine's workflow resource. `$tag`
7326
+ * is bound for tag-scoped filtering. */
7115
7327
  query: <T = unknown>(args: {
7116
7328
  groq: string;
7117
7329
  params?: Record<string, unknown>;
@@ -7145,7 +7357,7 @@ export declare interface Engine {
7145
7357
  access?: WorkflowAccessOverride;
7146
7358
  }) => Promise<DrainEffectsResult>;
7147
7359
  /**
7148
- * Inspect every deployed definition in the engine's tags and apply
7360
+ * Inspect every deployed definition in the engine's tag and apply
7149
7361
  * the configured missingHandler policy at `phase: "deploy"` for any
7150
7362
  * effect name without a registered handler. Catches "definition
7151
7363
  * shipped, handler removed" misconfigurations at startup instead of
@@ -7165,8 +7377,8 @@ export declare interface EngineLogger {
7165
7377
 
7166
7378
  export declare interface EvaluateArgs {
7167
7379
  client: WorkflowClient;
7168
- /** Engine-scope tags — required. */
7169
- tags: string[];
7380
+ /** Engine-scope environment partition — required. */
7381
+ tag: string;
7170
7382
  /** Engine workflow resource — required. */
7171
7383
  workflowResource: WorkflowResource;
7172
7384
  instanceId: string;
@@ -8160,10 +8372,16 @@ export declare interface OpAppliedSummary {
8160
8372
  resolved?: Record<string, unknown>;
8161
8373
  }
8162
8374
 
8375
+ /** The instance's current, not-yet-exited {@link StageEntry}, if it has one —
8376
+ * the engine's canonical {@link findOpenStageEntry}, over the diagnosis input. */
8377
+ export declare function openStage(
8378
+ instance: Pick<WorkflowInstance, "currentStage" | "stages">,
8379
+ ): StageEntry | undefined;
8380
+
8163
8381
  export declare interface OperationArgs {
8164
8382
  client: WorkflowClient;
8165
- /** Engine-scope tags — required. */
8166
- tags: string[];
8383
+ /** Engine-scope environment partition — required. */
8384
+ tag: string;
8167
8385
  /** The Sanity resource the engine's own data lives in. */
8168
8386
  workflowResource: WorkflowResource;
8169
8387
  /** Cross-resource routing — see `StartInstanceArgs.resourceClients`. */
@@ -8502,8 +8720,8 @@ export declare type StageName = string;
8502
8720
 
8503
8721
  export declare interface StartInstanceArgs {
8504
8722
  client: WorkflowClient;
8505
- /** Engine-scope tags — required. */
8506
- tags: string[];
8723
+ /** Engine-scope environment partition — required. */
8724
+ tag: string;
8507
8725
  /** The Sanity resource the engine's own data lives in. */
8508
8726
  workflowResource: WorkflowResource;
8509
8727
  /**
@@ -11417,6 +11635,31 @@ export declare function stripSystemFields(
11417
11635
  doc: Record<string, unknown>,
11418
11636
  ): Record<string, unknown>;
11419
11637
 
11638
+ /**
11639
+ * Why an in-flight instance is genuinely blocked — nothing advances it on its
11640
+ * own OR via a normal action. Ordered most- to least-actionable in
11641
+ * {@link diagnoseInstance}: a failed effect is the root cause even when it left
11642
+ * its task looking merely "active", so it wins over the task- and
11643
+ * transition-level symptoms it produces. Note an active task awaiting a human
11644
+ * action is NOT here — that's the healthy {@link Diagnosis} `waiting` state.
11645
+ */
11646
+ export declare type StuckCause =
11647
+ | {
11648
+ kind: "failed-effect";
11649
+ effect: EffectHistoryEntry;
11650
+ }
11651
+ | {
11652
+ kind: "hung-effect";
11653
+ effect: PendingEffect;
11654
+ }
11655
+ | {
11656
+ kind: "failed-task";
11657
+ task: string;
11658
+ }
11659
+ | {
11660
+ kind: "no-transition-fires";
11661
+ };
11662
+
11420
11663
  /**
11421
11664
  * A document the reactive layer should subscribe to, with its GDR
11422
11665
  * exploded so consumers never re-parse: the resource-addressing parts
@@ -11532,13 +11775,11 @@ declare const SubworkflowsSchema: v.StrictObjectSchema<
11532
11775
 
11533
11776
  /**
11534
11777
  * The engine's read-partition invariant as a GROQ predicate: a document is
11535
- * visible when its `tags[]` intersect the caller's tag set.
11536
- *
11537
- * @param param - GROQ parameter holding the caller's tags. Defaults to
11538
- * `engineTags`, matching the `workflow.query` guard so any query built with
11539
- * it stays tag-scoped.
11778
+ * visible when its `tag` equals the caller's `$tag` param. The single
11779
+ * definition of "tag-scoped" shared by the engine's internal lookups, the
11780
+ * `workflow.query` guard, and the CLI/MCP read helpers.
11540
11781
  */
11541
- export declare function tagScopeFilter(param?: string): string;
11782
+ export declare function tagScopeFilter(): string;
11542
11783
 
11543
11784
  export declare type Task = v.InferOutput<typeof StoredTaskSchema>;
11544
11785
 
@@ -11628,18 +11869,25 @@ export declare function validateDefinition(
11628
11869
  ): void;
11629
11870
 
11630
11871
  /**
11631
- * Engine-scope tags — the multi-tenant isolation primitive.
11872
+ * Engine-scope tag — the environment partition primitive.
11873
+ *
11874
+ * Every engine operates against exactly one `tag` ("test", "prod", …).
11875
+ * The tag partitions definitions and instances within a single workflow
11876
+ * resource: `deploy(def, tag: "test")` and `deploy(def, tag: "prod")` are
11877
+ * separate deployed workflows with independent lifecycles, and every read
11878
+ * is scoped to one tag so test runs never surface in prod.
11632
11879
  *
11633
- * Every engine takes a required `tags: string[]` set at construction.
11634
- * Tags must be Sanity-ID-compatible since they're joined into IDs with
11635
- * `.` ASCII lowercase + digits + dashes, no leading dash, no dots.
11880
+ * The tag must be Sanity-ID-compatible since it's joined into IDs with
11881
+ * `.` ASCII lowercase + digits + dashes, no leading dash, no dots. It
11882
+ * is also the ID prefix for every definition/instance the engine writes.
11636
11883
  *
11637
- * The first tag in the array is the *canonical* tag, used as the ID
11638
- * prefix when the engine writes new definitions or instances. The full
11639
- * tag set goes onto every written doc and is the basis for read
11640
- * filtering (tag intersection between engine and doc).
11884
+ * There is no default. The tag selects which environment the engine reads
11885
+ * and writes, and the engine enforces nothing so the partition is the
11886
+ * only thing keeping test runs out of prod. Every entry point
11887
+ * (`createEngine`, the CLI, the MCP server) requires it explicitly and
11888
+ * fails when it's absent rather than guessing an environment.
11641
11889
  */
11642
- export declare function validateTags(tags: string[]): void;
11890
+ export declare function validateTag(tag: string): void;
11643
11891
 
11644
11892
  /**
11645
11893
  * The guards allowed to influence this instance's verdicts, read from the
@@ -11729,6 +11977,16 @@ export declare const workflow: {
11729
11977
  deployDefinitions: (
11730
11978
  args: DeployDefinitionsArgs,
11731
11979
  ) => Promise<DeployDefinitionsResult>;
11980
+ /**
11981
+ * Remove a deployed workflow definition (all versions, or one via
11982
+ * `version`). Refuses while non-terminal instances exist unless
11983
+ * `cascade` aborts them first — instances are never deleted, only
11984
+ * aborted in place; see {@link deleteDefinitionInternal} for the
11985
+ * full contract (spawn-referrer check, guard-doc housekeeping).
11986
+ */
11987
+ deleteDefinition: (
11988
+ args: Clocked<DeleteDefinitionArgs>,
11989
+ ) => Promise<DeleteDefinitionResult>;
11732
11990
  /**
11733
11991
  * Spawn a new workflow instance from a deployed definition.
11734
11992
  *
@@ -11779,51 +12037,49 @@ export declare const workflow: {
11779
12037
  setStage: (args: Clocked<SetStageArgs>) => Promise<DispatchResult>;
11780
12038
  /**
11781
12039
  * Admin override — hard-stop an in-flight instance where it stands.
11782
- * No stage move, no transition effects, pending effects cancelled; see
11783
- * the engine-level {@link engineAbortInstance} for the full contract.
11784
- * Ancestors are propagated (not cascaded — the instance is terminal)
11785
- * so a parent gate waiting on this child re-evaluates.
12040
+ * No stage move, no transition effects, pending effects cancelled;
12041
+ * see {@link abortAndPropagate} for the abort + ancestor-propagation
12042
+ * contract (propagated, not cascaded — the instance is terminal).
11786
12043
  */
11787
12044
  abortInstance: (args: Clocked<AbortInstanceArgs>) => Promise<DispatchResult>;
11788
12045
  /**
11789
- * Fetch a workflow instance by id, scoped to the engine's tags.
12046
+ * Fetch a workflow instance by id, scoped to the engine's tag.
11790
12047
  * Throws when the instance doesn't exist or isn't visible to this
11791
12048
  * engine.
11792
12049
  */
11793
12050
  getInstance: (args: {
11794
12051
  client: WorkflowClient;
11795
- tags: string[];
12052
+ tag: string;
11796
12053
  workflowResource: WorkflowResource;
11797
12054
  instanceId: string;
11798
12055
  }) => Promise<WorkflowInstance>;
11799
12056
  guardsForInstance: (args: {
11800
12057
  client: WorkflowClient;
11801
- tags: string[];
12058
+ tag: string;
11802
12059
  workflowResource: WorkflowResource;
11803
12060
  instanceId: string;
11804
12061
  resourceClients?: ResourceClientResolver;
11805
12062
  }) => Promise<MutationGuardDoc[]>;
11806
12063
  guardsForDefinition: (args: {
11807
12064
  client: WorkflowClient;
11808
- tags: string[];
12065
+ tag: string;
11809
12066
  workflowResource: WorkflowResource;
11810
12067
  /** The definition's `name`. */
11811
12068
  definition: string;
11812
12069
  resourceClients?: ResourceClientResolver;
11813
12070
  }) => Promise<MutationGuardDoc[]>;
11814
12071
  /**
11815
- * Run a caller-supplied GROQ query with the engine's tags bound as
11816
- * `$engineTags`. This does NOT rewrite the query — arbitrary GROQ
12072
+ * Run a caller-supplied GROQ query with the engine's tag bound as
12073
+ * `$tag`. This does NOT rewrite the query — arbitrary GROQ
11817
12074
  * can't be safely tag-scoped after the fact — so the CALLER MUST
11818
- * filter on `$engineTags` (e.g.
11819
- * `count(tags[@ in $engineTags]) > 0`). To guard against accidental
11820
- * cross-tenant reads, a query that never references `$engineTags` is
12075
+ * filter on `$tag` (e.g. `tag == $tag`). To guard against accidental
12076
+ * cross-partition reads, a query that never references `$tag` is
11821
12077
  * rejected before it reaches the lake. Caller is responsible for type
11822
12078
  * narrowing the result.
11823
12079
  */
11824
12080
  query: <T = unknown>(args: {
11825
12081
  client: WorkflowClient;
11826
- tags: string[];
12082
+ tag: string;
11827
12083
  workflowResource: WorkflowResource;
11828
12084
  groq: string;
11829
12085
  params?: Record<string, unknown>;
@@ -11847,7 +12103,7 @@ export declare const workflow: {
11847
12103
  queryInScope: <T = unknown>(
11848
12104
  args: Clocked<{
11849
12105
  client: WorkflowClient;
11850
- tags: string[];
12106
+ tag: string;
11851
12107
  workflowResource: WorkflowResource;
11852
12108
  resourceClients?: ResourceClientResolver;
11853
12109
  instanceId: string;
@@ -11861,7 +12117,7 @@ export declare const workflow: {
11861
12117
  */
11862
12118
  listPendingEffects: (args: {
11863
12119
  client: WorkflowClient;
11864
- tags: string[];
12120
+ tag: string;
11865
12121
  workflowResource: WorkflowResource;
11866
12122
  instanceId: string;
11867
12123
  }) => Promise<PendingEffect[]>;
@@ -11872,7 +12128,7 @@ export declare const workflow: {
11872
12128
  */
11873
12129
  findPendingEffects: (args: {
11874
12130
  client: WorkflowClient;
11875
- tags: string[];
12131
+ tag: string;
11876
12132
  workflowResource: WorkflowResource;
11877
12133
  instanceId: string;
11878
12134
  claimed?: boolean;
@@ -11887,6 +12143,26 @@ export declare const workflow: {
11887
12143
  * `fireAction` to gate writes via the same logic.
11888
12144
  */
11889
12145
  evaluate: (args: Clocked<EvaluateArgs>) => Promise<WorkflowEvaluation>;
12146
+ /**
12147
+ * Diagnose why an instance is or isn't progressing. Projects the
12148
+ * instance (the same read as `evaluate`) and classifies it — terminal,
12149
+ * `progressing`, `waiting` (an action is available — healthy), or `stuck`
12150
+ * with a structured cause — returning that verdict as a
12151
+ * {@link DiagnoseResult} alongside the evaluation it came from, so a
12152
+ * consumer can render the supporting evidence without a second projection.
12153
+ * Pure read.
12154
+ */
12155
+ diagnose: (args: Clocked<EvaluateArgs>) => Promise<DiagnoseResult>;
12156
+ /**
12157
+ * List the actions an actor could fire on an instance's current stage,
12158
+ * each flagged `allowed` (with a structured `disabledReason` when not).
12159
+ * Projects the instance from the actor's perspective and flattens its
12160
+ * tasks' actions. Returns the evaluation alongside the actions so a
12161
+ * consumer can read the instance/stage context. Pure read.
12162
+ */
12163
+ availableActions: (
12164
+ args: Clocked<EvaluateArgs>,
12165
+ ) => Promise<AvailableActionsResult>;
11890
12166
  /**
11891
12167
  * Materialised spawned children of a parent instance.
11892
12168
  *
@@ -11894,14 +12170,14 @@ export declare const workflow: {
11894
12170
  * record. (The per-task `spawnedInstances` field on the active stage
11895
12171
  * only exists while that stage is current; history survives.) Strips
11896
12172
  * the GDR URI on each `instanceRef` to a bare `_id`, fetches the
11897
- * instances, drops any that aren't visible to this engine's tags, and
12173
+ * instances, drops any that aren't visible to this engine's tag, and
11898
12174
  * returns them sorted by `startedAt` ascending.
11899
12175
  *
11900
12176
  * Pass `task` to restrict to a single spawning task on the parent.
11901
12177
  */
11902
12178
  children: (args: {
11903
12179
  client: WorkflowClient;
11904
- tags: string[];
12180
+ tag: string;
11905
12181
  workflowResource: WorkflowResource;
11906
12182
  instanceId: string;
11907
12183
  task?: string;
@@ -13854,11 +14130,11 @@ export declare interface WorkflowFetchOptions {
13854
14130
  export declare interface WorkflowInstance extends SanityDocument {
13855
14131
  _type: typeof WORKFLOW_INSTANCE_TYPE;
13856
14132
  /**
13857
- * Engine-scope tags stamped on the instance at create time. Engines
13858
- * with disjoint tag sets cannot read this instance; engines sharing
13859
- * any tag with this array can.
14133
+ * Engine-scope environment partition stamped on the instance at create
14134
+ * time. Reads are scoped to a single tag, so an engine only sees
14135
+ * instances whose `tag` equals its own.
13860
14136
  */
13861
- tags: string[];
14137
+ tag: string;
13862
14138
  /**
13863
14139
  * The Sanity resource this instance lives in. Stored on the doc so
13864
14140
  * any internal operation can mint GDRs for ancestors / spawned
@@ -14041,6 +14317,15 @@ export declare interface WorkflowTransaction {
14041
14317
  * clients drain it structurally.
14042
14318
  */
14043
14319
  patch: (patch: any) => WorkflowTransaction;
14320
+ /**
14321
+ * Queue a document delete. Deliberately a transaction-only capability —
14322
+ * the top-level client surface stays delete-free so no engine code path
14323
+ * can casually remove documents; the sole consumer is `deleteDefinition`
14324
+ * housekeeping (definition docs + orphaned guard docs). Both the real
14325
+ * `@sanity/client` Transaction and the test fake's TransactionHandle
14326
+ * carry this shape.
14327
+ */
14328
+ delete: (id: string) => WorkflowTransaction;
14044
14329
  commit: () => Promise<unknown>;
14045
14330
  }
14046
14331