@sanity/workflow-engine 0.27.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -86,6 +86,9 @@ export declare type Action = ActionFields<Op, string[]> & {
86
86
  export declare const ACTION_SEMANTICS: readonly [
87
87
  "decision.accept",
88
88
  "decision.decline",
89
+ "signal.positive",
90
+ "signal.caution",
91
+ "signal.critical",
89
92
  ];
90
93
 
91
94
  /**
@@ -358,7 +361,7 @@ export declare function actionRendering(action: {
358
361
  | undefined;
359
362
  }): "absent" | "automation" | "button";
360
363
 
361
- export declare type ActionSemantic = (typeof ACTION_SEMANTICS)[number];
364
+ export declare type ActionSemantic = DecisionSemantic | Semantic;
362
365
 
363
366
  /** The fireable-action verdict for one action on an activity — its `allowed`
364
367
  * state, structured `disabledReason`, and declared params, tagged with the
@@ -416,8 +419,9 @@ export declare const ACTIVITY_KINDS: readonly [
416
419
  ];
417
420
 
418
421
  /**
419
- * Leaf enums the const arrays (and their derived union types) that both
420
- * the authoring schema and the engine address by name.
422
+ * Leaf vocabularies that both the authoring schema and the engine address by
423
+ * name. Some exported types also include grammar-validated open values that
424
+ * cannot be enumerated by a const array.
421
425
  *
422
426
  * This module imports nothing. It is the schema-free foundation that
423
427
  * `../define/schema.ts` reads its value constants from, which is what keeps
@@ -478,6 +482,8 @@ export declare interface ActivityEntry {
478
482
 
479
483
  export declare interface ActivityEvaluation {
480
484
  activity: Activity;
485
+ /** The activity's advisory workflow meaning, unchanged from its definition. */
486
+ semantics?: Semantic[] | undefined;
481
487
  status: ActivityStatus;
482
488
  /**
483
489
  * The activity's shape-derived {@link ActivityKind}. Advisory: a label so a
@@ -529,6 +535,7 @@ export declare interface ActivityEvaluation {
529
535
  /** Type-mirror of {@link activityFields}, parameterised over field/action/target/group. */
530
536
  declare type ActivityFields<TField, TAction, TTarget, TGroup> = {
531
537
  name: string;
538
+ semantics?: Semantic[] | undefined;
532
539
  title?: string | undefined;
533
540
  description?: string | undefined;
534
541
  groups?: Group[] | undefined;
@@ -1160,6 +1167,31 @@ declare const AuthoringOpSchema: v.VariantSchema<
1160
1167
  },
1161
1168
  undefined
1162
1169
  >,
1170
+ v.StrictObjectSchema<
1171
+ {
1172
+ readonly type: v.LiteralSchema<"field.setIfMissing", undefined>;
1173
+ readonly target: v.StrictObjectSchema<
1174
+ {
1175
+ readonly scope: v.OptionalSchema<
1176
+ v.PicklistSchema<
1177
+ readonly ["workflow", "stage", "activity"],
1178
+ string
1179
+ >,
1180
+ undefined
1181
+ >;
1182
+ readonly field: v.SchemaWithPipe<
1183
+ readonly [
1184
+ v.StringSchema<undefined>,
1185
+ v.MinLengthAction<string, 1, "must be a non-empty string">,
1186
+ ]
1187
+ >;
1188
+ },
1189
+ undefined
1190
+ >;
1191
+ readonly value: v.GenericSchema<ValueExprInternal>;
1192
+ },
1193
+ undefined
1194
+ >,
1163
1195
  v.StrictObjectSchema<
1164
1196
  {
1165
1197
  readonly type: v.LiteralSchema<"field.unset", undefined>;
@@ -1209,6 +1241,62 @@ declare const AuthoringOpSchema: v.VariantSchema<
1209
1241
  },
1210
1242
  undefined
1211
1243
  >,
1244
+ v.StrictObjectSchema<
1245
+ {
1246
+ readonly type: v.LiteralSchema<"field.inc", undefined>;
1247
+ readonly target: v.StrictObjectSchema<
1248
+ {
1249
+ readonly scope: v.OptionalSchema<
1250
+ v.PicklistSchema<
1251
+ readonly ["workflow", "stage", "activity"],
1252
+ string
1253
+ >,
1254
+ undefined
1255
+ >;
1256
+ readonly field: v.SchemaWithPipe<
1257
+ readonly [
1258
+ v.StringSchema<undefined>,
1259
+ v.MinLengthAction<string, 1, "must be a non-empty string">,
1260
+ ]
1261
+ >;
1262
+ },
1263
+ undefined
1264
+ >;
1265
+ readonly value: v.OptionalSchema<
1266
+ v.GenericSchema<ValueExprInternal>,
1267
+ undefined
1268
+ >;
1269
+ },
1270
+ undefined
1271
+ >,
1272
+ v.StrictObjectSchema<
1273
+ {
1274
+ readonly type: v.LiteralSchema<"field.dec", undefined>;
1275
+ readonly target: v.StrictObjectSchema<
1276
+ {
1277
+ readonly scope: v.OptionalSchema<
1278
+ v.PicklistSchema<
1279
+ readonly ["workflow", "stage", "activity"],
1280
+ string
1281
+ >,
1282
+ undefined
1283
+ >;
1284
+ readonly field: v.SchemaWithPipe<
1285
+ readonly [
1286
+ v.StringSchema<undefined>,
1287
+ v.MinLengthAction<string, 1, "must be a non-empty string">,
1288
+ ]
1289
+ >;
1290
+ },
1291
+ undefined
1292
+ >;
1293
+ readonly value: v.OptionalSchema<
1294
+ v.GenericSchema<ValueExprInternal>,
1295
+ undefined
1296
+ >;
1297
+ },
1298
+ undefined
1299
+ >,
1212
1300
  v.StrictObjectSchema<
1213
1301
  {
1214
1302
  readonly type: v.LiteralSchema<"field.updateWhere", undefined>;
@@ -2288,6 +2376,9 @@ export declare function createTelemetryIntake(args: {
2288
2376
  denied?: boolean;
2289
2377
  }): TelemetryIntake;
2290
2378
 
2379
+ /** A define-time validated `custom.<camelCaseMeaning>` value. */
2380
+ export declare type CustomSemantic = `custom.${string}`;
2381
+
2291
2382
  /**
2292
2383
  * The append-only, machine-readable counterpart of the model log in
2293
2384
  * `DATAMODEL.md`. It records compatibility decisions; the prose log retains
@@ -2328,7 +2419,7 @@ export declare const DATA_MODEL_CHANGES: readonly [
2328
2419
  documentTypes: readonly ["definition"];
2329
2420
  compatibility: "additive";
2330
2421
  applicability: "detectable";
2331
- summary: "Ordinary actions may carry a closed bag of advisory workflow semantics.";
2422
+ summary: "Ordinary actions may carry advisory workflow semantics.";
2332
2423
  }>,
2333
2424
  Readonly<{
2334
2425
  id: "inclusive-scalar-bounds";
@@ -2384,6 +2475,33 @@ export declare const DATA_MODEL_CHANGES: readonly [
2384
2475
  applicability: "detectable";
2385
2476
  summary: string;
2386
2477
  }>,
2478
+ Readonly<{
2479
+ id: "node-semantics";
2480
+ introducedInModel: 6;
2481
+ minReaderModel: 0;
2482
+ documentTypes: readonly ["definition"];
2483
+ compatibility: "additive";
2484
+ applicability: "detectable";
2485
+ summary: "Workflow, stage, activity, and action nodes may carry signal or custom advisory semantics.";
2486
+ }>,
2487
+ Readonly<{
2488
+ id: "field-patch-ops";
2489
+ introducedInModel: 6;
2490
+ minReaderModel: 0;
2491
+ documentTypes: readonly ["definition", "instance"];
2492
+ compatibility: "additive";
2493
+ applicability: "detectable";
2494
+ summary: "Field ops may increment, decrement, or initialize a missing field value.";
2495
+ }>,
2496
+ Readonly<{
2497
+ id: "attributes-condition-var";
2498
+ introducedInModel: 7;
2499
+ minReaderModel: 0;
2500
+ documentTypes: readonly ["definition"];
2501
+ compatibility: "additive";
2502
+ applicability: "unconditional";
2503
+ summary: string;
2504
+ }>,
2387
2505
  ];
2388
2506
 
2389
2507
  /**
@@ -2408,7 +2526,7 @@ export declare const DATA_MODEL_MIN_READER = 4;
2408
2526
  * job. Declare every bump in `DATAMODEL.md`; the model-surface snapshot test
2409
2527
  * keeps undeclared drift red.
2410
2528
  */
2411
- export declare const DATA_MODEL_VERSION = 5;
2529
+ export declare const DATA_MODEL_VERSION = 7;
2412
2530
 
2413
2531
  export declare interface DataModelChange {
2414
2532
  readonly id: string;
@@ -2433,6 +2551,13 @@ export declare function datasetResourceParts(id: string): {
2433
2551
  dataset: string;
2434
2552
  };
2435
2553
 
2554
+ export declare const DECISION_SEMANTICS: readonly [
2555
+ "decision.accept",
2556
+ "decision.decline",
2557
+ ];
2558
+
2559
+ export declare type DecisionSemantic = (typeof DECISION_SEMANTICS)[number];
2560
+
2436
2561
  /** The declarable half of {@link ExecutionContext} — what `createEngine` accepts. */
2437
2562
  export declare type DeclaredExecutionContext = Pick<
2438
2563
  ExecutionContext,
@@ -2967,6 +3092,18 @@ export declare function describeSiteHeading(
2967
3092
  ctx: DescribeContext,
2968
3093
  ): InsightPhrase;
2969
3094
 
3095
+ /**
3096
+ * The activity slice the document-derivable stuck causes read: its runtime
3097
+ * status, and the declared actions whose effects a failure is matched against.
3098
+ * Narrowed to exactly this, so one set of cause functions serves both a full
3099
+ * {@link WorkflowEvaluation} and {@link documentStuckCause}'s snapshot-derived
3100
+ * rows.
3101
+ */
3102
+ declare interface DiagnosedActivity {
3103
+ status: ActivityStatus;
3104
+ activity: Pick<Activity, "name" | "actions">;
3105
+ }
3106
+
2970
3107
  /** The slice of a {@link TransitionEvaluation} the classifier reads — narrowed
2971
3108
  * so a hand-crafted stuck permutation doesn't have to fabricate insights. */
2972
3109
  export declare type DiagnosedTransition = Pick<
@@ -2980,7 +3117,7 @@ export declare type DiagnosedTransition = Pick<
2980
3117
  * without standing up a full evaluation; {@link diagnoseInputFromEvaluation}
2981
3118
  * builds it from a real {@link WorkflowEvaluation}.
2982
3119
  */
2983
- export declare interface DiagnoseInput {
3120
+ export declare interface DiagnoseInput extends DocumentStuckInput {
2984
3121
  instance: Pick<
2985
3122
  WorkflowInstance,
2986
3123
  | "currentStage"
@@ -3269,6 +3406,36 @@ export declare function documentPrefilter(
3269
3406
  params: Record<string, string | string[]>,
3270
3407
  ): string;
3271
3408
 
3409
+ /**
3410
+ * Classify an instance from its document alone — no evaluation, no reads, no
3411
+ * actor. The transition-level causes need GROQ `when` results, so only
3412
+ * {@link diagnoseInstance} reaches those.
3413
+ *
3414
+ * Sound but incomplete, and a consumer must present it that way: `undefined`
3415
+ * means "no cause this classifier can see", never "healthy". Flag an instance on
3416
+ * a cause; never word an absence as an all-clear.
3417
+ */
3418
+ export declare function documentStuckCause(args: {
3419
+ instance: Pick<
3420
+ WorkflowInstance,
3421
+ "currentStage" | "effectHistory" | "pendingEffects" | "stages"
3422
+ >;
3423
+ /** The instance's parsed snapshot. Absent, the answer narrows — a failed
3424
+ * effect cannot be tied to the activity it stalls — and never widens. */
3425
+ definition: WorkflowDefinition | undefined;
3426
+ }): StuckCause | undefined;
3427
+
3428
+ /**
3429
+ * What the document-derivable stuck causes read. Every field is persisted —
3430
+ * on the instance itself or in the definition snapshot pinned to it — so a
3431
+ * caller holding only a committed instance can classify these without an
3432
+ * evaluation.
3433
+ */
3434
+ declare interface DocumentStuckInput {
3435
+ instance: Pick<WorkflowInstance, "effectHistory" | "pendingEffects">;
3436
+ activities: readonly DiagnosedActivity[];
3437
+ }
3438
+
3272
3439
  export declare type DocumentValuePermission =
3273
3440
  (typeof DOCUMENT_VALUE_PERMISSIONS)[number];
3274
3441
 
@@ -4093,6 +4260,12 @@ export declare interface EvaluateFromSnapshotArgs {
4093
4260
  * write boundary still enforces).
4094
4261
  */
4095
4262
  grants?: Grant[];
4263
+ /**
4264
+ * Resolved org-level user attributes for the actor. Omit to leave the
4265
+ * rendered `$attributes` undefined (conditions referencing it fail
4266
+ * closed).
4267
+ */
4268
+ attributes?: UserAttributes;
4096
4269
  /**
4097
4270
  * The in-memory snapshot to evaluate against. The caller assembles it
4098
4271
  * from whatever source — a fetch (see {@link evaluateInstance}) or a
@@ -4515,6 +4688,10 @@ export declare interface FieldInsight {
4515
4688
 
4516
4689
  export declare type FieldKind = keyof FieldValueMap;
4517
4690
 
4691
+ /**
4692
+ * A stored field mutation. `field.inc` and `field.dec` use the same names as
4693
+ * `@sanity/client` patches and default an omitted `value` to a delta of `1`.
4694
+ */
4518
4695
  export declare type FieldOp = v.InferOutput<typeof StoredFieldOpSchema>;
4519
4696
 
4520
4697
  /**
@@ -4629,6 +4806,12 @@ export declare class FieldValueShapeError extends WorkflowError<"field-value-sha
4629
4806
  */
4630
4807
  export declare const FILTER_SCOPE_VARS: readonly string[];
4631
4808
 
4809
+ export declare function findActivityNode(args: {
4810
+ activityName: string;
4811
+ definition: WorkflowDefinition | undefined;
4812
+ stageName: string;
4813
+ }): Activity | undefined;
4814
+
4632
4815
  /**
4633
4816
  * The current stage's {@link ActivityEntry} named `activityName`, or
4634
4817
  * `undefined` when the open stage holds no such activity (including when
@@ -4669,6 +4852,11 @@ export declare interface FindPendingEffectsArgs extends InstanceRefArgs {
4669
4852
  names?: string[];
4670
4853
  }
4671
4854
 
4855
+ export declare function findStageNode(args: {
4856
+ definition: WorkflowDefinition | undefined;
4857
+ stageName: string;
4858
+ }): Stage | undefined;
4859
+
4672
4860
  export declare interface FireActionArgs extends DedupableOperationArgs {
4673
4861
  activity: string;
4674
4862
  action: string;
@@ -5975,6 +6163,17 @@ export declare function isNotesEntry(
5975
6163
  /** Whether a project-user API failure explicitly means the user is absent. */
5976
6164
  export declare function isProjectUserNotFoundError(error: unknown): boolean;
5977
6165
 
6166
+ /**
6167
+ * True when a write looks like a lost optimistic lock — every `statusCode: 409`
6168
+ * from the real client, or the bench's `ifRevisionId check failed` message.
6169
+ * A bare 409 is not exclusively a lost fence: a `create` against an existing id
6170
+ * (`documentAlreadyExistsError`) carries the same status. Narrow the error to
6171
+ * one rev-guarded write before asking — anything wider (a whole cascade, or a
6172
+ * commit together with its guard deploy) reads a create collision as a lost
6173
+ * race.
6174
+ */
6175
+ export declare function isRevisionConflict(error: unknown): boolean;
6176
+
5978
6177
  /** Entry-level {@link isSingleDocRefKind}: narrows a resolved entry to the
5979
6178
  * single-GDR arms (`doc.ref` / `subject`) — the value is one GDR (or null)
5980
6179
  * and the entry may carry the accepted-target `types`. */
@@ -6471,6 +6670,10 @@ export declare const OP_DISPLAY: {
6471
6670
  title: string;
6472
6671
  description: string;
6473
6672
  };
6673
+ "field.setIfMissing": {
6674
+ title: string;
6675
+ description: string;
6676
+ };
6474
6677
  "field.unset": {
6475
6678
  title: string;
6476
6679
  description: string;
@@ -6479,6 +6682,14 @@ export declare const OP_DISPLAY: {
6479
6682
  title: string;
6480
6683
  description: string;
6481
6684
  };
6685
+ "field.inc": {
6686
+ title: string;
6687
+ description: string;
6688
+ };
6689
+ "field.dec": {
6690
+ title: string;
6691
+ description: string;
6692
+ };
6482
6693
  "field.updateWhere": {
6483
6694
  title: string;
6484
6695
  description: string;
@@ -6586,11 +6797,6 @@ export declare interface ParsedGdr {
6586
6797
  documentId: string;
6587
6798
  }
6588
6799
 
6589
- declare type ParsedWorkflowConfig = v.InferOutput<typeof WorkflowConfigSchema>;
6590
-
6591
- declare type ParsedWorkflowDeployment =
6592
- ParsedWorkflowConfig["deployments"][number];
6593
-
6594
6800
  /**
6595
6801
  * Parse a GDR URI into its scheme + addressing parts. Throws on
6596
6802
  * unknown scheme or malformed shape.
@@ -6864,7 +7070,7 @@ export declare class ReaderModelAcknowledgementError extends WorkflowError<"read
6864
7070
  readonly code = "WORKFLOW_READER_MODEL_ACKNOWLEDGEMENT_MISMATCH";
6865
7071
  readonly expectedMinReaderModel: unknown;
6866
7072
  readonly engineMinReaderModel = 4;
6867
- readonly engineModelVersion = 5;
7073
+ readonly engineModelVersion = 7;
6868
7074
  readonly documentationUrl =
6869
7075
  "https://www.sanity.io/docs/editorial-workflows/prerelease";
6870
7076
  constructor(expectedMinReaderModel: unknown, context?: string);
@@ -7134,10 +7340,11 @@ export declare type ResetActivityTarget =
7134
7340
  (typeof RESET_ACTIVITY_TARGETS)[number];
7135
7341
 
7136
7342
  /**
7137
- * Resolve the engine's `WorkflowAccess` for a client — both halves
7138
- * fetched from its token in parallel and cached. Throws if the client
7139
- * can't yield an actor — the engine refuses to operate without an
7140
- * identity.
7343
+ * Resolve the engine's `WorkflowAccess` for a client — actor and grants
7344
+ * (when a path is supplied) fetched from its token in parallel and cached.
7345
+ * Throws if the client can't yield an actor — the engine refuses to operate
7346
+ * without an identity. Does **not** fetch User Attributes; see
7347
+ * {@link resolveUserAttributes}.
7141
7348
  */
7142
7349
  export declare function resolveAccess(
7143
7350
  taggedClient: WorkflowClient,
@@ -7228,6 +7435,17 @@ export declare function resolveFieldEntry(
7228
7435
  },
7229
7436
  ): ResolvedFieldEntry | undefined;
7230
7437
 
7438
+ /**
7439
+ * Resolve advisory `$attributes` for the caller-bound projection — project →
7440
+ * org → global-host attributes page. Cached per (client, orgId). Expected
7441
+ * absences (401–404) leave the bag unbound; unexpected failures throw.
7442
+ * Call only from soft-gate paths (evaluate / fireAction filter re-check /
7443
+ * editField), never from ticks or drainers.
7444
+ */
7445
+ export declare function resolveUserAttributes(
7446
+ taggedClient: WorkflowClient,
7447
+ ): Promise<UserAttributes | undefined>;
7448
+
7231
7449
  /**
7232
7450
  * A map binding each resource-alias name to the physical {@link WorkflowResource}
7233
7451
  * it resolves to at deploy. Parallels the role-alias map: where role aliases map
@@ -7415,6 +7633,8 @@ export declare interface ScopedInitialFieldDeclarations {
7415
7633
  }[];
7416
7634
  }
7417
7635
 
7636
+ export declare type Semantic = SignalSemantic | CustomSemantic;
7637
+
7418
7638
  export { sentenceCase };
7419
7639
 
7420
7640
  export declare interface SessionArgs {
@@ -7436,6 +7656,14 @@ export declare interface SetStageArgs extends DedupableOperationArgs {
7436
7656
  initialFields?: InitialFieldValue[];
7437
7657
  }
7438
7658
 
7659
+ export declare const SIGNAL_SEMANTICS: readonly [
7660
+ "signal.positive",
7661
+ "signal.caution",
7662
+ "signal.critical",
7663
+ ];
7664
+
7665
+ export declare type SignalSemantic = (typeof SIGNAL_SEMANTICS)[number];
7666
+
7439
7667
  /**
7440
7668
  * No-op logger. Default for library callers that don't want any
7441
7669
  * output unless explicitly opted in.
@@ -7534,6 +7762,8 @@ export declare interface StageEntry {
7534
7762
 
7535
7763
  export declare interface StageEvaluation {
7536
7764
  stage: Stage;
7765
+ /** The stage's advisory workflow meaning, unchanged from its definition. */
7766
+ semantics?: Semantic[] | undefined;
7537
7767
  activities: ActivityEvaluation[];
7538
7768
  transitions: TransitionEvaluation[];
7539
7769
  /** The stage's causal-autonomy rollup — will it progress without a caller,
@@ -7544,6 +7774,7 @@ export declare interface StageEvaluation {
7544
7774
  /** Type-mirror of {@link stageFields}, parameterised over field/activity/transition/guard/editable. */
7545
7775
  declare type StageFields<TField, TActivity, TTransition, TGuard, TEditable> = {
7546
7776
  name: string;
7777
+ semantics?: Semantic[] | undefined;
7547
7778
  title?: string | undefined;
7548
7779
  description?: string | undefined;
7549
7780
  groups?: Group[] | undefined;
@@ -7602,10 +7833,12 @@ export declare class StaleEffectClaimError extends WorkflowError<"stale-effect-c
7602
7833
  * not the rendered condition scope (no {@link ConditionVarBinding}: these
7603
7834
  * bind only while the filter is evaluated on the READ side — the
7604
7835
  * `definitionsForDocument` derivation and the Studio start control).
7605
- * `startInstance` never evaluates the filter. BROWSE-TIME-PURE: `$fields` is
7606
- * deliberately absent a `$fields` read is deploy-rejected with a pointer
7607
- * to start GROQ requirements.
7608
- * Bound in one place: `startContextParams` in the applicability evaluator.
7836
+ * `startInstance` never evaluates the filter. BROWSE-TIME-PURE: `$fields` and
7837
+ * every caller-bound var (`$actor` / `$assigned` / `$can` / `$attributes` /
7838
+ * `$params`) are deliberately absent — a read is deploy-rejected (`$fields`
7839
+ * with a pointer to start GROQ requirements; caller vars as silent
7840
+ * never-match). Bound in one place: `startContextParams` in the applicability
7841
+ * evaluator.
7609
7842
  */
7610
7843
  export declare const START_FILTER_VARS: readonly {
7611
7844
  name: string;
@@ -7925,9 +8158,9 @@ export declare interface StartSliceRow {
7925
8158
  * (absent) is NOT editable: a field is op-only engine working memory unless the
7926
8159
  * modeler opens it. The stored form is `true` (editable by anyone within the
7927
8160
  * field's scope window) or an EDIT CONDITION — rendered-scope GROQ (`$actor`,
7928
- * `$can`, `$fields`, `$assigned`), checked like an action filter to decide
7929
- * who-may-edit. ADVISORY like every engine gate — it disables the inline field
7930
- * and explains; a {@link Guard} declares the intended write-lock.
8161
+ * `$can`, `$attributes`, `$fields`, `$assigned`), checked like an action filter
8162
+ * to decide who-may-edit. ADVISORY like every engine gate — it disables the
8163
+ * inline field and explains; a {@link Guard} declares the intended write-lock.
7931
8164
  */
7932
8165
  declare const StoredEditableSchema: v.UnionSchema<
7933
8166
  [
@@ -7976,6 +8209,28 @@ declare const StoredFieldOpSchema: v.VariantSchema<
7976
8209
  },
7977
8210
  undefined
7978
8211
  >,
8212
+ v.StrictObjectSchema<
8213
+ {
8214
+ readonly type: v.LiteralSchema<"field.setIfMissing", undefined>;
8215
+ readonly target: v.StrictObjectSchema<
8216
+ {
8217
+ readonly scope: v.PicklistSchema<
8218
+ readonly ["workflow", "stage", "activity"],
8219
+ string
8220
+ >;
8221
+ readonly field: v.SchemaWithPipe<
8222
+ readonly [
8223
+ v.StringSchema<undefined>,
8224
+ v.MinLengthAction<string, 1, "must be a non-empty string">,
8225
+ ]
8226
+ >;
8227
+ },
8228
+ undefined
8229
+ >;
8230
+ readonly value: v.GenericSchema<ValueExprInternal>;
8231
+ },
8232
+ undefined
8233
+ >,
7979
8234
  v.StrictObjectSchema<
7980
8235
  {
7981
8236
  readonly type: v.LiteralSchema<"field.unset", undefined>;
@@ -8019,6 +8274,56 @@ declare const StoredFieldOpSchema: v.VariantSchema<
8019
8274
  },
8020
8275
  undefined
8021
8276
  >,
8277
+ v.StrictObjectSchema<
8278
+ {
8279
+ readonly type: v.LiteralSchema<"field.inc", undefined>;
8280
+ readonly target: v.StrictObjectSchema<
8281
+ {
8282
+ readonly scope: v.PicklistSchema<
8283
+ readonly ["workflow", "stage", "activity"],
8284
+ string
8285
+ >;
8286
+ readonly field: v.SchemaWithPipe<
8287
+ readonly [
8288
+ v.StringSchema<undefined>,
8289
+ v.MinLengthAction<string, 1, "must be a non-empty string">,
8290
+ ]
8291
+ >;
8292
+ },
8293
+ undefined
8294
+ >;
8295
+ readonly value: v.OptionalSchema<
8296
+ v.GenericSchema<ValueExprInternal>,
8297
+ undefined
8298
+ >;
8299
+ },
8300
+ undefined
8301
+ >,
8302
+ v.StrictObjectSchema<
8303
+ {
8304
+ readonly type: v.LiteralSchema<"field.dec", undefined>;
8305
+ readonly target: v.StrictObjectSchema<
8306
+ {
8307
+ readonly scope: v.PicklistSchema<
8308
+ readonly ["workflow", "stage", "activity"],
8309
+ string
8310
+ >;
8311
+ readonly field: v.SchemaWithPipe<
8312
+ readonly [
8313
+ v.StringSchema<undefined>,
8314
+ v.MinLengthAction<string, 1, "must be a non-empty string">,
8315
+ ]
8316
+ >;
8317
+ },
8318
+ undefined
8319
+ >;
8320
+ readonly value: v.OptionalSchema<
8321
+ v.GenericSchema<ValueExprInternal>,
8322
+ undefined
8323
+ >;
8324
+ },
8325
+ undefined
8326
+ >,
8022
8327
  v.StrictObjectSchema<
8023
8328
  {
8024
8329
  readonly type: v.LiteralSchema<"field.updateWhere", undefined>;
@@ -8162,6 +8467,28 @@ declare const StoredOpSchema: v.VariantSchema<
8162
8467
  },
8163
8468
  undefined
8164
8469
  >,
8470
+ v.StrictObjectSchema<
8471
+ {
8472
+ readonly type: v.LiteralSchema<"field.setIfMissing", undefined>;
8473
+ readonly target: v.StrictObjectSchema<
8474
+ {
8475
+ readonly scope: v.PicklistSchema<
8476
+ readonly ["workflow", "stage", "activity"],
8477
+ string
8478
+ >;
8479
+ readonly field: v.SchemaWithPipe<
8480
+ readonly [
8481
+ v.StringSchema<undefined>,
8482
+ v.MinLengthAction<string, 1, "must be a non-empty string">,
8483
+ ]
8484
+ >;
8485
+ },
8486
+ undefined
8487
+ >;
8488
+ readonly value: v.GenericSchema<ValueExprInternal>;
8489
+ },
8490
+ undefined
8491
+ >,
8165
8492
  v.StrictObjectSchema<
8166
8493
  {
8167
8494
  readonly type: v.LiteralSchema<"field.unset", undefined>;
@@ -8205,6 +8532,56 @@ declare const StoredOpSchema: v.VariantSchema<
8205
8532
  },
8206
8533
  undefined
8207
8534
  >,
8535
+ v.StrictObjectSchema<
8536
+ {
8537
+ readonly type: v.LiteralSchema<"field.inc", undefined>;
8538
+ readonly target: v.StrictObjectSchema<
8539
+ {
8540
+ readonly scope: v.PicklistSchema<
8541
+ readonly ["workflow", "stage", "activity"],
8542
+ string
8543
+ >;
8544
+ readonly field: v.SchemaWithPipe<
8545
+ readonly [
8546
+ v.StringSchema<undefined>,
8547
+ v.MinLengthAction<string, 1, "must be a non-empty string">,
8548
+ ]
8549
+ >;
8550
+ },
8551
+ undefined
8552
+ >;
8553
+ readonly value: v.OptionalSchema<
8554
+ v.GenericSchema<ValueExprInternal>,
8555
+ undefined
8556
+ >;
8557
+ },
8558
+ undefined
8559
+ >,
8560
+ v.StrictObjectSchema<
8561
+ {
8562
+ readonly type: v.LiteralSchema<"field.dec", undefined>;
8563
+ readonly target: v.StrictObjectSchema<
8564
+ {
8565
+ readonly scope: v.PicklistSchema<
8566
+ readonly ["workflow", "stage", "activity"],
8567
+ string
8568
+ >;
8569
+ readonly field: v.SchemaWithPipe<
8570
+ readonly [
8571
+ v.StringSchema<undefined>,
8572
+ v.MinLengthAction<string, 1, "must be a non-empty string">,
8573
+ ]
8574
+ >;
8575
+ },
8576
+ undefined
8577
+ >;
8578
+ readonly value: v.OptionalSchema<
8579
+ v.GenericSchema<ValueExprInternal>,
8580
+ undefined
8581
+ >;
8582
+ },
8583
+ undefined
8584
+ >,
8208
8585
  v.StrictObjectSchema<
8209
8586
  {
8210
8587
  readonly type: v.LiteralSchema<"field.updateWhere", undefined>;
@@ -8813,6 +9190,13 @@ export declare function unsatisfiedTransitionSummaries(
8813
9190
  summary: string;
8814
9191
  }[];
8815
9192
 
9193
+ /**
9194
+ * Normalize Management API user-attribute payloads into the `$attributes`
9195
+ * bag. Fetch/caching stays in access resolution; this module is I/O-free.
9196
+ */
9197
+ /** Flat key → active-value record bound as advisory `$attributes` when present. */
9198
+ export declare type UserAttributes = Record<string, unknown>;
9199
+
8816
9200
  /** The identity provider under whichever spelling the answering endpoint used
8817
9201
  * — the ONE place that disagreement is resolved. */
8818
9202
  export declare function userLoginProvider(
@@ -9367,7 +9751,8 @@ declare const WORKFLOW_LIFECYCLES: readonly ["standalone", "child"];
9367
9751
  * can read; there is no engine-side permission verdict. When grants are
9368
9752
  * absent the rendered `$can` is undefined — conditions referencing it
9369
9753
  * fail closed, everything else is ungated engine-side — and the real
9370
- * Sanity write boundary takes over.
9754
+ * Sanity write boundary takes over. See {@link WorkflowAccess.attributes}
9755
+ * for the parallel `$attributes` bag.
9371
9756
  */
9372
9757
  export declare interface WorkflowAccess {
9373
9758
  actor: Actor;
@@ -9382,6 +9767,12 @@ export declare interface WorkflowAccess {
9382
9767
  */
9383
9768
  localPrincipalId?: string;
9384
9769
  grants?: Grant[];
9770
+ /**
9771
+ * Optional bag for callers that compose a {@link WorkflowAccess} by hand
9772
+ * (the test bench). {@link resolveAccess} never populates this — soft-gate
9773
+ * paths load attributes via {@link resolveUserAttributes}.
9774
+ */
9775
+ attributes?: UserAttributes;
9385
9776
  }
9386
9777
 
9387
9778
  export declare const WorkflowActionFired: WorkflowTelemetryEvent<WorkflowActionFiredData>;
@@ -9582,11 +9973,18 @@ export declare interface WorkflowCommitOptions {
9582
9973
  tag?: string;
9583
9974
  }
9584
9975
 
9585
- export declare type WorkflowConfig = Omit<
9586
- ParsedWorkflowConfig,
9976
+ export declare type WorkflowConfig = v.InferOutput<typeof WorkflowConfigSchema>;
9977
+
9978
+ /**
9979
+ * What an author writes for a whole config: every deployment is a
9980
+ * {@link WorkflowDeploymentInput}. `defineWorkflowConfig` accepts this and
9981
+ * returns the looser {@link WorkflowConfig}.
9982
+ */
9983
+ export declare type WorkflowConfigInput = Omit<
9984
+ WorkflowConfig,
9587
9985
  "deployments"
9588
9986
  > & {
9589
- deployments: WorkflowDeployment[];
9987
+ deployments: WorkflowDeploymentInput[];
9590
9988
  };
9591
9989
 
9592
9990
  declare const WorkflowConfigSchema: v.ObjectSchema<
@@ -9852,6 +10250,7 @@ declare const WorkflowConfigSchema: v.ObjectSchema<
9852
10250
  v.CustomSchema<
9853
10251
  {
9854
10252
  name: string;
10253
+ semantics?: Semantic[] | undefined;
9855
10254
  title: string;
9856
10255
  description?: string | undefined;
9857
10256
  groups?: Group[] | undefined;
@@ -9870,6 +10269,7 @@ declare const WorkflowConfigSchema: v.ObjectSchema<
9870
10269
  v.MinLengthAction<
9871
10270
  {
9872
10271
  name: string;
10272
+ semantics?: Semantic[] | undefined;
9873
10273
  title: string;
9874
10274
  description?: string | undefined;
9875
10275
  groups?: Group[] | undefined;
@@ -9937,6 +10337,7 @@ declare const WorkflowConfigSchema: v.ObjectSchema<
9937
10337
  | undefined;
9938
10338
  definitions: {
9939
10339
  name: string;
10340
+ semantics?: Semantic[] | undefined;
9940
10341
  title: string;
9941
10342
  description?: string | undefined;
9942
10343
  groups?: Group[] | undefined;
@@ -9998,6 +10399,7 @@ declare const WorkflowConfigSchema: v.ObjectSchema<
9998
10399
  | undefined;
9999
10400
  definitions: {
10000
10401
  name: string;
10402
+ semantics?: Semantic[] | undefined;
10001
10403
  title: string;
10002
10404
  description?: string | undefined;
10003
10405
  groups?: Group[] | undefined;
@@ -10057,6 +10459,7 @@ declare const WorkflowConfigSchema: v.ObjectSchema<
10057
10459
  | undefined;
10058
10460
  definitions: {
10059
10461
  name: string;
10462
+ semantics?: Semantic[] | undefined;
10060
10463
  title: string;
10061
10464
  description?: string | undefined;
10062
10465
  groups?: Group[] | undefined;
@@ -10118,6 +10521,7 @@ declare const WorkflowConfigSchema: v.ObjectSchema<
10118
10521
  | undefined;
10119
10522
  definitions: {
10120
10523
  name: string;
10524
+ semantics?: Semantic[] | undefined;
10121
10525
  title: string;
10122
10526
  description?: string | undefined;
10123
10527
  groups?: Group[] | undefined;
@@ -10177,6 +10581,7 @@ declare const WorkflowConfigSchema: v.ObjectSchema<
10177
10581
  | undefined;
10178
10582
  definitions: {
10179
10583
  name: string;
10584
+ semantics?: Semantic[] | undefined;
10180
10585
  title: string;
10181
10586
  description?: string | undefined;
10182
10587
  groups?: Group[] | undefined;
@@ -10297,15 +10702,25 @@ declare const WorkflowDefinitionSchema: v.GenericSchema<
10297
10702
  WorkflowFields<FieldEntry, Stage, StartBlock>
10298
10703
  >;
10299
10704
 
10300
- export declare type WorkflowDeployment = Omit<
10301
- ParsedWorkflowDeployment,
10705
+ /** One deployment as loaded from a config: the floor is optional/unverified so
10706
+ * a command that never selects a deployment can hold a stale or missing
10707
+ * acknowledgement. Deployment-scoped paths assert before they act; authors
10708
+ * write {@link WorkflowDeploymentInput}. */
10709
+ export declare type WorkflowDeployment = WorkflowConfig["deployments"][number];
10710
+
10711
+ /**
10712
+ * What an author writes for one deployment: the current reader floor as the
10713
+ * reviewed literal. Compile-time only — omitting it or setting a wrong value
10714
+ * is a type error in the editor. Runtime parse still tolerates a stale or
10715
+ * missing floor on {@link WorkflowDeployment} so commands that never select a
10716
+ * deployment still run; deployment-scoped paths assert the selected
10717
+ * deployment (instance-id commands do not).
10718
+ */
10719
+ export declare type WorkflowDeploymentInput = Omit<
10720
+ WorkflowDeployment,
10302
10721
  "expectedMinReaderModel"
10303
10722
  > & {
10304
- /**
10305
- * Reviewed numeric literal. Runtime validation owns the exact installed-floor check so a stale
10306
- * acknowledgement reaches the readers-first rollout guidance instead of becoming a type error.
10307
- */
10308
- expectedMinReaderModel: number;
10723
+ expectedMinReaderModel: typeof DATA_MODEL_MIN_READER;
10309
10724
  };
10310
10725
 
10311
10726
  export declare const WorkflowEffectCompleted: WorkflowTelemetryEvent<WorkflowEffectCompletedData>;
@@ -10400,6 +10815,8 @@ export declare type WorkflowErrorKind =
10400
10815
  export declare interface WorkflowEvaluation {
10401
10816
  instance: WorkflowInstance;
10402
10817
  definition: WorkflowDefinition;
10818
+ /** The workflow's advisory meaning, unchanged from its definition. */
10819
+ semantics?: Semantic[] | undefined;
10403
10820
  actor: Actor;
10404
10821
  currentStage: StageEvaluation;
10405
10822
  /** Active activities whose assignees-kind field entry matches the actor. */
@@ -10464,6 +10881,7 @@ declare type WorkflowFields<TField, TStage, TStart> = {
10464
10881
  * subworkflows resolve by it.
10465
10882
  */
10466
10883
  name: string;
10884
+ semantics?: Semantic[] | undefined;
10467
10885
  title: string;
10468
10886
  description?: string | undefined;
10469
10887
  groups?: Group[] | undefined;