@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.d.cts CHANGED
@@ -6547,10 +6547,10 @@ export declare interface AvailableActionsResult {
6547
6547
  declare type Bound<
6548
6548
  Args extends {
6549
6549
  client: WorkflowClient;
6550
- tags: string[];
6550
+ tag: string;
6551
6551
  workflowResource: WorkflowResource;
6552
6552
  },
6553
- > = Omit<Args, "client" | "tags" | "workflowResource">;
6553
+ > = Omit<Args, "client" | "tag" | "workflowResource">;
6554
6554
 
6555
6555
  /**
6556
6556
  * Build a snapshot from a set of loaded docs. Pure transform.
@@ -6570,8 +6570,6 @@ export declare function buildSnapshot(args: {
6570
6570
  docs: LoadedDoc[];
6571
6571
  }): HydratedSnapshot;
6572
6572
 
6573
- export declare function canonicalTag(tags: string[]): string;
6574
-
6575
6573
  /**
6576
6574
  * Thrown when auto-transitions on an instance fail to stabilise within
6577
6575
  * {@link CascadeLimitError.limit} passes — the signature of a runaway
@@ -6713,10 +6711,11 @@ export declare function contentReleaseName(args: {
6713
6711
  }): string | undefined;
6714
6712
 
6715
6713
  /**
6716
- * Construct an engine bound to a workflow resource + tags. The returned
6714
+ * Construct an engine bound to a workflow resource + tag. The returned
6717
6715
  * object exposes the same verbs as the `workflow.*` namespace, minus
6718
- * the boilerplate config arguments (client / tags / workflowResource)
6719
- * 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.
6720
6719
  *
6721
6720
  * Effect handlers + missingHandler are stored for future drain wiring
6722
6721
  * (Step 10). They have no effect on `fireAction` / `tick` /
@@ -6728,7 +6727,14 @@ export declare function createEngine(args: CreateEngineArgs): Engine;
6728
6727
  export declare interface CreateEngineArgs {
6729
6728
  client: WorkflowClient;
6730
6729
  workflowResource: WorkflowResource;
6731
- 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;
6732
6738
  /**
6733
6739
  * Optional routing for cross-resource reads. When the engine needs
6734
6740
  * a doc whose GDR points at a resource other than its own, it calls
@@ -6774,8 +6780,8 @@ export declare const defaultLoggerFactory: LoggerFactory;
6774
6780
 
6775
6781
  export declare interface DeleteDefinitionArgs {
6776
6782
  client: WorkflowClient;
6777
- /** Engine-scope tags — required. See `validateTags` + `tags.ts`. */
6778
- tags: string[];
6783
+ /** Engine-scope environment partition — required. See {@link validateTag} + `tags.ts`. */
6784
+ tag: string;
6779
6785
  /** The Sanity resource the engine's own data lives in. */
6780
6786
  workflowResource: WorkflowResource;
6781
6787
  /** Cross-resource routing — see `StartInstanceArgs.resourceClients`. */
@@ -6837,8 +6843,8 @@ export declare interface DeployDefinitionResult {
6837
6843
 
6838
6844
  export declare interface DeployDefinitionsArgs {
6839
6845
  client: WorkflowClient;
6840
- /** Engine-scope tags — required. See `validateTags` + `tags.ts`. */
6841
- tags: string[];
6846
+ /** Engine-scope environment partition — required. See {@link validateTag} + `tags.ts`. */
6847
+ tag: string;
6842
6848
  /**
6843
6849
  * The Sanity resource the engine's own data lives in. Used to mint
6844
6850
  * GDR URIs for every doc the engine writes (definitions, instances,
@@ -6868,11 +6874,11 @@ export declare interface DeployDefinitionsResult {
6868
6874
  */
6869
6875
  export declare function deployStageGuards(args: StageGuardArgs): Promise<void>;
6870
6876
 
6871
- /** Where a definition deploys: the engine tags it partitions under, and the
6877
+ /** Where a definition deploys: the engine tag it partitions under, and the
6872
6878
  * workflow resource it belongs to. Structurally what `deployDefinitions`
6873
6879
  * receives, minus the definitions themselves. */
6874
6880
  export declare interface DeployTarget {
6875
- tags: string[];
6881
+ tag: string;
6876
6882
  workflowResource: WorkflowResource;
6877
6883
  }
6878
6884
 
@@ -7239,7 +7245,7 @@ export declare interface Engine {
7239
7245
  * (e.g. test bench, drain workers) that need them; the verbs already
7240
7246
  * thread them through internally. */
7241
7247
  readonly client: WorkflowClient;
7242
- readonly tags: readonly string[];
7248
+ readonly tag: string;
7243
7249
  readonly workflowResource: WorkflowResource;
7244
7250
  readonly effectHandlers: Readonly<Record<string, EffectHandler>>;
7245
7251
  readonly missingHandler: MissingHandlerPolicy;
@@ -7316,8 +7322,8 @@ export declare interface Engine {
7316
7322
  instanceId: string;
7317
7323
  task?: string;
7318
7324
  }) => Promise<WorkflowInstance[]>;
7319
- /** GROQ query against the engine's workflow resource. `$engineTags`
7320
- * is bound for tag-aware filtering. */
7325
+ /** GROQ query against the engine's workflow resource. `$tag`
7326
+ * is bound for tag-scoped filtering. */
7321
7327
  query: <T = unknown>(args: {
7322
7328
  groq: string;
7323
7329
  params?: Record<string, unknown>;
@@ -7351,7 +7357,7 @@ export declare interface Engine {
7351
7357
  access?: WorkflowAccessOverride;
7352
7358
  }) => Promise<DrainEffectsResult>;
7353
7359
  /**
7354
- * Inspect every deployed definition in the engine's tags and apply
7360
+ * Inspect every deployed definition in the engine's tag and apply
7355
7361
  * the configured missingHandler policy at `phase: "deploy"` for any
7356
7362
  * effect name without a registered handler. Catches "definition
7357
7363
  * shipped, handler removed" misconfigurations at startup instead of
@@ -7371,8 +7377,8 @@ export declare interface EngineLogger {
7371
7377
 
7372
7378
  export declare interface EvaluateArgs {
7373
7379
  client: WorkflowClient;
7374
- /** Engine-scope tags — required. */
7375
- tags: string[];
7380
+ /** Engine-scope environment partition — required. */
7381
+ tag: string;
7376
7382
  /** Engine workflow resource — required. */
7377
7383
  workflowResource: WorkflowResource;
7378
7384
  instanceId: string;
@@ -8374,8 +8380,8 @@ export declare function openStage(
8374
8380
 
8375
8381
  export declare interface OperationArgs {
8376
8382
  client: WorkflowClient;
8377
- /** Engine-scope tags — required. */
8378
- tags: string[];
8383
+ /** Engine-scope environment partition — required. */
8384
+ tag: string;
8379
8385
  /** The Sanity resource the engine's own data lives in. */
8380
8386
  workflowResource: WorkflowResource;
8381
8387
  /** Cross-resource routing — see `StartInstanceArgs.resourceClients`. */
@@ -8714,8 +8720,8 @@ export declare type StageName = string;
8714
8720
 
8715
8721
  export declare interface StartInstanceArgs {
8716
8722
  client: WorkflowClient;
8717
- /** Engine-scope tags — required. */
8718
- tags: string[];
8723
+ /** Engine-scope environment partition — required. */
8724
+ tag: string;
8719
8725
  /** The Sanity resource the engine's own data lives in. */
8720
8726
  workflowResource: WorkflowResource;
8721
8727
  /**
@@ -11769,13 +11775,11 @@ declare const SubworkflowsSchema: v.StrictObjectSchema<
11769
11775
 
11770
11776
  /**
11771
11777
  * The engine's read-partition invariant as a GROQ predicate: a document is
11772
- * visible when its `tags[]` intersect the caller's tag set.
11773
- *
11774
- * @param param - GROQ parameter holding the caller's tags. Defaults to
11775
- * `engineTags`, matching the `workflow.query` guard so any query built with
11776
- * 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.
11777
11781
  */
11778
- export declare function tagScopeFilter(param?: string): string;
11782
+ export declare function tagScopeFilter(): string;
11779
11783
 
11780
11784
  export declare type Task = v.InferOutput<typeof StoredTaskSchema>;
11781
11785
 
@@ -11865,18 +11869,25 @@ export declare function validateDefinition(
11865
11869
  ): void;
11866
11870
 
11867
11871
  /**
11868
- * 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.
11869
11879
  *
11870
- * Every engine takes a required `tags: string[]` set at construction.
11871
- * Tags must be Sanity-ID-compatible since they're joined into IDs with
11872
- * `.` 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.
11873
11883
  *
11874
- * The first tag in the array is the *canonical* tag, used as the ID
11875
- * prefix when the engine writes new definitions or instances. The full
11876
- * tag set goes onto every written doc and is the basis for read
11877
- * 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.
11878
11889
  */
11879
- export declare function validateTags(tags: string[]): void;
11890
+ export declare function validateTag(tag: string): void;
11880
11891
 
11881
11892
  /**
11882
11893
  * The guards allowed to influence this instance's verdicts, read from the
@@ -12032,44 +12043,43 @@ export declare const workflow: {
12032
12043
  */
12033
12044
  abortInstance: (args: Clocked<AbortInstanceArgs>) => Promise<DispatchResult>;
12034
12045
  /**
12035
- * 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.
12036
12047
  * Throws when the instance doesn't exist or isn't visible to this
12037
12048
  * engine.
12038
12049
  */
12039
12050
  getInstance: (args: {
12040
12051
  client: WorkflowClient;
12041
- tags: string[];
12052
+ tag: string;
12042
12053
  workflowResource: WorkflowResource;
12043
12054
  instanceId: string;
12044
12055
  }) => Promise<WorkflowInstance>;
12045
12056
  guardsForInstance: (args: {
12046
12057
  client: WorkflowClient;
12047
- tags: string[];
12058
+ tag: string;
12048
12059
  workflowResource: WorkflowResource;
12049
12060
  instanceId: string;
12050
12061
  resourceClients?: ResourceClientResolver;
12051
12062
  }) => Promise<MutationGuardDoc[]>;
12052
12063
  guardsForDefinition: (args: {
12053
12064
  client: WorkflowClient;
12054
- tags: string[];
12065
+ tag: string;
12055
12066
  workflowResource: WorkflowResource;
12056
12067
  /** The definition's `name`. */
12057
12068
  definition: string;
12058
12069
  resourceClients?: ResourceClientResolver;
12059
12070
  }) => Promise<MutationGuardDoc[]>;
12060
12071
  /**
12061
- * Run a caller-supplied GROQ query with the engine's tags bound as
12062
- * `$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
12063
12074
  * can't be safely tag-scoped after the fact — so the CALLER MUST
12064
- * filter on `$engineTags` (e.g.
12065
- * `count(tags[@ in $engineTags]) > 0`). To guard against accidental
12066
- * 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
12067
12077
  * rejected before it reaches the lake. Caller is responsible for type
12068
12078
  * narrowing the result.
12069
12079
  */
12070
12080
  query: <T = unknown>(args: {
12071
12081
  client: WorkflowClient;
12072
- tags: string[];
12082
+ tag: string;
12073
12083
  workflowResource: WorkflowResource;
12074
12084
  groq: string;
12075
12085
  params?: Record<string, unknown>;
@@ -12093,7 +12103,7 @@ export declare const workflow: {
12093
12103
  queryInScope: <T = unknown>(
12094
12104
  args: Clocked<{
12095
12105
  client: WorkflowClient;
12096
- tags: string[];
12106
+ tag: string;
12097
12107
  workflowResource: WorkflowResource;
12098
12108
  resourceClients?: ResourceClientResolver;
12099
12109
  instanceId: string;
@@ -12107,7 +12117,7 @@ export declare const workflow: {
12107
12117
  */
12108
12118
  listPendingEffects: (args: {
12109
12119
  client: WorkflowClient;
12110
- tags: string[];
12120
+ tag: string;
12111
12121
  workflowResource: WorkflowResource;
12112
12122
  instanceId: string;
12113
12123
  }) => Promise<PendingEffect[]>;
@@ -12118,7 +12128,7 @@ export declare const workflow: {
12118
12128
  */
12119
12129
  findPendingEffects: (args: {
12120
12130
  client: WorkflowClient;
12121
- tags: string[];
12131
+ tag: string;
12122
12132
  workflowResource: WorkflowResource;
12123
12133
  instanceId: string;
12124
12134
  claimed?: boolean;
@@ -12160,14 +12170,14 @@ export declare const workflow: {
12160
12170
  * record. (The per-task `spawnedInstances` field on the active stage
12161
12171
  * only exists while that stage is current; history survives.) Strips
12162
12172
  * the GDR URI on each `instanceRef` to a bare `_id`, fetches the
12163
- * 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
12164
12174
  * returns them sorted by `startedAt` ascending.
12165
12175
  *
12166
12176
  * Pass `task` to restrict to a single spawning task on the parent.
12167
12177
  */
12168
12178
  children: (args: {
12169
12179
  client: WorkflowClient;
12170
- tags: string[];
12180
+ tag: string;
12171
12181
  workflowResource: WorkflowResource;
12172
12182
  instanceId: string;
12173
12183
  task?: string;
@@ -14120,11 +14130,11 @@ export declare interface WorkflowFetchOptions {
14120
14130
  export declare interface WorkflowInstance extends SanityDocument {
14121
14131
  _type: typeof WORKFLOW_INSTANCE_TYPE;
14122
14132
  /**
14123
- * Engine-scope tags stamped on the instance at create time. Engines
14124
- * with disjoint tag sets cannot read this instance; engines sharing
14125
- * 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.
14126
14136
  */
14127
- tags: string[];
14137
+ tag: string;
14128
14138
  /**
14129
14139
  * The Sanity resource this instance lives in. Stored on the doc so
14130
14140
  * any internal operation can mint GDRs for ancestors / spawned
package/dist/index.d.ts CHANGED
@@ -6547,10 +6547,10 @@ export declare interface AvailableActionsResult {
6547
6547
  declare type Bound<
6548
6548
  Args extends {
6549
6549
  client: WorkflowClient;
6550
- tags: string[];
6550
+ tag: string;
6551
6551
  workflowResource: WorkflowResource;
6552
6552
  },
6553
- > = Omit<Args, "client" | "tags" | "workflowResource">;
6553
+ > = Omit<Args, "client" | "tag" | "workflowResource">;
6554
6554
 
6555
6555
  /**
6556
6556
  * Build a snapshot from a set of loaded docs. Pure transform.
@@ -6570,8 +6570,6 @@ export declare function buildSnapshot(args: {
6570
6570
  docs: LoadedDoc[];
6571
6571
  }): HydratedSnapshot;
6572
6572
 
6573
- export declare function canonicalTag(tags: string[]): string;
6574
-
6575
6573
  /**
6576
6574
  * Thrown when auto-transitions on an instance fail to stabilise within
6577
6575
  * {@link CascadeLimitError.limit} passes — the signature of a runaway
@@ -6713,10 +6711,11 @@ export declare function contentReleaseName(args: {
6713
6711
  }): string | undefined;
6714
6712
 
6715
6713
  /**
6716
- * Construct an engine bound to a workflow resource + tags. The returned
6714
+ * Construct an engine bound to a workflow resource + tag. The returned
6717
6715
  * object exposes the same verbs as the `workflow.*` namespace, minus
6718
- * the boilerplate config arguments (client / tags / workflowResource)
6719
- * 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.
6720
6719
  *
6721
6720
  * Effect handlers + missingHandler are stored for future drain wiring
6722
6721
  * (Step 10). They have no effect on `fireAction` / `tick` /
@@ -6728,7 +6727,14 @@ export declare function createEngine(args: CreateEngineArgs): Engine;
6728
6727
  export declare interface CreateEngineArgs {
6729
6728
  client: WorkflowClient;
6730
6729
  workflowResource: WorkflowResource;
6731
- 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;
6732
6738
  /**
6733
6739
  * Optional routing for cross-resource reads. When the engine needs
6734
6740
  * a doc whose GDR points at a resource other than its own, it calls
@@ -6774,8 +6780,8 @@ export declare const defaultLoggerFactory: LoggerFactory;
6774
6780
 
6775
6781
  export declare interface DeleteDefinitionArgs {
6776
6782
  client: WorkflowClient;
6777
- /** Engine-scope tags — required. See `validateTags` + `tags.ts`. */
6778
- tags: string[];
6783
+ /** Engine-scope environment partition — required. See {@link validateTag} + `tags.ts`. */
6784
+ tag: string;
6779
6785
  /** The Sanity resource the engine's own data lives in. */
6780
6786
  workflowResource: WorkflowResource;
6781
6787
  /** Cross-resource routing — see `StartInstanceArgs.resourceClients`. */
@@ -6837,8 +6843,8 @@ export declare interface DeployDefinitionResult {
6837
6843
 
6838
6844
  export declare interface DeployDefinitionsArgs {
6839
6845
  client: WorkflowClient;
6840
- /** Engine-scope tags — required. See `validateTags` + `tags.ts`. */
6841
- tags: string[];
6846
+ /** Engine-scope environment partition — required. See {@link validateTag} + `tags.ts`. */
6847
+ tag: string;
6842
6848
  /**
6843
6849
  * The Sanity resource the engine's own data lives in. Used to mint
6844
6850
  * GDR URIs for every doc the engine writes (definitions, instances,
@@ -6868,11 +6874,11 @@ export declare interface DeployDefinitionsResult {
6868
6874
  */
6869
6875
  export declare function deployStageGuards(args: StageGuardArgs): Promise<void>;
6870
6876
 
6871
- /** Where a definition deploys: the engine tags it partitions under, and the
6877
+ /** Where a definition deploys: the engine tag it partitions under, and the
6872
6878
  * workflow resource it belongs to. Structurally what `deployDefinitions`
6873
6879
  * receives, minus the definitions themselves. */
6874
6880
  export declare interface DeployTarget {
6875
- tags: string[];
6881
+ tag: string;
6876
6882
  workflowResource: WorkflowResource;
6877
6883
  }
6878
6884
 
@@ -7239,7 +7245,7 @@ export declare interface Engine {
7239
7245
  * (e.g. test bench, drain workers) that need them; the verbs already
7240
7246
  * thread them through internally. */
7241
7247
  readonly client: WorkflowClient;
7242
- readonly tags: readonly string[];
7248
+ readonly tag: string;
7243
7249
  readonly workflowResource: WorkflowResource;
7244
7250
  readonly effectHandlers: Readonly<Record<string, EffectHandler>>;
7245
7251
  readonly missingHandler: MissingHandlerPolicy;
@@ -7316,8 +7322,8 @@ export declare interface Engine {
7316
7322
  instanceId: string;
7317
7323
  task?: string;
7318
7324
  }) => Promise<WorkflowInstance[]>;
7319
- /** GROQ query against the engine's workflow resource. `$engineTags`
7320
- * is bound for tag-aware filtering. */
7325
+ /** GROQ query against the engine's workflow resource. `$tag`
7326
+ * is bound for tag-scoped filtering. */
7321
7327
  query: <T = unknown>(args: {
7322
7328
  groq: string;
7323
7329
  params?: Record<string, unknown>;
@@ -7351,7 +7357,7 @@ export declare interface Engine {
7351
7357
  access?: WorkflowAccessOverride;
7352
7358
  }) => Promise<DrainEffectsResult>;
7353
7359
  /**
7354
- * Inspect every deployed definition in the engine's tags and apply
7360
+ * Inspect every deployed definition in the engine's tag and apply
7355
7361
  * the configured missingHandler policy at `phase: "deploy"` for any
7356
7362
  * effect name without a registered handler. Catches "definition
7357
7363
  * shipped, handler removed" misconfigurations at startup instead of
@@ -7371,8 +7377,8 @@ export declare interface EngineLogger {
7371
7377
 
7372
7378
  export declare interface EvaluateArgs {
7373
7379
  client: WorkflowClient;
7374
- /** Engine-scope tags — required. */
7375
- tags: string[];
7380
+ /** Engine-scope environment partition — required. */
7381
+ tag: string;
7376
7382
  /** Engine workflow resource — required. */
7377
7383
  workflowResource: WorkflowResource;
7378
7384
  instanceId: string;
@@ -8374,8 +8380,8 @@ export declare function openStage(
8374
8380
 
8375
8381
  export declare interface OperationArgs {
8376
8382
  client: WorkflowClient;
8377
- /** Engine-scope tags — required. */
8378
- tags: string[];
8383
+ /** Engine-scope environment partition — required. */
8384
+ tag: string;
8379
8385
  /** The Sanity resource the engine's own data lives in. */
8380
8386
  workflowResource: WorkflowResource;
8381
8387
  /** Cross-resource routing — see `StartInstanceArgs.resourceClients`. */
@@ -8714,8 +8720,8 @@ export declare type StageName = string;
8714
8720
 
8715
8721
  export declare interface StartInstanceArgs {
8716
8722
  client: WorkflowClient;
8717
- /** Engine-scope tags — required. */
8718
- tags: string[];
8723
+ /** Engine-scope environment partition — required. */
8724
+ tag: string;
8719
8725
  /** The Sanity resource the engine's own data lives in. */
8720
8726
  workflowResource: WorkflowResource;
8721
8727
  /**
@@ -11769,13 +11775,11 @@ declare const SubworkflowsSchema: v.StrictObjectSchema<
11769
11775
 
11770
11776
  /**
11771
11777
  * The engine's read-partition invariant as a GROQ predicate: a document is
11772
- * visible when its `tags[]` intersect the caller's tag set.
11773
- *
11774
- * @param param - GROQ parameter holding the caller's tags. Defaults to
11775
- * `engineTags`, matching the `workflow.query` guard so any query built with
11776
- * 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.
11777
11781
  */
11778
- export declare function tagScopeFilter(param?: string): string;
11782
+ export declare function tagScopeFilter(): string;
11779
11783
 
11780
11784
  export declare type Task = v.InferOutput<typeof StoredTaskSchema>;
11781
11785
 
@@ -11865,18 +11869,25 @@ export declare function validateDefinition(
11865
11869
  ): void;
11866
11870
 
11867
11871
  /**
11868
- * 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.
11869
11879
  *
11870
- * Every engine takes a required `tags: string[]` set at construction.
11871
- * Tags must be Sanity-ID-compatible since they're joined into IDs with
11872
- * `.` 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.
11873
11883
  *
11874
- * The first tag in the array is the *canonical* tag, used as the ID
11875
- * prefix when the engine writes new definitions or instances. The full
11876
- * tag set goes onto every written doc and is the basis for read
11877
- * 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.
11878
11889
  */
11879
- export declare function validateTags(tags: string[]): void;
11890
+ export declare function validateTag(tag: string): void;
11880
11891
 
11881
11892
  /**
11882
11893
  * The guards allowed to influence this instance's verdicts, read from the
@@ -12032,44 +12043,43 @@ export declare const workflow: {
12032
12043
  */
12033
12044
  abortInstance: (args: Clocked<AbortInstanceArgs>) => Promise<DispatchResult>;
12034
12045
  /**
12035
- * 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.
12036
12047
  * Throws when the instance doesn't exist or isn't visible to this
12037
12048
  * engine.
12038
12049
  */
12039
12050
  getInstance: (args: {
12040
12051
  client: WorkflowClient;
12041
- tags: string[];
12052
+ tag: string;
12042
12053
  workflowResource: WorkflowResource;
12043
12054
  instanceId: string;
12044
12055
  }) => Promise<WorkflowInstance>;
12045
12056
  guardsForInstance: (args: {
12046
12057
  client: WorkflowClient;
12047
- tags: string[];
12058
+ tag: string;
12048
12059
  workflowResource: WorkflowResource;
12049
12060
  instanceId: string;
12050
12061
  resourceClients?: ResourceClientResolver;
12051
12062
  }) => Promise<MutationGuardDoc[]>;
12052
12063
  guardsForDefinition: (args: {
12053
12064
  client: WorkflowClient;
12054
- tags: string[];
12065
+ tag: string;
12055
12066
  workflowResource: WorkflowResource;
12056
12067
  /** The definition's `name`. */
12057
12068
  definition: string;
12058
12069
  resourceClients?: ResourceClientResolver;
12059
12070
  }) => Promise<MutationGuardDoc[]>;
12060
12071
  /**
12061
- * Run a caller-supplied GROQ query with the engine's tags bound as
12062
- * `$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
12063
12074
  * can't be safely tag-scoped after the fact — so the CALLER MUST
12064
- * filter on `$engineTags` (e.g.
12065
- * `count(tags[@ in $engineTags]) > 0`). To guard against accidental
12066
- * 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
12067
12077
  * rejected before it reaches the lake. Caller is responsible for type
12068
12078
  * narrowing the result.
12069
12079
  */
12070
12080
  query: <T = unknown>(args: {
12071
12081
  client: WorkflowClient;
12072
- tags: string[];
12082
+ tag: string;
12073
12083
  workflowResource: WorkflowResource;
12074
12084
  groq: string;
12075
12085
  params?: Record<string, unknown>;
@@ -12093,7 +12103,7 @@ export declare const workflow: {
12093
12103
  queryInScope: <T = unknown>(
12094
12104
  args: Clocked<{
12095
12105
  client: WorkflowClient;
12096
- tags: string[];
12106
+ tag: string;
12097
12107
  workflowResource: WorkflowResource;
12098
12108
  resourceClients?: ResourceClientResolver;
12099
12109
  instanceId: string;
@@ -12107,7 +12117,7 @@ export declare const workflow: {
12107
12117
  */
12108
12118
  listPendingEffects: (args: {
12109
12119
  client: WorkflowClient;
12110
- tags: string[];
12120
+ tag: string;
12111
12121
  workflowResource: WorkflowResource;
12112
12122
  instanceId: string;
12113
12123
  }) => Promise<PendingEffect[]>;
@@ -12118,7 +12128,7 @@ export declare const workflow: {
12118
12128
  */
12119
12129
  findPendingEffects: (args: {
12120
12130
  client: WorkflowClient;
12121
- tags: string[];
12131
+ tag: string;
12122
12132
  workflowResource: WorkflowResource;
12123
12133
  instanceId: string;
12124
12134
  claimed?: boolean;
@@ -12160,14 +12170,14 @@ export declare const workflow: {
12160
12170
  * record. (The per-task `spawnedInstances` field on the active stage
12161
12171
  * only exists while that stage is current; history survives.) Strips
12162
12172
  * the GDR URI on each `instanceRef` to a bare `_id`, fetches the
12163
- * 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
12164
12174
  * returns them sorted by `startedAt` ascending.
12165
12175
  *
12166
12176
  * Pass `task` to restrict to a single spawning task on the parent.
12167
12177
  */
12168
12178
  children: (args: {
12169
12179
  client: WorkflowClient;
12170
- tags: string[];
12180
+ tag: string;
12171
12181
  workflowResource: WorkflowResource;
12172
12182
  instanceId: string;
12173
12183
  task?: string;
@@ -14120,11 +14130,11 @@ export declare interface WorkflowFetchOptions {
14120
14130
  export declare interface WorkflowInstance extends SanityDocument {
14121
14131
  _type: typeof WORKFLOW_INSTANCE_TYPE;
14122
14132
  /**
14123
- * Engine-scope tags stamped on the instance at create time. Engines
14124
- * with disjoint tag sets cannot read this instance; engines sharing
14125
- * 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.
14126
14136
  */
14127
- tags: string[];
14137
+ tag: string;
14128
14138
  /**
14129
14139
  * The Sanity resource this instance lives in. Stored on the doc so
14130
14140
  * any internal operation can mint GDRs for ancestors / spawned