@sanity/workflow-engine 0.31.0 → 0.33.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
@@ -99,8 +99,10 @@ export declare function aclPathForResource(
99
99
  * only when cascade-fired (the pin on which identities may execute the
100
100
  * trigger); a fireAction-fired action's `roles` folds into `filter` at
101
101
  * desugar instead.
102
+ *
103
+ * @interface
102
104
  */
103
- export declare type Action = ActionFields<Op, string[]> & {
105
+ export declare type Action = ActionFields<Op, string[], Effect> & {
104
106
  roles?: string[] | undefined;
105
107
  };
106
108
 
@@ -185,11 +187,16 @@ export declare interface ActionEvaluation {
185
187
  /** Derived state of a cascade-fired action's `when` trigger — what would
186
188
  * fire it. Present iff the action declares `when`. */
187
189
  whenInsight?: ConditionInsight;
190
+ /** A canonical `$assigned` filter leg withheld this absent action. The
191
+ * action still follows filter-existence semantics; this metadata lets the
192
+ * owning activity explain who currently holds the work. */
193
+ holderGate?: {
194
+ holders: Assignee[];
195
+ };
188
196
  }
189
197
 
190
- /** Type-mirror of {@link actionFields}, parameterised over the op and
191
- * group-membership grammars. */
192
- declare type ActionFields<TOp, TGroup> = {
198
+ /** @inline */
199
+ declare type ActionFields<TOp, TGroup, TEffect> = {
193
200
  name: string;
194
201
  semantics?: ActionSemantic[] | undefined;
195
202
  title?: string | undefined;
@@ -199,7 +206,7 @@ declare type ActionFields<TOp, TGroup> = {
199
206
  filter?: string | undefined;
200
207
  params?: ActionParam[] | undefined;
201
208
  ops?: TOp[] | undefined;
202
- effects?: Effect[] | undefined;
209
+ effects?: TEffect[] | undefined;
203
210
  spawn?: Subworkflows | undefined;
204
211
  };
205
212
 
@@ -210,6 +217,8 @@ export declare type ActionName = string;
210
217
  * or queuing effects: a missing required param throws
211
218
  * `ActionParamsInvalidError` and the action does not commit. Resolved values
212
219
  * feed `ValueExpr.param` lookups.
220
+ *
221
+ * @interface
213
222
  */
214
223
  export declare type ActionParam = v.InferOutput<typeof ActionParamSchema>;
215
224
 
@@ -390,6 +399,11 @@ export declare function actionVerdict(
390
399
  action: ActionEvaluation,
391
400
  ): AvailableAction;
392
401
 
402
+ /** The members that own work after direct-user membership shadows every role route. */
403
+ export declare function activeAssignmentMembers(
404
+ members: readonly Assignee[],
405
+ ): readonly Assignee[];
406
+
393
407
  /**
394
408
  * A unit of work carrying no payload of its own — every op, effect, and
395
409
  * spawn lives on an action; an activity contributes scoped `fields`
@@ -403,6 +417,8 @@ export declare function actionVerdict(
403
417
  * `requirements` are readiness gates orthogonal to `filter` — an unmet one
404
418
  * keeps the activity visible but disables its actions with a
405
419
  * `requirements-unmet` verdict; distinct from ACL and guards.
420
+ *
421
+ * @interface
406
422
  */
407
423
  export declare type Activity = ActivityFields<
408
424
  FieldEntry,
@@ -454,19 +470,6 @@ export declare const ACTIVITY_KINDS: readonly [
454
470
  "receive",
455
471
  ];
456
472
 
457
- /**
458
- * An activity is `active` from stage entry (or `skipped` when its `filter`
459
- * excluded it) until a terminal status resolves it — there is no pre-active
460
- * state. The authored action `status:` sugar (and the `status.set` op it
461
- * desugars to) is constrained to {@link TerminalActivityStatus}.
462
- */
463
- declare const ACTIVITY_STATUSES: readonly [
464
- "active",
465
- "done",
466
- "skipped",
467
- "failed",
468
- ];
469
-
470
473
  /** The activity slice of a stage rollup — total by construction, like
471
474
  * {@link stageAutonomyOf}. */
472
475
  export declare function activityAutonomyOf(
@@ -548,15 +551,14 @@ export declare interface ActivityEvaluation {
548
551
  */
549
552
  scopedOut: boolean;
550
553
  /**
551
- * The activity's unmet {@link Activity.requirements}, with authored display copy — present iff at least
552
- * one is unmet. The activity's own readiness summary: a consumer can explain why
553
- * the whole activity is gated without inspecting each action (every action also
554
- * carries the matching `requirements-unmet` `disabledReason`).
554
+ * Unmet authored activity requirements and required-reference readability checks.
555
+ * Present when at least one is unmet. Required-reference descriptors use
556
+ * `field:<name>` and the field's declared title when available.
555
557
  */
556
558
  unmetRequirements?: RequirementDescriptor[];
557
- /** Derived state per declared requirement, keyed by requirement name.
558
- * Present iff the activity declares requirements; `unmetRequirements`
559
- * contains descriptors for exactly the requirements whose insight isn't satisfied. */
559
+ /** Derived state per authored requirement, keyed by its declared name.
560
+ * Present when the activity declares requirements. Unmet authored requirements
561
+ * appear in `unmetRequirements`; required-reference checks have no insight entry. */
560
562
  requirementInsights?: Record<string, ConditionInsight>;
561
563
  /** Derived state of the activity's `filter` existence gate. Present iff
562
564
  * declared. Advisory read: the engine's stage entry owns the gate itself. */
@@ -564,7 +566,7 @@ export declare interface ActivityEvaluation {
564
566
  actions: ActionEvaluation[];
565
567
  }
566
568
 
567
- /** Type-mirror of {@link activityFields}, parameterised over field/action/target/group. */
569
+ /** @inline */
568
570
  declare type ActivityFields<TField, TAction, TTarget, TGroup> = {
569
571
  name: string;
570
572
  semantics?: Semantic[] | undefined;
@@ -583,7 +585,13 @@ export declare type ActivityKind = (typeof ACTIVITY_KINDS)[number];
583
585
 
584
586
  export declare type ActivityName = string;
585
587
 
586
- export declare type ActivityStatus = (typeof ACTIVITY_STATUSES)[number];
588
+ /**
589
+ * An activity is `active` from stage entry (or `skipped` when its `filter`
590
+ * excluded it) until a terminal status resolves it — there is no pre-active
591
+ * state. The authored action `status:` sugar (and the `status.set` op it
592
+ * desugars to) is constrained to {@link TerminalActivityStatus}.
593
+ */
594
+ export declare type ActivityStatus = "active" | "done" | "skipped" | "failed";
587
595
 
588
596
  /**
589
597
  * Who is acting — advisory provenance, not an authenticated principal. The
@@ -633,7 +641,13 @@ export declare interface Actor {
633
641
  */
634
642
  export declare const ACTOR_KINDS: readonly ["person", "agent", "system"];
635
643
 
636
- /** Runtime counterpart of {@link expandRequiredRoles}; both expand only the required side. */
644
+ /**
645
+ * Checks whether an actor role fulfills `required`, directly or through one
646
+ * level of aliases. Pass `roleAliases` from a definition returned by
647
+ * {@link define.defineWorkflow | defineWorkflow}; its universal aliases are
648
+ * normalized. A raw authored `"*"` entry is not expanded here.
649
+ * This role check is advisory.
650
+ */
637
651
  export declare function actorFulfillsRole({
638
652
  actorRoles,
639
653
  required,
@@ -646,6 +660,13 @@ export declare function actorFulfillsRole({
646
660
 
647
661
  export declare type ActorKind = (typeof ACTOR_KINDS)[number];
648
662
 
663
+ /** Assignment ownership for runtime actors, with authorization aliases applied to role members. */
664
+ export declare function actorMatchesAssignment(args: {
665
+ actor: Actor | undefined;
666
+ members: readonly Assignee[];
667
+ roleAliases?: RoleAliases | undefined;
668
+ }): boolean;
669
+
649
670
  export declare type ActorResolution<User> =
650
671
  | {
651
672
  readonly status: "resolved";
@@ -666,6 +687,14 @@ export declare type ActorResolution<User> =
666
687
  readonly actor: Actor;
667
688
  };
668
689
 
690
+ /** Missing-reference evidence accompanying another primary fault, for workspace renderers only.
691
+ * @internal
692
+ */
693
+ export declare function _additionalMissingDocuments(
694
+ diagnosis: Diagnosis,
695
+ documents: MissingDocument[] | undefined,
696
+ ): MissingDocument[];
697
+
669
698
  export { analyzeCondition };
670
699
 
671
700
  /** Lake `identity()` sentinel for unauthenticated callers. */
@@ -720,12 +749,13 @@ export declare function assertReaderModelAcknowledgement(
720
749
  ): asserts expectedMinReaderModel is number;
721
750
 
722
751
  /**
723
- * One member of an `assignees`-kind entry's value and the value of the
724
- * singular `assignee` kind. The WHO-FOR spec the inbox reverse-query and the
725
- * rendered `$assigned` gate match against. A `role` member names a capability
726
- * (fulfilled by whoever deploys that role), not a concrete principal — which
727
- * is what distinguishes it from {@link Actor}. `id` here is a SYSTEM
728
- * identifier (a principal), not authored identity.
752
+ * One member of an `assignee` or `assignees` field. For a user member, pass a
753
+ * human's account-global `sanityUserId`, not a project-scoped user ID. Robot
754
+ * IDs are rejected.
755
+ *
756
+ * A role member identifies a project role, not an individual {@link Actor}.
757
+ * Direct user members take ownership ahead of role members. Role aliases apply
758
+ * to `$assigned` authorization, but inbox routing uses literal project roles.
729
759
  */
730
760
  export declare type Assignee =
731
761
  | {
@@ -737,6 +767,56 @@ export declare type Assignee =
737
767
  role: string;
738
768
  };
739
769
 
770
+ export declare interface AssignmentIdentity {
771
+ readonly userId: string;
772
+ readonly roles: readonly string[];
773
+ }
774
+
775
+ /** @inline */
776
+ declare type AssignmentInstance = Pick<
777
+ WorkflowInstance,
778
+ "currentStage" | "stages"
779
+ >;
780
+
781
+ export declare type AssignmentMatch = "user" | "role" | undefined;
782
+
783
+ /** Whether an identity owns the assignment directly or through a literal project role. */
784
+ export declare function assignmentMatch(
785
+ members: readonly Assignee[],
786
+ identity: AssignmentIdentity,
787
+ ): AssignmentMatch;
788
+
789
+ /** Every member stored in assignment entries, preserving field and member order. */
790
+ export declare function assignmentMembers(
791
+ entries: readonly ResolvedFieldEntry[],
792
+ ): readonly Assignee[];
793
+
794
+ export declare function assignmentPrefilter(
795
+ assignment: NonNullable<InstancesQueryFilter["assignment"]>,
796
+ params: Record<string, string | string[]>,
797
+ ): string;
798
+
799
+ export declare type AssignmentState = "unrouted" | "routed" | "held";
800
+
801
+ /** Classify one assignment slot by whether it has no route, role routes, or a user holder. */
802
+ export declare function assignmentState(
803
+ members: readonly Assignee[],
804
+ ): AssignmentState;
805
+
806
+ export declare interface AssignmentStateCounts {
807
+ readonly unrouted: number;
808
+ readonly routed: number;
809
+ readonly held: number;
810
+ }
811
+
812
+ /** Viewer-scoped assignment counts at assignment-slot grain. Unrouted work is
813
+ * visible to every viewer; routed and held count only work offered to or
814
+ * held by the supplied identity. */
815
+ export declare function assignmentStateCounts(
816
+ assignments: readonly (readonly Assignee[])[],
817
+ identity: AssignmentIdentity,
818
+ ): AssignmentStateCounts;
819
+
740
820
  export { AtomInsight };
741
821
 
742
822
  export { atomReadsDataset };
@@ -766,8 +846,7 @@ export declare const AUTHORING_DISPLAY: {
766
846
  };
767
847
 
768
848
  /**
769
- * The stored action fields plus two authoring sugars, or the
770
- * {@link ClaimAction} pair-half. `roles`: on a fireAction-fired action (no
849
+ * The stored action fields plus authoring sugar. `roles`: on a fireAction-fired action (no
771
850
  * `when`) it desugars into a `count($actor.roles[@ in [...]]) > 0` condition
772
851
  * ANDed with `filter`; on a CASCADE-FIRED action it stores VERBATIM instead —
773
852
  * the pin on which identities may execute the trigger, since folding it into
@@ -777,8 +856,9 @@ export declare const AUTHORING_DISPLAY: {
777
856
  * deliberately never implied, so a forgotten `status` is a visible stall
778
857
  * rather than a silently completed action.
779
858
  */
780
- export declare type AuthoringAction = AuthoringRawAction | ClaimAction;
859
+ export declare type AuthoringAction = AuthoringRawAction;
781
860
 
861
+ /** @interface */
782
862
  export declare type AuthoringActivity = ActivityFields<
783
863
  AuthoringFieldEntry,
784
864
  AuthoringAction,
@@ -792,41 +872,48 @@ export declare type AuthoringActivity = ActivityFields<
792
872
  * predicate `action.roles` produces. `true` opens the field to anyone in its
793
873
  * window; a bare string is a raw predicate.
794
874
  */
795
- export declare type AuthoringEditable = v.InferOutput<
796
- typeof AuthoringEditableSchema
797
- >;
875
+ export declare type AuthoringEditable = true | string[] | string;
798
876
 
799
- declare const AuthoringEditableSchema: v.UnionSchema<
800
- [
801
- v.LiteralSchema<true, undefined>,
802
- v.ArraySchema<
803
- v.SchemaWithPipe<
804
- readonly [
805
- v.StringSchema<undefined>,
806
- v.MinLengthAction<string, 1, "must be a non-empty string">,
807
- ]
808
- >,
809
- undefined
810
- >,
811
- v.SchemaWithPipe<
812
- readonly [
813
- v.StringSchema<undefined>,
814
- v.MinLengthAction<string, 1, "must be a non-empty string">,
815
- ]
816
- >,
817
- ],
818
- undefined
819
- >;
877
+ /**
878
+ * An {@link Effect} whose `retry` block may omit its `kind`, plus the
879
+ * authoring-only `runtime` block that says where the generated runtime hosts
880
+ * this handler. `retry` is stored; `runtime` is stripped before the deploy
881
+ * writes the definition.
882
+ *
883
+ * @interface
884
+ */
885
+ export declare type AuthoringEffect = EffectFields<AuthoringEffectRetry> & {
886
+ runtime?: EffectRuntimeBlock | undefined;
887
+ };
820
888
 
889
+ /** An {@link EffectRetry} whose omitted `kind` defaults to `engine`. */
890
+ export declare type AuthoringEffectRetry = EffectRetryFields & {
891
+ kind?: EffectRetryKind | undefined;
892
+ };
893
+
894
+ /**
895
+ * A raw field entry or one of the authoring-only field sugars. `todoList`
896
+ * expands to an array of objects with `label`, `status`, optional `assignee`,
897
+ * and optional `dueDate`; that due date remains an ordinary date field.
898
+ * `notes` expands to an array of audit-shaped objects with `body`, `actor`,
899
+ * and `at` fields. Sugar type names are compiled away and never become stored
900
+ * field kinds.
901
+ * See {@link FieldEntry} for scope, required-input, and field-type constraints.
902
+ */
821
903
  export declare type AuthoringFieldEntry =
822
904
  | AuthoringRawFieldEntry
823
- | ClaimField
824
905
  | TodoListField
825
906
  | NotesField;
826
907
 
827
- /** A field reference with `scope` optional; desugar resolves it lexically
828
- * (activity stage workflow) into {@link StoredFieldRef}. */
829
- declare type AuthoringFieldRef = v.InferOutput<typeof AuthoringFieldRefSchema>;
908
+ /**
909
+ * A field reference with `scope` optional; desugar resolves it lexically
910
+ * (activity stage → workflow) into {@link StoredFieldRef}.
911
+ *
912
+ * @interface
913
+ */
914
+ export declare type AuthoringFieldRef = v.InferOutput<
915
+ typeof AuthoringFieldRefSchema
916
+ >;
830
917
 
831
918
  declare const AuthoringFieldRefSchema: v.StrictObjectSchema<
832
919
  {
@@ -844,8 +931,26 @@ declare const AuthoringFieldRefSchema: v.StrictObjectSchema<
844
931
  undefined
845
932
  >;
846
933
 
847
- /** {@link Guard}'s contract as authored: `match.idRefs` and `metadata` carry
848
- * typed {@link GuardRead} values that deploy resolves to bare ones. */
934
+ /**
935
+ * A stage's content mutation guard. Its name must be unique across the whole
936
+ * definition and use lowercase letters, digits, and dashes, starting with a
937
+ * letter or digit. `match.actions` must contain at least one action.
938
+ *
939
+ * `match.types` intersects the ID criteria. Within the ID criteria, matching
940
+ * either `idRefs` or `idPatterns` is sufficient. Omitted or empty optional
941
+ * criteria do not constrain the match. `idRefs` uses typed {@link GuardRead}s.
942
+ * Patterns use resource-local document-ID characters and `*` wildcards.
943
+ * A release-version pattern is rejected if translating it for a lifecycle
944
+ * action would broaden it to every document.
945
+ *
946
+ * `predicate` is delta-mode GROQ over `document`, `guard`, and `mutation`;
947
+ * see {@link GUARD_PREDICATE_VARS}. Only a strict `true` allows a matching
948
+ * mutation. An omitted or empty predicate denies it. `metadata` resolves
949
+ * {@link GuardRead}s into values available as `guard.metadata` in the predicate.
950
+ * Engine evaluations are advisory; the Content Lake is the enforcement point.
951
+ *
952
+ * @interface
953
+ */
849
954
  export declare type AuthoringGuard = v.InferOutput<typeof AuthoringGuardSchema>;
850
955
 
851
956
  declare const AuthoringGuardSchema: v.StrictObjectSchema<
@@ -873,105 +978,7 @@ declare const AuthoringGuardSchema: v.StrictObjectSchema<
873
978
  undefined
874
979
  >;
875
980
  idRefs: v.OptionalSchema<
876
- v.ArraySchema<
877
- v.VariantSchema<
878
- "type",
879
- [
880
- v.StrictObjectSchema<
881
- {
882
- readonly type: v.LiteralSchema<"self", undefined>;
883
- },
884
- undefined
885
- >,
886
- v.StrictObjectSchema<
887
- {
888
- readonly type: v.LiteralSchema<"now", undefined>;
889
- },
890
- undefined
891
- >,
892
- v.StrictObjectSchema<
893
- {
894
- readonly type: v.LiteralSchema<"fieldRead", undefined>;
895
- readonly field: v.SchemaWithPipe<
896
- readonly [
897
- v.StringSchema<undefined>,
898
- v.RegexAction<string, string>,
899
- ]
900
- >;
901
- readonly path: v.OptionalSchema<
902
- v.SchemaWithPipe<
903
- readonly [
904
- v.SchemaWithPipe<
905
- readonly [
906
- v.StringSchema<undefined>,
907
- v.MinLengthAction<
908
- string,
909
- 1,
910
- "must be a non-empty string"
911
- >,
912
- ]
913
- >,
914
- v.CheckAction<
915
- string,
916
- "a guard read path cannot contain a line break"
917
- >,
918
- ]
919
- >,
920
- undefined
921
- >;
922
- },
923
- undefined
924
- >,
925
- v.StrictObjectSchema<
926
- {
927
- readonly type: v.LiteralSchema<"effectsRead", undefined>;
928
- readonly effect: v.SchemaWithPipe<
929
- readonly [
930
- v.SchemaWithPipe<
931
- readonly [
932
- v.StringSchema<undefined>,
933
- v.MinLengthAction<
934
- string,
935
- 1,
936
- "must be a non-empty string"
937
- >,
938
- ]
939
- >,
940
- v.CheckAction<
941
- string,
942
- "an effect name cannot contain `'`"
943
- >,
944
- ]
945
- >;
946
- readonly path: v.OptionalSchema<
947
- v.SchemaWithPipe<
948
- readonly [
949
- v.SchemaWithPipe<
950
- readonly [
951
- v.StringSchema<undefined>,
952
- v.MinLengthAction<
953
- string,
954
- 1,
955
- "must be a non-empty string"
956
- >,
957
- ]
958
- >,
959
- v.CheckAction<
960
- string,
961
- "a guard read path cannot contain a line break"
962
- >,
963
- ]
964
- >,
965
- undefined
966
- >;
967
- },
968
- undefined
969
- >,
970
- ],
971
- undefined
972
- >,
973
- undefined
974
- >,
981
+ v.ArraySchema<v.GenericSchema<GuardRead>, undefined>,
975
982
  undefined
976
983
  >;
977
984
  idPatterns: v.OptionalSchema<
@@ -1014,99 +1021,7 @@ declare const AuthoringGuardSchema: v.StrictObjectSchema<
1014
1021
  v.MinLengthAction<string, 1, "must be a non-empty string">,
1015
1022
  ]
1016
1023
  >,
1017
- v.VariantSchema<
1018
- "type",
1019
- [
1020
- v.StrictObjectSchema<
1021
- {
1022
- readonly type: v.LiteralSchema<"self", undefined>;
1023
- },
1024
- undefined
1025
- >,
1026
- v.StrictObjectSchema<
1027
- {
1028
- readonly type: v.LiteralSchema<"now", undefined>;
1029
- },
1030
- undefined
1031
- >,
1032
- v.StrictObjectSchema<
1033
- {
1034
- readonly type: v.LiteralSchema<"fieldRead", undefined>;
1035
- readonly field: v.SchemaWithPipe<
1036
- readonly [
1037
- v.StringSchema<undefined>,
1038
- v.RegexAction<string, string>,
1039
- ]
1040
- >;
1041
- readonly path: v.OptionalSchema<
1042
- v.SchemaWithPipe<
1043
- readonly [
1044
- v.SchemaWithPipe<
1045
- readonly [
1046
- v.StringSchema<undefined>,
1047
- v.MinLengthAction<
1048
- string,
1049
- 1,
1050
- "must be a non-empty string"
1051
- >,
1052
- ]
1053
- >,
1054
- v.CheckAction<
1055
- string,
1056
- "a guard read path cannot contain a line break"
1057
- >,
1058
- ]
1059
- >,
1060
- undefined
1061
- >;
1062
- },
1063
- undefined
1064
- >,
1065
- v.StrictObjectSchema<
1066
- {
1067
- readonly type: v.LiteralSchema<"effectsRead", undefined>;
1068
- readonly effect: v.SchemaWithPipe<
1069
- readonly [
1070
- v.SchemaWithPipe<
1071
- readonly [
1072
- v.StringSchema<undefined>,
1073
- v.MinLengthAction<
1074
- string,
1075
- 1,
1076
- "must be a non-empty string"
1077
- >,
1078
- ]
1079
- >,
1080
- v.CheckAction<string, "an effect name cannot contain `'`">,
1081
- ]
1082
- >;
1083
- readonly path: v.OptionalSchema<
1084
- v.SchemaWithPipe<
1085
- readonly [
1086
- v.SchemaWithPipe<
1087
- readonly [
1088
- v.StringSchema<undefined>,
1089
- v.MinLengthAction<
1090
- string,
1091
- 1,
1092
- "must be a non-empty string"
1093
- >,
1094
- ]
1095
- >,
1096
- v.CheckAction<
1097
- string,
1098
- "a guard read path cannot contain a line break"
1099
- >,
1100
- ]
1101
- >,
1102
- undefined
1103
- >;
1104
- },
1105
- undefined
1106
- >,
1107
- ],
1108
- undefined
1109
- >,
1024
+ v.GenericSchema<GuardRead>,
1110
1025
  undefined
1111
1026
  >,
1112
1027
  undefined
@@ -1117,373 +1032,64 @@ declare const AuthoringGuardSchema: v.StrictObjectSchema<
1117
1032
 
1118
1033
  /** Like {@link ManualTarget}, but the `field` variant also accepts a bare
1119
1034
  * field name; desugar normalises it into {@link AuthoringFieldRef}. */
1120
- export declare type AuthoringManualTarget = v.InferOutput<
1121
- typeof AuthoringManualTargetSchema
1122
- >;
1123
-
1124
- declare const AuthoringManualTargetSchema: v.VariantSchema<
1125
- "type",
1126
- [
1127
- v.StrictObjectSchema<
1128
- {
1129
- readonly type: v.LiteralSchema<"url", undefined>;
1130
- readonly url: v.SchemaWithPipe<
1131
- readonly [
1132
- v.StringSchema<undefined>,
1133
- v.UrlAction<string, "must be a valid URL">,
1134
- v.CheckAction<string, "must be an http(s) URL">,
1135
- ]
1136
- >;
1137
- },
1138
- undefined
1139
- >,
1140
- v.StrictObjectSchema<
1141
- {
1142
- readonly type: v.LiteralSchema<"field", undefined>;
1143
- readonly field: v.UnionSchema<
1144
- [
1145
- v.SchemaWithPipe<
1146
- readonly [
1147
- v.StringSchema<undefined>,
1148
- v.MinLengthAction<string, 1, "must be a non-empty string">,
1149
- ]
1150
- >,
1151
- v.StrictObjectSchema<
1152
- {
1153
- readonly scope: v.OptionalSchema<
1154
- v.PicklistSchema<
1155
- readonly ["workflow", "stage", "activity"],
1156
- string
1157
- >,
1158
- undefined
1159
- >;
1160
- readonly field: v.SchemaWithPipe<
1161
- readonly [
1162
- v.StringSchema<undefined>,
1163
- v.MinLengthAction<string, 1, "must be a non-empty string">,
1164
- ]
1165
- >;
1166
- },
1167
- undefined
1168
- >,
1169
- ],
1170
- undefined
1171
- >;
1172
- },
1173
- undefined
1174
- >,
1175
- ],
1176
- undefined
1177
- >;
1035
+ export declare type AuthoringManualTarget =
1036
+ | {
1037
+ type: "url";
1038
+ url: string;
1039
+ }
1040
+ | {
1041
+ type: "field";
1042
+ field: string | AuthoringFieldRef;
1043
+ };
1178
1044
 
1179
1045
  /** Like {@link Op}, plus: `status.set`'s `activity` is optional (desugar fills
1180
1046
  * the firing activity), and the `audit` sugar — a stamped append merging
1181
- * `actor`/`at` {@link ValueExpr} fields into its own value. */
1182
- export declare type AuthoringOp = v.InferOutput<typeof AuthoringOpSchema>;
1183
-
1184
- declare const AuthoringOpSchema: v.VariantSchema<
1185
- "type",
1186
- [
1187
- v.StrictObjectSchema<
1188
- {
1189
- readonly type: v.LiteralSchema<"field.set", undefined>;
1190
- readonly target: v.StrictObjectSchema<
1191
- {
1192
- readonly scope: v.OptionalSchema<
1193
- v.PicklistSchema<
1194
- readonly ["workflow", "stage", "activity"],
1195
- string
1196
- >,
1197
- undefined
1198
- >;
1199
- readonly field: v.SchemaWithPipe<
1200
- readonly [
1201
- v.StringSchema<undefined>,
1202
- v.MinLengthAction<string, 1, "must be a non-empty string">,
1203
- ]
1204
- >;
1205
- },
1206
- undefined
1207
- >;
1208
- readonly value: v.GenericSchema<ValueExprInternal>;
1209
- },
1210
- undefined
1211
- >,
1212
- v.StrictObjectSchema<
1213
- {
1214
- readonly type: v.LiteralSchema<"field.setIfMissing", undefined>;
1215
- readonly target: v.StrictObjectSchema<
1216
- {
1217
- readonly scope: v.OptionalSchema<
1218
- v.PicklistSchema<
1219
- readonly ["workflow", "stage", "activity"],
1220
- string
1221
- >,
1222
- undefined
1223
- >;
1224
- readonly field: v.SchemaWithPipe<
1225
- readonly [
1226
- v.StringSchema<undefined>,
1227
- v.MinLengthAction<string, 1, "must be a non-empty string">,
1228
- ]
1229
- >;
1230
- },
1231
- undefined
1232
- >;
1233
- readonly value: v.GenericSchema<ValueExprInternal>;
1234
- },
1235
- undefined
1236
- >,
1237
- v.StrictObjectSchema<
1238
- {
1239
- readonly type: v.LiteralSchema<"field.unset", undefined>;
1240
- readonly target: v.StrictObjectSchema<
1241
- {
1242
- readonly scope: v.OptionalSchema<
1243
- v.PicklistSchema<
1244
- readonly ["workflow", "stage", "activity"],
1245
- string
1246
- >,
1247
- undefined
1248
- >;
1249
- readonly field: v.SchemaWithPipe<
1250
- readonly [
1251
- v.StringSchema<undefined>,
1252
- v.MinLengthAction<string, 1, "must be a non-empty string">,
1253
- ]
1254
- >;
1255
- },
1256
- undefined
1257
- >;
1258
- },
1259
- undefined
1260
- >,
1261
- v.StrictObjectSchema<
1262
- {
1263
- readonly type: v.LiteralSchema<"field.append", undefined>;
1264
- readonly target: v.StrictObjectSchema<
1265
- {
1266
- readonly scope: v.OptionalSchema<
1267
- v.PicklistSchema<
1268
- readonly ["workflow", "stage", "activity"],
1269
- string
1270
- >,
1271
- undefined
1272
- >;
1273
- readonly field: v.SchemaWithPipe<
1274
- readonly [
1275
- v.StringSchema<undefined>,
1276
- v.MinLengthAction<string, 1, "must be a non-empty string">,
1277
- ]
1278
- >;
1279
- },
1280
- undefined
1281
- >;
1282
- readonly value: v.GenericSchema<ValueExprInternal>;
1283
- },
1284
- undefined
1285
- >,
1286
- v.StrictObjectSchema<
1287
- {
1288
- readonly type: v.LiteralSchema<"field.inc", undefined>;
1289
- readonly target: v.StrictObjectSchema<
1290
- {
1291
- readonly scope: v.OptionalSchema<
1292
- v.PicklistSchema<
1293
- readonly ["workflow", "stage", "activity"],
1294
- string
1295
- >,
1296
- undefined
1297
- >;
1298
- readonly field: v.SchemaWithPipe<
1299
- readonly [
1300
- v.StringSchema<undefined>,
1301
- v.MinLengthAction<string, 1, "must be a non-empty string">,
1302
- ]
1303
- >;
1304
- },
1305
- undefined
1306
- >;
1307
- readonly value: v.OptionalSchema<
1308
- v.GenericSchema<ValueExprInternal>,
1309
- undefined
1310
- >;
1311
- },
1312
- undefined
1313
- >,
1314
- v.StrictObjectSchema<
1315
- {
1316
- readonly type: v.LiteralSchema<"field.dec", undefined>;
1317
- readonly target: v.StrictObjectSchema<
1318
- {
1319
- readonly scope: v.OptionalSchema<
1320
- v.PicklistSchema<
1321
- readonly ["workflow", "stage", "activity"],
1322
- string
1323
- >,
1324
- undefined
1325
- >;
1326
- readonly field: v.SchemaWithPipe<
1327
- readonly [
1328
- v.StringSchema<undefined>,
1329
- v.MinLengthAction<string, 1, "must be a non-empty string">,
1330
- ]
1331
- >;
1332
- },
1333
- undefined
1334
- >;
1335
- readonly value: v.OptionalSchema<
1336
- v.GenericSchema<ValueExprInternal>,
1337
- undefined
1338
- >;
1339
- },
1340
- undefined
1341
- >,
1342
- v.StrictObjectSchema<
1343
- {
1344
- readonly type: v.LiteralSchema<"field.updateWhere", undefined>;
1345
- readonly target: v.StrictObjectSchema<
1346
- {
1347
- readonly scope: v.OptionalSchema<
1348
- v.PicklistSchema<
1349
- readonly ["workflow", "stage", "activity"],
1350
- string
1351
- >,
1352
- undefined
1353
- >;
1354
- readonly field: v.SchemaWithPipe<
1355
- readonly [
1356
- v.StringSchema<undefined>,
1357
- v.MinLengthAction<string, 1, "must be a non-empty string">,
1358
- ]
1359
- >;
1360
- },
1361
- undefined
1362
- >;
1363
- readonly where: v.SchemaWithPipe<
1364
- readonly [
1365
- v.StringSchema<undefined>,
1366
- v.MinLengthAction<string, 1, "must be a non-empty string">,
1367
- ]
1368
- >;
1369
- readonly value: v.GenericSchema<ValueExprInternal>;
1370
- },
1371
- undefined
1372
- >,
1373
- v.StrictObjectSchema<
1374
- {
1375
- readonly type: v.LiteralSchema<"field.removeWhere", undefined>;
1376
- readonly target: v.StrictObjectSchema<
1377
- {
1378
- readonly scope: v.OptionalSchema<
1379
- v.PicklistSchema<
1380
- readonly ["workflow", "stage", "activity"],
1381
- string
1382
- >,
1383
- undefined
1384
- >;
1385
- readonly field: v.SchemaWithPipe<
1386
- readonly [
1387
- v.StringSchema<undefined>,
1388
- v.MinLengthAction<string, 1, "must be a non-empty string">,
1389
- ]
1390
- >;
1391
- },
1392
- undefined
1393
- >;
1394
- readonly where: v.SchemaWithPipe<
1395
- readonly [
1396
- v.StringSchema<undefined>,
1397
- v.MinLengthAction<string, 1, "must be a non-empty string">,
1398
- ]
1399
- >;
1400
- },
1401
- undefined
1402
- >,
1403
- v.StrictObjectSchema<
1404
- {
1405
- readonly type: v.LiteralSchema<"status.set", undefined>;
1406
- readonly activity: v.OptionalSchema<
1407
- v.SchemaWithPipe<
1408
- readonly [
1409
- v.StringSchema<undefined>,
1410
- v.MinLengthAction<string, 1, "must be a non-empty string">,
1411
- ]
1412
- >,
1413
- undefined
1414
- >;
1415
- readonly status: v.PicklistSchema<
1416
- readonly ["active", "done", "skipped", "failed"],
1417
- string
1418
- >;
1419
- },
1420
- undefined
1421
- >,
1422
- v.StrictObjectSchema<
1423
- {
1424
- readonly type: v.LiteralSchema<"audit", undefined>;
1425
- readonly target: v.StrictObjectSchema<
1426
- {
1427
- readonly scope: v.OptionalSchema<
1428
- v.PicklistSchema<
1429
- readonly ["workflow", "stage", "activity"],
1430
- string
1431
- >,
1432
- undefined
1433
- >;
1434
- readonly field: v.SchemaWithPipe<
1435
- readonly [
1436
- v.StringSchema<undefined>,
1437
- v.MinLengthAction<string, 1, "must be a non-empty string">,
1438
- ]
1439
- >;
1440
- },
1441
- undefined
1442
- >;
1443
- readonly value: v.GenericSchema<ValueExprInternal>;
1444
- readonly stampFields: v.OptionalSchema<
1445
- v.StrictObjectSchema<
1446
- {
1447
- readonly actor: v.OptionalSchema<
1448
- v.SchemaWithPipe<
1449
- readonly [
1450
- v.StringSchema<undefined>,
1451
- v.MinLengthAction<string, 1, "must be a non-empty string">,
1452
- ]
1453
- >,
1454
- undefined
1455
- >;
1456
- readonly at: v.OptionalSchema<
1457
- v.SchemaWithPipe<
1458
- readonly [
1459
- v.StringSchema<undefined>,
1460
- v.MinLengthAction<string, 1, "must be a non-empty string">,
1461
- ]
1462
- >,
1463
- undefined
1464
- >;
1465
- },
1466
- undefined
1467
- >,
1468
- undefined
1469
- >;
1470
- },
1471
- undefined
1472
- >,
1473
- ],
1474
- undefined
1475
- >;
1047
+ * `actor`/`at` {@link ValueExpr} fields into its own value.
1048
+ */
1049
+ export declare type AuthoringOp =
1050
+ | FieldMutationOp<AuthoringFieldRef>
1051
+ | {
1052
+ type: "status.set";
1053
+ activity?: string | undefined;
1054
+ status: ActivityStatus;
1055
+ }
1056
+ | {
1057
+ type: "audit";
1058
+ target: AuthoringFieldRef;
1059
+ value: ValueExpr;
1060
+ stampFields?:
1061
+ | {
1062
+ actor?: string | undefined;
1063
+ at?: string | undefined;
1064
+ }
1065
+ | undefined;
1066
+ };
1476
1067
 
1477
- declare type AuthoringRawAction = ActionFields<AuthoringOp, GroupMembership> & {
1068
+ /** @inline */
1069
+ declare type AuthoringRawAction = ActionFields<
1070
+ AuthoringOp,
1071
+ GroupMembership,
1072
+ AuthoringEffect
1073
+ > & {
1478
1074
  roles?: string[] | undefined;
1479
1075
  status?: TerminalActivityStatus | undefined;
1480
1076
  };
1481
1077
 
1078
+ /** @inline */
1482
1079
  declare type AuthoringRawFieldEntry = FieldEntryFields<
1483
1080
  AuthoringEditable,
1484
1081
  GroupMembership
1485
1082
  >;
1486
1083
 
1084
+ /** @inline */
1085
+ declare type AuthoringRuntimeKey = "runtime";
1086
+
1087
+ /**
1088
+ * A {@link Stage} accepting authoring fields, activities, transitions, guards,
1089
+ * and role-list editability. The same terminal-stage constraints apply.
1090
+ *
1091
+ * @interface
1092
+ */
1487
1093
  export declare type AuthoringStage = StageFields<
1488
1094
  AuthoringFieldEntry,
1489
1095
  AuthoringActivity,
@@ -1492,25 +1098,33 @@ export declare type AuthoringStage = StageFields<
1492
1098
  AuthoringEditable
1493
1099
  >;
1494
1100
 
1101
+ /** A {@link StartBlock} whose omitted `kind` defaults to `interactive`. */
1495
1102
  export declare type AuthoringStartBlock = StartFields & {
1496
1103
  kind?: StartKind | undefined;
1497
1104
  };
1498
1105
 
1499
1106
  /**
1500
- * Authoring transitions may omit `when`; desugar fills the safe,
1501
- * overwhelmingly-common trigger `"$allActivitiesDone"`. "Fire unconditionally"
1502
- * stays spellable as an explicit `when: "true"`.
1107
+ * A {@link Transition} whose `when` may be omitted, defaulting to
1108
+ * `$allActivitiesDone`. Use `when: 'true'` for an unconditional route.
1503
1109
  */
1504
1110
  export declare type AuthoringTransition = TransitionFields & {
1505
1111
  when?: string | undefined;
1506
1112
  };
1507
1113
 
1508
- /** The authoring surface: stored primitives plus the define-time sugar. */
1114
+ /**
1115
+ * The authoring surface: stored primitives plus the define-time sugar. `runtime`
1116
+ * says where the generated unattended runtime hosts this workflow, overriding
1117
+ * its deployment's kind; an effect node overrides it in turn.
1118
+ *
1119
+ * @interface
1120
+ */
1509
1121
  export declare type AuthoringWorkflow = WorkflowFields<
1510
1122
  AuthoringFieldEntry,
1511
1123
  AuthoringStage,
1512
1124
  AuthoringStartBlock
1513
- >;
1125
+ > & {
1126
+ runtime?: RuntimeBlock | undefined;
1127
+ };
1514
1128
 
1515
1129
  /** The narratable answer at one rollup level: the verdict plus what it waits
1516
1130
  * on. `waitsOn` may be non-empty on a `yes` verdict (an effect settle is a
@@ -1673,37 +1287,21 @@ export declare interface ChoiceOption {
1673
1287
  value: ChoiceValue;
1674
1288
  }
1675
1289
 
1290
+ /**
1291
+ * A closed list of allowed non-null scalar values. The list must be nonempty,
1292
+ * with unique values and nonempty titles. Each value must satisfy the
1293
+ * receiving type and its validation bounds.
1294
+ *
1295
+ * Fields accept choices on `string`, `text`, `number`, `url`, `date`,
1296
+ * `dueDate`, `datetime`, and `dueDatetime`. Action parameters accept choices
1297
+ * on `string`, `number`, `url`, and `dateTime`.
1298
+ */
1676
1299
  export declare interface ChoiceOptions {
1677
1300
  list: ChoiceOption[];
1678
1301
  }
1679
1302
 
1680
1303
  export declare type ChoiceValue = string | number;
1681
1304
 
1682
- /** The action half of the mirrored claim pair: `field` names the actor-valued entry this action claims, resolved lexically, and the expansion
1683
- * adds a no-steal `!defined($fields.<field>)` filter ANDed with `roles`/`filter` plus a `field.set` ← actor op. `ops`/`status` are reserved (strictObject rejects them). */
1684
- declare type ClaimAction = {
1685
- type: "claim";
1686
- name: string;
1687
- title?: string | undefined;
1688
- description?: string | undefined;
1689
- group?: GroupMembership | undefined;
1690
- field: string | AuthoringFieldRef;
1691
- roles?: string[] | undefined;
1692
- filter?: string | undefined;
1693
- params?: ActionParam[] | undefined;
1694
- effects?: Effect[] | undefined;
1695
- };
1696
-
1697
- /** The field half of the mirrored claim pair, expanding strictly within this entry: an `actor`
1698
- * working-memory field with no `initialValue` — the paired {@link ClaimAction}'s op fills it. */
1699
- declare type ClaimField = {
1700
- type: "claim";
1701
- name: string;
1702
- title?: string | undefined;
1703
- description?: string | undefined;
1704
- group?: GroupMembership | undefined;
1705
- };
1706
-
1707
1305
  export declare interface ClassifiedPrincipal {
1708
1306
  namespace: PrincipalNamespace;
1709
1307
  /**
@@ -1744,9 +1342,22 @@ export declare function clientConfigFromResource(res: WorkflowResource):
1744
1342
  resource: WorkflowResource;
1745
1343
  };
1746
1344
 
1747
- /** The router {@link buildClientForGdr} builds total: every parsed GDR
1345
+ /** The total GDR router — every parsed GDR
1748
1346
  * resolves to a client, or the router throws. */
1749
- declare type ClientForGdr = (parsed: ParsedGdr) => WorkflowClient;
1347
+ export declare type ClientForGdr = (parsed: ParsedGdr) => WorkflowClient;
1348
+
1349
+ /** Stored-resource dereferencing for write pre-flights and host previews. */
1350
+ export declare function clientGuardDereference(
1351
+ client: Pick<WorkflowClient, "getDocument">,
1352
+ ): GuardDereference;
1353
+
1354
+ /** @internal Shared member rows for workspace adapters; not a supported consumer API. */
1355
+ export declare interface _ClientProjectMember {
1356
+ readonly id: string;
1357
+ readonly isRobot?: boolean;
1358
+ readonly roles?: unknown;
1359
+ readonly [key: string]: unknown;
1360
+ }
1750
1361
 
1751
1362
  /** Native project-user response returned by Sanity's project API. */
1752
1363
  export declare interface ClientProjectUser {
@@ -1792,7 +1403,7 @@ export declare function clientProjectUserDirectory(
1792
1403
  * `createEngine({ clock })`, and tests use `@sanity/workflow-engine-test`'s
1793
1404
  * `setNow` / `advance` (the bench wraps the same seam). It is deliberately
1794
1405
  * NOT a field on the public per-verb `*Args` — the raw `workflow.*` verbs
1795
- * accept it only through the internal {@link Clocked} seam, so prod code
1406
+ * accept it only through the {@link Clocked} composition seam, so prod code
1796
1407
  * can't trivially override engine time by accident.
1797
1408
  *
1798
1409
  * `drainEffects` and `sweepStaleClaims` read the same engine clock for
@@ -1802,19 +1413,18 @@ export declare function clientProjectUserDirectory(
1802
1413
  export declare type Clock = () => string;
1803
1414
 
1804
1415
  /**
1805
- * Internal clock-injection seam for the raw `workflow.*` verbs. NOT part
1806
- * of the public per-verb args (it is deliberately not re-exported from the
1807
- * package root) production injects a clock ONCE via
1808
- * `createEngine({ clock })`, and the test bench via its `setNow` /
1809
- * `advance`. This intersection just lets those two callers thread the
1810
- * clock into a raw verb without `clock` cluttering every documented
1811
- * `*Args` interface as if it were an everyday option.
1416
+ * Optional clock-injection field on the raw `workflow.*` verbs. It is
1417
+ * exported because those verbs expose this composition helper in their
1418
+ * public signatures, but production normally injects a clock once via
1419
+ * `createEngine({ clock })`, and the test bench controls it through
1420
+ * `setNow` / `advance`. The documented `*Args` interfaces omit `clock`
1421
+ * because it is infrastructure context, not an everyday per-call option.
1812
1422
  */
1813
- declare type Clocked<T> = T & {
1423
+ export declare type Clocked<T> = T & {
1814
1424
  clock?: Clock;
1815
1425
  };
1816
1426
 
1817
- declare interface CommitEffectOpsArgs extends DedupableOperationArgs {
1427
+ export declare interface CommitEffectOpsArgs extends DedupableOperationArgs {
1818
1428
  /** The `_key` of the pending effect being reported on. */
1819
1429
  effectKey: string;
1820
1430
  /**
@@ -1841,7 +1451,7 @@ declare interface CommitEffectOpsArgs extends DedupableOperationArgs {
1841
1451
  */
1842
1452
  ops: FieldOp[];
1843
1453
  /** Lease duration the successful commit renews the claim to — the
1844
- * drain's `effectLeaseMs`. Default `DEFAULT_EFFECT_LEASE_MS` (5 min). */
1454
+ * drain's `effects.leaseMs`. Default `DEFAULT_EFFECT_LEASE_MS` (5 min). */
1845
1455
  leaseMs?: number;
1846
1456
  }
1847
1457
 
@@ -1862,10 +1472,19 @@ export declare interface CompiledQuery {
1862
1472
  params: Record<string, string | string[]>;
1863
1473
  }
1864
1474
 
1865
- /** Deliberately carries NO engine data-model stamp: the guard doc format is the lake's forthcoming contract, not ours to grow fields on (see DATAMODEL.md). */
1866
- export declare function compileGuard(args: CompileGuardArgs): MutationGuardDoc;
1475
+ /**
1476
+ * Translate one authored guard into the temporary documents that preview its
1477
+ * eventual Content Lake enforcement.
1478
+ * Content edits target draft ids, instance updates keep the instance id, and
1479
+ * publish or unpublish targets published ids using the Lake operations those
1480
+ * lifecycle writes perform. A mixed guard emits one document per id space so
1481
+ * its action and id facets never form an unintended cross-product.
1482
+ */
1483
+ export declare function compileGuards(
1484
+ args: CompileGuardsArgs,
1485
+ ): [MutationGuardDoc, ...MutationGuardDoc[]];
1867
1486
 
1868
- declare interface CompileGuardArgs extends MutationGuardBody {
1487
+ export declare interface CompileGuardsArgs extends MutationGuardBody {
1869
1488
  id: string;
1870
1489
  }
1871
1490
 
@@ -1924,6 +1543,17 @@ export declare function computeDiffEntries<
1924
1543
  target: DeployTarget;
1925
1544
  }): Promise<DiffEntry[]>;
1926
1545
 
1546
+ /**
1547
+ * Thrown when one automatic cascade hop loses every optimistic-locking
1548
+ * attempt. An earlier verb commit may already have landed; invoke `tick`
1549
+ * after re-reading the instance to resume convergence when contention subsides.
1550
+ */
1551
+ export declare class ConcurrentCascadeError extends WorkflowError<"concurrent-cascade"> {
1552
+ readonly instanceId: string;
1553
+ readonly attempts: number;
1554
+ constructor(args: { instanceId: string; attempts: number });
1555
+ }
1556
+
1927
1557
  /** {@link ConcurrentCompleteEffectError}'s mid-dispatch sibling: a
1928
1558
  * `commitEffectOps` commit lost every optimistic-locking attempt. Nothing
1929
1559
  * was written; the report may be retried under the same idempotency key. */
@@ -1984,7 +1614,7 @@ export declare class ConcurrentEditFieldError extends WorkflowError<"concurrent-
1984
1614
 
1985
1615
  /**
1986
1616
  * Thrown when a `fireAction` commit loses the optimistic-locking race on
1987
- * all {@link CONCURRENT_COMMIT_MAX_ATTEMPTS} attempts every reload +
1617
+ * every commit attempteach reload +
1988
1618
  * `ifRevisionId` retry was beaten by another writer committing first.
1989
1619
  * Surfacing it (rather than silently overwriting) lets the caller decide
1990
1620
  * whether to retry later or report a write storm; nothing was committed
@@ -2011,7 +1641,7 @@ export declare class ConcurrentFireActionError extends WorkflowError<"concurrent
2011
1641
  * never a `_type` scan over the lake (rejected at deploy).
2012
1642
  *
2013
1643
  * There is no `{ref, args}` wrapper: parameterized reuse is a define-time
2014
- * TypeScript function producing a condition string (see the {@link groq} tag).
1644
+ * TypeScript function producing a condition string (see the {@link define.groq | groq} tag).
2015
1645
  */
2016
1646
  export declare type Condition = string;
2017
1647
 
@@ -2063,7 +1693,7 @@ export { ConditionRead };
2063
1693
  * then per stage — transitions, activities (filter, requirements, action
2064
1694
  * filters and `when` triggers), editable gates, tighten-overrides.
2065
1695
  * Editable gates resolve through the same helper the runtime projection uses
2066
- * ({@link editableFieldsInStage}: entry `editable` ANDed with the stage
1696
+ * (entry `editable` ANDed with the stage
2067
1697
  * tighten-override), so every live editable-field address exists here with
2068
1698
  * the same EFFECTIVE predicate the edit insight explains — including
2069
1699
  * override-only gates on `editable: true` entries, and workflow-scope fields
@@ -2098,7 +1728,7 @@ export declare type ConditionVarBinding = "always" | "caller" | "spawn";
2098
1728
  /**
2099
1729
  * The one-doc read a reactive adapter subscribes with to observe a content doc
2100
1730
  * under a perspective stack. It uses the same perspective semantics as
2101
- * {@link hydrateSnapshot}: draft/version content is projected onto the published
1731
+ * `hydrateSnapshot`: draft/version content is projected onto the published
2102
1732
  * id, and a doc that exists only as a draft or release version remains visible.
2103
1733
  */
2104
1734
  export declare function contentDocQuery(documentId: string): CompiledQuery;
@@ -2139,7 +1769,7 @@ export declare function contentDraftFallback(args: {
2139
1769
  * Note: this resolves a **single** release — the documented `instance.perspective`
2140
1770
  * shapes (`[release]` / `[release, "drafts"]`). The stores' per-doc reads take
2141
1771
  * one release, so a multi-release stack can't be observed through them; the
2142
- * engine's own fetch path ({@link hydrateSnapshot}) — and the SDK adapter's
1772
+ * engine's own fetch path (`hydrateSnapshot`) — and the SDK adapter's
2143
1773
  * query-store route for stacks without a `'drafts'` entry — honour the full
2144
1774
  * stack via `client.fetch({perspective})`.
2145
1775
  */
@@ -2250,15 +1880,12 @@ export declare class ContractViolationError extends WorkflowError<"contract-viol
2250
1880
  * {@link Engine.subscriptionDocumentsForInstance} (need the pinned
2251
1881
  * binding), {@link Engine.drainEffects} and
2252
1882
  * {@link Engine.verifyDeployedDefinitions} (need the construction-time
2253
- * `effectHandlers` / `missingHandler` / `loggerFactory`).
1883
+ * `effects` / `loggerFactory`).
2254
1884
  * - Namespace-only: `workflow.permissions` — pure grant helpers that need
2255
1885
  * no engine scope.
2256
1886
  *
2257
- * Effect handlers + missingHandler feed {@link Engine.drainEffects}
2258
- * (dispatch of unclaimed pending effects) and
2259
- * {@link Engine.verifyDeployedDefinitions} (the startup audit of
2260
- * deployed effect names). They don't change `fireAction` / `tick` /
2261
- * `completeEffect` — the runtime still decides when to drain and
1887
+ * The {@link EngineEffectsArgs} group changes nothing about `fireAction` /
1888
+ * `tick` / `completeEffect` the runtime still decides when to drain, and
2262
1889
  * reports outcomes via `completeEffect`.
2263
1890
  */
2264
1891
  export declare function createEngine<Client extends WorkflowClient>(
@@ -2267,8 +1894,8 @@ export declare function createEngine<Client extends WorkflowClient>(
2267
1894
 
2268
1895
  /**
2269
1896
  * The {@link EngineScopeArgs} scope pinned at construction, plus the
2270
- * engine-only extras (`effectHandlers` / `missingHandler` / `loggerFactory`
2271
- * feed `drainEffects` + `verifyDeployedDefinitions`). The `tag` partition is
1897
+ * engine-only extras (`effects` and `loggerFactory` feed `drainEffects` +
1898
+ * `verifyDeployedDefinitions`). The `tag` partition is
2272
1899
  * required and never defaulted — the engine enforces nothing, so the
2273
1900
  * partition is the only thing keeping reads and writes off the wrong
2274
1901
  * environment.
@@ -2277,18 +1904,8 @@ export declare interface CreateEngineArgs<
2277
1904
  Client extends WorkflowClient = WorkflowClient,
2278
1905
  > extends EngineScopeArgs {
2279
1906
  client: Client;
2280
- effectHandlers?: Record<string, EffectHandler<Client>>;
2281
- missingHandler?: MissingHandlerPolicy;
1907
+ effects?: EngineEffectsArgs<Client>;
2282
1908
  loggerFactory?: LoggerFactory;
2283
- /**
2284
- * Lease duration `drainEffects` stamps on each pending-effect claim.
2285
- * Past the lease the claimer is presumed dead: the entry becomes
2286
- * recoverable by another drain's takeover or by
2287
- * the standalone `sweepStaleClaims` export. Default 5 minutes — size it well above
2288
- * the slowest handler's honest runtime, since a live-but-slow dispatch
2289
- * that outlives its lease can be redispatched (see {@link EffectHandler}).
2290
- */
2291
- effectLeaseMs?: number;
2292
1909
  /**
2293
1910
  * Deterministic-time seam, pinned once for this engine and threaded
2294
1911
  * into every verb it drives — `$now`, the `now` op-source, and the
@@ -2299,6 +1916,13 @@ export declare interface CreateEngineArgs<
2299
1916
  * option.
2300
1917
  */
2301
1918
  clock?: Clock;
1919
+ /**
1920
+ * How the engine waits out a `retry` policy's backoff between attempts.
1921
+ * Pinned once beside {@link CreateEngineArgs.clock}; omit (the default) to
1922
+ * spend real time. A deterministic harness passes one that moves its clock
1923
+ * forward instead, so a paced policy runs without waiting.
1924
+ */
1925
+ sleep?: Sleeper;
2302
1926
  /**
2303
1927
  * Product-telemetry seam, pinned once for this engine and threaded into
2304
1928
  * every verb it drives. The core engine ships no metrics pipeline — it
@@ -2326,6 +1950,8 @@ export declare function createTelemetryIntake(args: {
2326
1950
  client: TelemetryIntakeClient;
2327
1951
  projectId: string;
2328
1952
  denied?: boolean;
1953
+ /** Context merged into every event at send time. These values win on key collisions. */
1954
+ context?: Record<string, unknown>;
2329
1955
  }): TelemetryIntake;
2330
1956
 
2331
1957
  /** A define-time validated `custom.<camelCaseMeaning>` value. */
@@ -2459,10 +2085,46 @@ export declare const DATA_MODEL_CHANGES: readonly [
2459
2085
  applicability: "detectable";
2460
2086
  summary: "Assignee fields may restrict newly assigned users and collective roles by role.";
2461
2087
  }>,
2088
+ Readonly<{
2089
+ id: "split-guard-id-spaces";
2090
+ introducedInModel: 9;
2091
+ minReaderModel: 9;
2092
+ documentTypes: readonly ["definition", "instance"];
2093
+ compatibility: "reader-floor";
2094
+ applicability: "detectable";
2095
+ summary: "Guards spanning edit and lifecycle id spaces emit independently retractable documents.";
2096
+ }>,
2097
+ Readonly<{
2098
+ id: "singular-assignee-lists";
2099
+ introducedInModel: 9;
2100
+ minReaderModel: 9;
2101
+ documentTypes: readonly ["definition", "instance"];
2102
+ compatibility: "reader-floor";
2103
+ applicability: "detectable";
2104
+ summary: "Singular assignee fields use member lists with at most one user and any number of roles.";
2105
+ }>,
2106
+ Readonly<{
2107
+ id: "required-content-references";
2108
+ introducedInModel: 10;
2109
+ minReaderModel: 10;
2110
+ documentTypes: readonly ["definition", "instance"];
2111
+ compatibility: "reader-floor";
2112
+ applicability: "detectable";
2113
+ summary: "Required content references must remain readable after initialization before actions or transitions advance.";
2114
+ }>,
2115
+ Readonly<{
2116
+ id: "effect-retry-policy";
2117
+ introducedInModel: 10;
2118
+ minReaderModel: 10;
2119
+ documentTypes: readonly ["definition", "instance"];
2120
+ compatibility: "reader-floor";
2121
+ applicability: "detectable";
2122
+ summary: "An effect node declares a bounded retry policy the engine enforces on every runtime.";
2123
+ }>,
2462
2124
  ];
2463
2125
 
2464
2126
  /** The maximum reader floor this writer can emit for a detectable feature. */
2465
- export declare const DATA_MODEL_MAX_READER = 8;
2127
+ export declare const DATA_MODEL_MAX_READER = 10;
2466
2128
 
2467
2129
  /**
2468
2130
  * The unconditional model-4 reader floor for every engine-owned document.
@@ -2479,12 +2141,14 @@ export declare const DATA_MODEL_MIN_READER = 4;
2479
2141
  * instances are re-stamped on every full persist, so mixed-version fleets
2480
2142
  * honestly record whichever engine last shaped a doc.
2481
2143
  *
2482
- * Bump on every declared shape change (additive included). Bumping does NOT
2483
- * by itself lock out older engines that is the document's derived
2484
- * `minReaderModel` floor. Declare every bump in `DATAMODEL.md`; the model-surface snapshot test
2485
- * fails on undeclared drift.
2144
+ * A number is assigned per release, not per change: a declared shape change
2145
+ * merged before this model has shipped joins it, and one merged after it has
2146
+ * shipped moves the number on. Bumping does NOT by itself lock out older
2147
+ * engines that is the document's derived `minReaderModel` floor. Declare
2148
+ * every change in `DATAMODEL.md`; the model-surface snapshot test fails on
2149
+ * undeclared drift.
2486
2150
  */
2487
- export declare const DATA_MODEL_VERSION = 8;
2151
+ export declare const DATA_MODEL_VERSION = 10;
2488
2152
 
2489
2153
  export declare interface DataModelChange {
2490
2154
  readonly id: string;
@@ -2561,7 +2225,7 @@ export declare interface DedupableOperationArgs extends OperationArgs {
2561
2225
  export declare const DEFAULT_CONTENT_PERSPECTIVE = "drafts";
2562
2226
 
2563
2227
  /** How long a fresh claim's lease runs unless the engine configured
2564
- * `effectLeaseMs`. */
2228
+ * `effects.leaseMs`. */
2565
2229
  export declare const DEFAULT_EFFECT_LEASE_MS: number;
2566
2230
 
2567
2231
  /** How long a recorded idempotency key dedupes retries, unless the caller
@@ -2582,6 +2246,16 @@ export declare const DEFAULT_TRANSITION_WHEN = "$allActivitiesDone";
2582
2246
  */
2583
2247
  export declare const defaultLoggerFactory: LoggerFactory;
2584
2248
 
2249
+ /**
2250
+ * What `defineWorkflow` returns: the stored definition, plus `runtime` when the
2251
+ * workflow or one of its effects declared a hosting kind. Generation and the
2252
+ * blueprint tooling read `runtime`; the deploy drops it, so it never reaches the
2253
+ * Content Lake and never affects a definition's content fingerprint.
2254
+ */
2255
+ export declare type DefinedWorkflow = WorkflowDefinition & {
2256
+ runtime?: DefinitionRuntime | undefined;
2257
+ };
2258
+
2585
2259
  export declare interface DefinitionConditionSite {
2586
2260
  /** The stage the condition applies in; absent only for author predicates. */
2587
2261
  stage?: string;
@@ -2609,7 +2283,7 @@ export declare interface DefinitionGroupSite {
2609
2283
  members: GroupMember[];
2610
2284
  }
2611
2285
 
2612
- declare interface DefinitionGuardsQueryArgs {
2286
+ export declare interface DefinitionGuardsQueryArgs {
2613
2287
  client: WorkflowClient;
2614
2288
  clientForGdr: ClientForGdr;
2615
2289
  workflowResource: WorkflowResource;
@@ -2661,6 +2335,22 @@ export declare class DefinitionNotFoundError extends WorkflowError<"definition-n
2661
2335
  constructor(args: { definition: string; version?: number });
2662
2336
  }
2663
2337
 
2338
+ /** Every literal project role a stored definition references, deduplicated in encounter order. */
2339
+ export declare function definitionRoleNames(
2340
+ definition: WorkflowDefinition,
2341
+ ): readonly string[];
2342
+
2343
+ /**
2344
+ * The hosting declarations {@link DefinedWorkflow} carries for the generator,
2345
+ * collected out of the authored tree. `kind` is present only when the workflow
2346
+ * declared one, so an absent `kind` inherits the deployment's. `effects` holds
2347
+ * one entry per effect that declared a block, keyed by effect name.
2348
+ */
2349
+ export declare interface DefinitionRuntime {
2350
+ kind?: RuntimeKind | undefined;
2351
+ effects?: Record<string, EffectRuntimeBlock> | undefined;
2352
+ }
2353
+
2664
2354
  export declare interface DefinitionsForDocumentArgs {
2665
2355
  /**
2666
2356
  * The LOADED candidate document — unlike {@link InstancesForDocumentArgs},
@@ -2785,6 +2475,7 @@ export declare function denyingGuards(args: {
2785
2475
  type?: string;
2786
2476
  };
2787
2477
  context: MutationContext;
2478
+ dereference?: GuardDereference;
2788
2479
  }): Promise<MutationGuardDoc[]>;
2789
2480
 
2790
2481
  export declare interface DeployDefinitionResult {
@@ -2842,14 +2533,13 @@ export declare interface DeployDefinitionsResult {
2842
2533
  /** A definition as fetched back from the lake. The document carries `_id` plus
2843
2534
  * the deploy-stamped envelope the authored {@link WorkflowDefinition} never
2844
2535
  * had: the assigned `version` and the content fingerprint it was minted from
2845
- * ({@link hashDefinitionContent}). A pre-fingerprint document may lack
2846
- * `contentHash` at runtime — see {@link LatestDeployed}. */
2536
+ * ({@link hashDefinitionContent}). */
2847
2537
  export declare type DeployedDefinition = WorkflowDefinition & {
2848
2538
  _id: string;
2849
2539
  tag?: string;
2850
2540
  version: number;
2851
- /** Optional: a document deployed before content-addressing has none — see
2852
- * {@link LatestDeployed}. Every version this engine deploys carries one. */
2541
+ /** Optional: a document deployed before content-addressing has none. Every
2542
+ * version this engine deploys carries one. */
2853
2543
  contentHash?: string;
2854
2544
  /** Engine data-model stamp (see {@link DATA_MODEL_VERSION}) — absent on
2855
2545
  * documents deployed before the stamp existed (model 0). */
@@ -3048,6 +2738,8 @@ export declare type DiagnosedTransition = Pick<
3048
2738
  * builds it from a real {@link WorkflowEvaluation}.
3049
2739
  */
3050
2740
  export declare interface DiagnoseInput extends DocumentStuckInput {
2741
+ /** Missing references read by unmet requirements or transition conditions; omit when not checked. */
2742
+ missingDocuments?: MissingDocument[];
3051
2743
  instance: Pick<
3052
2744
  WorkflowInstance,
3053
2745
  | "currentStage"
@@ -3064,14 +2756,15 @@ export declare interface DiagnoseInput extends DocumentStuckInput {
3064
2756
  }
3065
2757
 
3066
2758
  /** Narrow a full {@link WorkflowEvaluation} to the {@link DiagnoseInput} the
3067
- * classifier reads. */
2759
+ * classifier reads. Throws when populated missing-reference evidence lacks
2760
+ * its blocking subset. */
3068
2761
  export declare function diagnoseInputFromEvaluation(
3069
2762
  evaluation: WorkflowEvaluation,
3070
2763
  ): DiagnoseInput;
3071
2764
 
3072
2765
  /**
3073
- * Classify an instance. Terminal states win first; then the genuine stuck
3074
- * causes (nothing advances on its own or via a normal action); then `waiting`
2766
+ * Classify an instance. Terminal states win first; then effect or activity
2767
+ * faults; then missing references read by unmet conditions; then transition faults; then `waiting`
3075
2768
  * (an action is available — healthy); then `blocked` (an active activity held by
3076
2769
  * an unmet requirement — healthy, not yet actionable); else `progressing` (a
3077
2770
  * transition is already satisfied and will cascade).
@@ -3089,16 +2782,17 @@ export declare interface DiagnoseResult {
3089
2782
  }
3090
2783
 
3091
2784
  /**
3092
- * How an in-flight instance reads right now. `waiting` and `blocked` are both
3093
- * HEALTHY, not stuck: `waiting` means an active activity has an available
3094
- * action and advances when someone acts how long a workflow is "allowed" to
3095
- * wait is workflow- and team-specific, not this classifier's call — while
3096
- * `blocked` means an active activity's declared requirements aren't all met
2785
+ * How an instance reads right now. `waiting` and `blocked` are both healthy,
2786
+ * not stuck. A `waiting` result says whether the activity awaits an
2787
+ * action available to this caller (`caller`), a manual action that this caller
2788
+ * cannot currently take (`manual-action`), or a cascade-fired action
2789
+ * (`automation`). How long a workflow is "allowed" to wait is workflow- and
2790
+ * team-specific, not this classifier's call. `blocked` means an active
2791
+ * activity's declared requirements aren't all met
3097
2792
  * yet, and flips to `waiting` once they hold (typically a sibling activity
3098
- * completing, or content landing). `completed` and `aborted` carry
3099
- * `liveChildren` when spawned work is still running: a parent finishing while
3100
- * detached children run is legal — detach means detach — but a consumer
3101
- * should surface it loudly.
2793
+ * completing, or content landing). Completed and aborted results include
2794
+ * `liveChildren` while detached spawned work remains active; consumers should
2795
+ * surface it prominently.
3102
2796
  */
3103
2797
  export declare type Diagnosis =
3104
2798
  | {
@@ -3109,6 +2803,7 @@ export declare type Diagnosis =
3109
2803
  activity: string;
3110
2804
  assignees: Assignee[];
3111
2805
  actions: string[];
2806
+ waitingFor: "automation" | "caller" | "manual-action";
3112
2807
  }
3113
2808
  | {
3114
2809
  state: "blocked";
@@ -3148,7 +2843,7 @@ export declare interface DiffEntry {
3148
2843
 
3149
2844
  /**
3150
2845
  * Classifies `def` against the latest deployed version of its name via
3151
- * {@link planDefinitionDeploy} — a content change is always a new version,
2846
+ * the deploy planner — a content change is always a new version,
3152
2847
  * never an in-place update. `def` passes the same boundary parse deploy uses
3153
2848
  * ({@link parseDefinitionInput}), so diff and deploy accept and reject the
3154
2849
  * same input shape.
@@ -3223,12 +2918,10 @@ export declare type DisabledReason =
3223
2918
  }
3224
2919
  | {
3225
2920
  /**
3226
- * The activity's declared {@link Activity.requirements} aren't all satisfied
3227
- * the readiness axis. The activity is visible and the actor authorized, but
3228
- * its own preconditions don't hold yet. `unmetRequirements` carries the
3229
- * authored descriptors so a consumer can disable the affirmative control and say
3230
- * which precondition is outstanding. Distinct from `filter-failed`
3231
- * (visibility/authorization) and `mutation-guard-denied` (content-write).
2921
+ * An authored activity requirement is unmet, or a selected target of a
2922
+ * required reference field cannot be read. Use `unmetRequirements` to
2923
+ * explain what blocks the action. Required-reference descriptors use
2924
+ * `field:<name>`; they have no entry in `requirementInsights`.
3232
2925
  */
3233
2926
  kind: "requirements-unmet";
3234
2927
  unmetRequirements: RequirementDescriptor[];
@@ -3279,26 +2972,25 @@ export declare interface DisplayMetadata {
3279
2972
  export declare function displayTitle(typeKey: string | undefined): string;
3280
2973
 
3281
2974
  /** Document-value permissions. Grants ({@link Grant} in ./authorization.ts) compose most-permissive-wins. */
3282
- declare const DOCUMENT_VALUE_PERMISSIONS: readonly ["create", "read", "update"];
2975
+ export declare const DOCUMENT_VALUE_PERMISSIONS: readonly [
2976
+ "create",
2977
+ "manage",
2978
+ "read",
2979
+ "update",
2980
+ ];
3283
2981
 
3284
2982
  /**
3285
- * The guards that would deny a PROSPECTIVE lake action on a document — the
3286
- * disable-this-button pre-flight, evaluated before any concrete mutation
3287
- * exists. Advisory, like every guard verdict: the check explains and
3288
- * disables, it never enforces.
2983
+ * The guards that deny a concrete Lake mutation image. Advisory, like every
2984
+ * engine-side guard verdict: the check explains and disables, it never
2985
+ * enforces.
3289
2986
  */
3290
2987
  export declare function documentActionDenials(
3291
2988
  args: DocumentActionDenialsArgs,
3292
2989
  ): Promise<MutationGuardDoc[]>;
3293
2990
 
3294
2991
  export declare interface DocumentActionDenialsArgs {
3295
- /** The document's current value both `before` and `after` of the
3296
- * pre-flighted action (a prospective check has no concrete mutation, so
3297
- * delta predicates see "no change"). */
3298
- doc: {
3299
- _id: string;
3300
- _type: string;
3301
- } & Record<string, unknown>;
2992
+ /** The concrete Lake mutation the action will perform. */
2993
+ mutation: MutationContext;
3302
2994
  /** The datasource the document lives in. A guard applies solely within the
3303
2995
  * datasource it is registered in, so a same-id match from a foreign
3304
2996
  * datasource can never gate this action and must not flip verdicts. */
@@ -3306,15 +2998,30 @@ export declare interface DocumentActionDenialsArgs {
3306
2998
  type: string;
3307
2999
  id: string;
3308
3000
  };
3309
- action: MutationGuardAction;
3310
3001
  guards: readonly MutationGuardDoc[];
3311
3002
  /** The caller's principal id in the guarded resource's own namespace,
3312
3003
  * resolved as `identity()` in predicates. */
3313
3004
  identity?: string;
3005
+ /** Resource-local stored-document lookup for predicates using `->`. */
3006
+ dereference?: GuardDereference;
3314
3007
  }
3315
3008
 
3316
- /** Compile-time mirror of {@link isDocumentEnvelopeKey}: the keys the
3317
- * boundary strips rather than rejects. */
3009
+ /**
3010
+ * Completed evidence for a document absent from the snapshot. `deleted` confirms
3011
+ * absence across versions; `outside-perspective` identifies an existing representation.
3012
+ * `unreadable` covers denied access and unsuccessful availability checks.
3013
+ */
3014
+ export declare type DocumentAvailability =
3015
+ | "deleted"
3016
+ | "unreadable"
3017
+ | "outside-perspective";
3018
+
3019
+ /** Supplies completed availability evidence for references absent from an evaluation snapshot. */
3020
+ export declare type DocumentAvailabilityReader = (
3021
+ documents: readonly MissingDocument[],
3022
+ ) => Promise<ReadonlyMap<string, DocumentAvailability>>;
3023
+
3024
+ /** @inline */
3318
3025
  declare type DocumentEnvelopeKey =
3319
3026
  | `_${string}`
3320
3027
  | "tag"
@@ -3337,8 +3044,8 @@ export declare function documentPrefilter(
3337
3044
 
3338
3045
  /**
3339
3046
  * Classify an instance from its document alone — no evaluation, no reads, no
3340
- * actor. The transition-level causes need GROQ `when` results, so only
3341
- * {@link diagnoseInstance} reaches those.
3047
+ * actor. Document absence and transition-level causes require an evaluation,
3048
+ * so only {@link diagnoseInstance} reaches those.
3342
3049
  *
3343
3050
  * Sound but incomplete, and a consumer must present it that way: `undefined`
3344
3051
  * means "no cause this classifier can see", never "healthy". Flag an instance on
@@ -3381,10 +3088,13 @@ export declare interface DrainEffectsResult {
3381
3088
  failed: PendingEffect[];
3382
3089
  skipped: PendingEffect[];
3383
3090
  /**
3384
- * Entries this drainer dispatched whose completion lost to another party
3385
- * (a lease-expiry takeover finishing first, or a manual recovery). The
3386
- * handler's side effect ran here too the at-least-once overlap the
3387
- * {@link EffectHandler} contract tells handlers to tolerate.
3091
+ * Entries this drainer dispatched without settling. Either another party
3092
+ * settled the entry first (a lease-expiry takeover, a manual recovery, or a
3093
+ * completion landing while a `retry` run waited out a backoff), or a `retry`
3094
+ * run stopped because the claim could no longer be held, which leaves the
3095
+ * entry pending for a later drain. The handler's side effect ran here too:
3096
+ * the at-least-once overlap the {@link EffectHandler} contract tells
3097
+ * handlers to tolerate.
3388
3098
  */
3389
3099
  lost: PendingEffect[];
3390
3100
  }
@@ -3442,7 +3152,7 @@ export declare function driverKind(actor: Actor): DriverKind;
3442
3152
  * to decide who-may-edit. ADVISORY like every engine gate — it disables the
3443
3153
  * inline field and explains; a {@link Guard} declares the intended write-lock.
3444
3154
  */
3445
- export declare type Editable = v.InferOutput<typeof StoredEditableSchema>;
3155
+ export declare type Editable = true | string;
3446
3156
 
3447
3157
  /**
3448
3158
  * One declared-editable field in the current scope, projected for an actor: its
@@ -3576,37 +3286,34 @@ export declare interface EditFieldTarget {
3576
3286
  export declare type EditMode = "set" | "append" | "unset";
3577
3287
 
3578
3288
  /**
3579
- * A registered effect: `name` is its only identity (unique per definition,
3580
- * read downstream as `$effects.<name>`) the host app registers a handler
3581
- * against it 1:1, and the stored definition never references code.
3582
- * `bindings` are GROQ reads over the rendered scope, resolved to concrete
3583
- * JSON at queue time; `input` is static config passed through verbatim.
3584
- * `outputs` (typed {@link FieldShape}s) is a STRICT allowlist: at completion
3585
- * an undeclared output key, or a value that doesn't fit its shape, fails the
3586
- * completion and nothing is stored. Omitting `outputs` is an EMPTY allowlist,
3587
- * so ANY returned output is rejected and fails the completion — the bound is
3588
- * universal, not opt-in.
3289
+ * External work queued for the handler registered under `name`. Names are
3290
+ * unique within a definition; completed outputs are read as `$effects['<name>']`.
3291
+ *
3292
+ * `bindings` resolves GROQ expressions against the action's rendered scope
3293
+ * when the effect is queued. The handler receives one parameter bag combining
3294
+ * those values with static `input`. An `input` key overrides a same-named
3295
+ * binding, including when its value is null.
3296
+ *
3297
+ * `outputs` declares the allowed result keys and their {@link FieldShape}s.
3298
+ * An undeclared key or invalid value rejects the completion without storing
3299
+ * it. Omitting `outputs` allows no output keys.
3300
+ *
3301
+ * `retry` ({@link EffectRetry}) bounds how many times a failing handler is
3302
+ * attempted. Omitting it completes the effect as failed on the first failure.
3303
+ *
3304
+ * @interface
3589
3305
  */
3590
- export declare type Effect = v.InferOutput<typeof EffectSchema>;
3306
+ export declare type Effect = EffectFields<EffectRetry>;
3591
3307
 
3592
3308
  /** Total commits one dispatch may make — the runaway-handler bound: without
3593
3309
  * it, a looping reporter renews its own lease and appends history forever.
3594
3310
  * 2× the ceiling of 1%-granularity progress reporting. */
3595
- export declare const EFFECT_COMMIT_DISPATCH_CAP = 200;
3596
-
3597
- /** Pending mid-dispatch commits one dispatch may hold before `commitOps` /
3598
- * `setProgress` throws synchronously. An awaiting handler never reaches it
3599
- * (its queue depth stays ≤ 1). */
3600
- export declare const EFFECT_COMMIT_QUEUE_DEPTH = 32;
3601
-
3602
- /**
3603
- * Every terminal state an effect run can record. `done` and `failed` are
3604
- * reported through completion ({@link EffectCompletionStatus}); `cancelled`
3605
- * is engine-stamped only — an abort cancelling the entry before dispatch.
3606
- * A cancellation is not a failure: anything counting failures (dashboards,
3607
- * retry tooling) must not count aborted-away effects among them.
3608
- */
3609
- declare const EFFECT_RUN_STATUSES: readonly ["done", "failed", "cancelled"];
3311
+ export declare const EFFECT_COMMIT_DISPATCH_CAP = 200;
3312
+
3313
+ /** Pending mid-dispatch commits one dispatch may hold before `commitOps` /
3314
+ * `setProgress` throws synchronously. An awaiting handler never reaches it
3315
+ * (its queue depth stays ≤ 1). */
3316
+ export declare const EFFECT_COMMIT_QUEUE_DEPTH = 32;
3610
3317
 
3611
3318
  /**
3612
3319
  * A `ctx.commitOps` / `ctx.setProgress` call hit one of the dispatch's
@@ -3634,6 +3341,17 @@ export declare type EffectCompletionStatus = Exclude<
3634
3341
  "cancelled"
3635
3342
  >;
3636
3343
 
3344
+ /** @inline */
3345
+ declare type EffectFields<TRetry> = {
3346
+ name: string;
3347
+ title?: string | undefined;
3348
+ description?: string | undefined;
3349
+ bindings?: Record<string, string> | undefined;
3350
+ input?: Record<string, unknown> | undefined;
3351
+ outputs?: FieldShape[] | undefined;
3352
+ retry?: TRetry | undefined;
3353
+ };
3354
+
3637
3355
  /**
3638
3356
  * External effect handler — invoked at drain time with resolved `params` and
3639
3357
  * a context. Returning `outputs` records them on the run's `effectHistory`
@@ -3641,15 +3359,29 @@ export declare type EffectCompletionStatus = Exclude<
3641
3359
  * applies the state half of the effect in the completion commit (`field.*`
3642
3360
  * only, never `status.set`) — every returned op must explicitly set
3643
3361
  * `target.scope`, since completion ops have no authoring location to infer
3644
- * one from. Throwing marks the effect failed, with no `ops`.
3362
+ * one from. Throwing fails the attempt, with no `ops`. Without a
3363
+ * {@link EffectRetry} policy on the node, or once one has spent its attempts
3364
+ * or closed its window, that failure settles the effect as failed. A policy
3365
+ * with attempts left inside its window dispatches again instead, unless the
3366
+ * drain finds between two attempts that it no longer holds the claim: then it
3367
+ * stops without settling and reports the entry as `lost`. That check happens
3368
+ * between attempts only. The completion itself stays first-writer-wins, so a
3369
+ * dispatch that runs to its end still reports its outcome and settles the
3370
+ * entry if it gets there first.
3645
3371
  *
3646
3372
  * Delivery is at-least-once: a handler MAY run more than once for the same
3647
- * effect (a dispatch dying after its side effect but before commit, or a
3648
- * lease expiring mid-dispatch and being taken over). Completion is
3649
- * first-writer-wins the losing run's completion is reported as `lost`.
3650
- * Write handlers to tolerate this: check `effectHistory[]` for a row keyed
3651
- * by `ctx.effectKey` before irreversible work, and derive external
3652
- * identifiers from `ctx.effectKey` so the receiving system can dedupe.
3373
+ * effect. Three causes. A dispatch can die after its side effect but before
3374
+ * commit. A lease can expire mid-dispatch and be taken over. And every
3375
+ * admitted attempt of a `retry` policy invokes the handler again. Completion
3376
+ * is first-writer-wins, and the losing run's completion is reported as `lost`.
3377
+ *
3378
+ * Write handlers to tolerate repetition. Derive external identifiers from
3379
+ * `ctx.effectKey` so the receiving system can dedupe: the key is stable across
3380
+ * every repeat, including all attempts of one policy run. Checking
3381
+ * `effectHistory[]` for a row keyed by `ctx.effectKey` before irreversible
3382
+ * work catches a repeat of an already-completed run, but never a retry
3383
+ * attempt, because a policy writes one history row when the whole run ends and
3384
+ * nothing records the attempt that just failed.
3653
3385
  *
3654
3386
  * The `bivarianceHack` indirection keeps this readable from the non-generic
3655
3387
  * `Engine` surface; only the typed drain invokes handlers.
@@ -3666,7 +3398,7 @@ export declare type EffectHandler<
3666
3398
  } | void>;
3667
3399
  }["bivarianceHack"];
3668
3400
 
3669
- declare type EffectHandlerContext<Client extends WorkflowClient> = {
3401
+ export declare type EffectHandlerContext<Client extends WorkflowClient> = {
3670
3402
  /** A concrete sibling of the `createEngine` client, bound to the workflow resource with the
3671
3403
  * same credentials; untagged handler requests carry the `workflow.effect` tag by default. */
3672
3404
  client: Client;
@@ -3784,45 +3516,94 @@ export declare function effectOutputsMap(
3784
3516
  instance: Pick<WorkflowInstance, "effectHistory">,
3785
3517
  ): Record<string, unknown>;
3786
3518
 
3787
- export declare type EffectRunStatus = (typeof EFFECT_RUN_STATUSES)[number];
3519
+ /**
3520
+ * A bounded retry policy for one effect. Both bounds govern one drain's run of
3521
+ * the policy, not the effect's lifetime: a drainer that dies mid-run leaves the
3522
+ * entry for the next drain, which starts a fresh run with the full budget, so
3523
+ * an effect can see more handler calls in total than `attempts`.
3524
+ *
3525
+ * `attempts` is the total number of attempts in a run, the first included, so
3526
+ * `1` means "never retry".
3527
+ *
3528
+ * `expiryMs` and the backoff a policy accumulates are each capped at 366 days
3529
+ * (`31_622_400_000` ms), inclusive. Deploy refuses a policy declaring more,
3530
+ * and one whose accumulated backoff reaches its own `expiryMs` before its
3531
+ * `attempts` are spent. Those checks weigh the declared waits alone. At
3532
+ * runtime every elapsed millisecond counts against `expiryMs`, handler time
3533
+ * included, so a slow handler can leave attempts unused. `backoff` paces
3534
+ * them; omitting it retries with no wait. Every duration is a whole number of
3535
+ * milliseconds above zero, and `attempts` a whole count above zero; deploy
3536
+ * rejects anything else.
3537
+ *
3538
+ * `expiryMs` decides whether a further attempt may start, measured from the
3539
+ * moment this run dispatched its first attempt. The window closes
3540
+ * on reaching it, so an attempt is admitted only while less than `expiryMs`
3541
+ * has elapsed. It is not a handler timeout. An attempt already running is
3542
+ * never interrupted, so a run can finish after the window, and a success then
3543
+ * still counts. Omitting it leaves `attempts` as the only bound.
3544
+ *
3545
+ * A policy that runs out of attempts, or that `expiryMs` stops, completes the
3546
+ * effect as failed, and `$effectStatus['<name>'] == 'failed'` routes the
3547
+ * instance. A successful attempt completes it as done, whichever attempt
3548
+ * succeeded. An effect with no `retry` completes as failed on its handler's
3549
+ * first failure.
3550
+ */
3551
+ export declare type EffectRetry = EffectRetryFields & {
3552
+ kind: EffectRetryKind;
3553
+ };
3788
3554
 
3789
- declare const EffectSchema: v.StrictObjectSchema<
3790
- {
3791
- readonly name: v.SchemaWithPipe<
3792
- readonly [
3793
- v.StringSchema<undefined>,
3794
- v.MinLengthAction<string, 1, "must be a non-empty string">,
3795
- ]
3796
- >;
3797
- readonly title: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
3798
- readonly description: v.OptionalSchema<
3799
- v.StringSchema<undefined>,
3800
- undefined
3801
- >;
3802
- readonly bindings: v.OptionalSchema<
3803
- v.RecordSchema<
3804
- v.StringSchema<undefined>,
3805
- v.SchemaWithPipe<
3806
- readonly [
3807
- v.StringSchema<undefined>,
3808
- v.MinLengthAction<string, 1, "must be a non-empty string">,
3809
- ]
3810
- >,
3811
- undefined
3812
- >,
3813
- undefined
3814
- >;
3815
- readonly input: v.OptionalSchema<
3816
- v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>,
3817
- undefined
3818
- >;
3819
- readonly outputs: v.OptionalSchema<
3820
- v.ArraySchema<v.GenericSchema<FieldShape>, undefined>,
3821
- undefined
3822
- >;
3823
- },
3824
- undefined
3825
- >;
3555
+ /**
3556
+ * How long the engine waits between two attempts. `delayMs` is that wait in
3557
+ * milliseconds: `'fixed'` waits it every time, `'exponential'` doubles it per
3558
+ * attempt already made (`delayMs`, then `2 × delayMs`, then `4 × delayMs`).
3559
+ */
3560
+ export declare type EffectRetryBackoff = {
3561
+ kind: "fixed" | "exponential";
3562
+ delayMs: number;
3563
+ };
3564
+
3565
+ /** @inline */
3566
+ declare type EffectRetryFields = {
3567
+ attempts: number;
3568
+ backoff?: EffectRetryBackoff | undefined;
3569
+ expiryMs?: number | undefined;
3570
+ };
3571
+
3572
+ /**
3573
+ * Who runs a retry policy. `'engine'` is the only member: the engine loops
3574
+ * inside the `drainEffects` call that picked the effect up, holding the claim
3575
+ * across the waits.
3576
+ */
3577
+ export declare type EffectRetryKind = "engine";
3578
+
3579
+ /**
3580
+ * Every terminal state an effect run can record. `done` and `failed` are
3581
+ * reported through completion ({@link EffectCompletionStatus}); `cancelled`
3582
+ * is engine-stamped only — an abort cancelling the entry before dispatch.
3583
+ * A cancellation is not a failure: anything counting failures (dashboards,
3584
+ * retry tooling) must not count aborted-away effects among them.
3585
+ */
3586
+ export declare type EffectRunStatus = "done" | "failed" | "cancelled";
3587
+
3588
+ /**
3589
+ * The `runtime` block on an effect node, overriding its workflow's kind.
3590
+ * `timeout` is seconds and `memory` megabytes of the function that runs this
3591
+ * handler, and an effect declaring either gets its own drain function instead of
3592
+ * sharing the deployment's. Both are the function budget, so both are accepted
3593
+ * only under `'function'`.
3594
+ */
3595
+ export declare type EffectRuntimeBlock =
3596
+ | {
3597
+ kind: "function";
3598
+ timeout?: number | undefined;
3599
+ memory?: number | undefined;
3600
+ }
3601
+ | {
3602
+ kind: "durableFunction";
3603
+ }
3604
+ | {
3605
+ kind: "selfHosted";
3606
+ };
3826
3607
 
3827
3608
  /** The `effectHistory` outcome {@link EffectNotFoundError} reports when the
3828
3609
  * missing key belongs to a settled run. `detail` is the row's recorded
@@ -3833,6 +3614,21 @@ export declare interface EffectSettledInfo {
3833
3614
  detail?: string;
3834
3615
  }
3835
3616
 
3617
+ /** One declared effect plus a structural location string identifying where it
3618
+ * sits in the definition (for diagnostics). */
3619
+ export declare interface EffectSite {
3620
+ effect: Effect;
3621
+ location: string;
3622
+ }
3623
+
3624
+ /**
3625
+ * Every effect a definition declares, with its location — the single source of
3626
+ * "where effects live": action `effects[]` (actions are the only payload
3627
+ * carriers). Effect names are unique per definition, so consumers can key by
3628
+ * `site.effect.name` cleanly.
3629
+ */
3630
+ export declare function effectSites(def: WorkflowDefinition): EffectSite[];
3631
+
3836
3632
  export declare interface Engine {
3837
3633
  /** Engine-scoped bindings — exposed for the few advanced consumers
3838
3634
  * (e.g. test bench, drain workers) that need them; the verbs already
@@ -3840,8 +3636,7 @@ export declare interface Engine {
3840
3636
  readonly client: WorkflowClient;
3841
3637
  readonly tag: string;
3842
3638
  readonly workflowResource: WorkflowResource;
3843
- readonly effectHandlers: Readonly<Record<string, EffectHandler>>;
3844
- readonly missingHandler: MissingHandlerPolicy;
3639
+ readonly effects: ResolvedEngineEffects;
3845
3640
  readonly logger: LoggerFactory;
3846
3641
  /** The resolved telemetry logger ({@link noopTelemetry} unless injected) —
3847
3642
  * exposed so adapters built on the engine log through the same seam. */
@@ -3850,6 +3645,9 @@ export declare interface Engine {
3850
3645
  resolveActor: (
3851
3646
  args: ResolveClientActorArgs,
3852
3647
  ) => Promise<ActorResolution<ClientProjectUser>>;
3648
+ /** Validates and stores immutable definition versions. Content matching the
3649
+ * latest deployed version's fingerprint keeps that version; otherwise,
3650
+ * deployment creates the next version. Batch dependencies deploy children first. */
3853
3651
  deployDefinitions: <T extends WorkflowDefinitionInput<T>>(
3854
3652
  args: DeployDefinitionsArgs<T>,
3855
3653
  ) => Promise<DeployDefinitionsResult>;
@@ -3858,15 +3656,25 @@ export declare interface Engine {
3858
3656
  * starts without complaint. `instanceId` is the idempotency key: reusing
3859
3657
  * it for the same start resumes; a different start throws. */
3860
3658
  startInstance: (args: StartInstanceArgs) => Promise<OperationResult>;
3659
+ /** Commits a caller-fired action and runs the resulting cascade. Actions
3660
+ * declaring `when` cannot be fired through this method. Dispatch queued
3661
+ * effects separately with {@link Engine.drainEffects}. */
3861
3662
  fireAction: (args: FireActionArgs) => Promise<OperationResult>;
3862
3663
  /** Edit a declared-editable field directly (the generic edit seam):
3863
3664
  * reassign / reschedule / claim-by-hand / append-to-log, then cascade. */
3864
3665
  editField: (args: EditFieldArgs) => Promise<OperationResult>;
3666
+ /** Records an effect result, applies its completion field operations, and
3667
+ * runs the resulting cascade. Use {@link Engine.drainEffects} to invoke
3668
+ * registered handlers. */
3865
3669
  completeEffect: (args: CompleteEffectArgs) => Promise<OperationResult>;
3866
3670
  /** Commit mid-dispatch field state from a running effect handler — the
3867
3671
  * verb behind `ctx.commitOps`. Gated on the dispatch's exact claim token;
3868
3672
  * a successful commit renews the claim's lease. */
3869
3673
  commitEffectOps: (args: CommitEffectOpsArgs) => Promise<OperationResult>;
3674
+ /** Reevaluates an instance and commits enabled triggers and transitions
3675
+ * until progression settles. A successful call reports `changed: false`
3676
+ * when the instance remains unchanged. It does not run effect handlers;
3677
+ * dispatch queued work with {@link Engine.drainEffects}. */
3870
3678
  tick: (args: OperationArgs) => Promise<OperationResult>;
3871
3679
  /** Project the instance from an actor's perspective — per-action verdicts
3872
3680
  * with structured disabled reasons. Pure read. */
@@ -3881,8 +3689,9 @@ export declare interface Engine {
3881
3689
  setStage: (args: SetStageArgs) => Promise<OperationResult>;
3882
3690
  /** Admin override — hard-stop an in-flight instance where it stands. */
3883
3691
  abortInstance: (args: AbortInstanceArgs) => Promise<OperationResult>;
3884
- /** Admin override — reset a failed/terminal activity in the current stage
3885
- * back to `active` (re-run) or `skipped` (bypass), then cascade. */
3692
+ /** Changes a terminal activity in the current stage to `active` or `skipped`,
3693
+ * then continues the cascade. Already-fired triggers do not fire again
3694
+ * during the same stage visit. */
3886
3695
  resetActivity: (args: ResetActivityArgs) => Promise<OperationResult>;
3887
3696
  /** Admin override — remove a deployed definition (instances are only ever aborted, never deleted). */
3888
3697
  deleteDefinition: (
@@ -3979,13 +3788,13 @@ export declare interface Engine {
3979
3788
  drainEffects: (args: DrainEffectsArgs) => Promise<DrainEffectsResult>;
3980
3789
  /**
3981
3790
  * Inspect every deployed definition in the engine's tag and apply
3982
- * the configured missingHandler policy at `phase: "deploy"` for any
3791
+ * the configured `effects.missingHandler` policy at `phase: "deploy"` for any
3983
3792
  * effect name without a registered handler. Catches "definition
3984
3793
  * shipped, handler removed" misconfigurations at startup instead of
3985
3794
  * three days later when the effect fires.
3986
3795
  *
3987
3796
  * Returns the list of (definitionId, name, locations) tuples it saw.
3988
- * Throws if missingHandler resolved as "fail" for any of them.
3797
+ * Throws if `effects.missingHandler` resolved as "fail" for any of them.
3989
3798
  */
3990
3799
  verifyDeployedDefinitions: () => Promise<VerifyDeployedDefinitionsResult>;
3991
3800
  }
@@ -4004,6 +3813,31 @@ export declare interface Engine {
4004
3813
  */
4005
3814
  export declare const ENGINE_API_VERSION = "2026-04-29";
4006
3815
 
3816
+ /**
3817
+ * Everything this engine needs to run pending effects, in one group.
3818
+ * {@link Engine.drainEffects} dispatches through `handlers` under a
3819
+ * `leaseMs` claim, and both the drain and
3820
+ * {@link Engine.verifyDeployedDefinitions} apply `missingHandler` to an effect
3821
+ * name no handler covers.
3822
+ */
3823
+ export declare interface EngineEffectsArgs<
3824
+ Client extends WorkflowClient = WorkflowClient,
3825
+ > {
3826
+ /** Effect handlers keyed by the effect name the definition queues. */
3827
+ handlers?: Record<string, EffectHandler<Client>>;
3828
+ /**
3829
+ * Lease duration `drainEffects` stamps on each pending-effect claim.
3830
+ * Past the lease the claimer is presumed dead: the entry becomes
3831
+ * recoverable by another drain's takeover or by
3832
+ * the standalone `sweepStaleClaims` export. Default 5 minutes — size it well above
3833
+ * the slowest handler's honest runtime, since a live-but-slow dispatch
3834
+ * that outlives its lease can be redispatched (see {@link EffectHandler}).
3835
+ */
3836
+ leaseMs?: number;
3837
+ /** What to do with an effect name `handlers` doesn't cover. Default `fail`. */
3838
+ missingHandler?: MissingHandlerPolicy;
3839
+ }
3840
+
4007
3841
  export declare interface EngineLogger {
4008
3842
  info: (message: string, extra?: Record<string, unknown>) => void;
4009
3843
  warn: (message: string, extra?: Record<string, unknown>) => void;
@@ -4066,7 +3900,7 @@ export declare interface EngineScopeArgs {
4066
3900
  /**
4067
3901
  * Pull the {@link GlobalDocumentReference} values out of `doc.ref` /
4068
3902
  * `subject` / `doc.refs` (content) field entries. Content only — release
4069
- * field entries come from {@link entryReleaseRefs}, so guard discovery (which
3903
+ * field entries come from the shared release-ref projection, so guard discovery (which
4070
3904
  * reads this via `collectEntryDocUris`) stays scoped to content docs.
4071
3905
  */
4072
3906
  export declare function entryDocRefs(
@@ -4098,12 +3932,16 @@ export declare interface EvaluateArgs {
4098
3932
  }
4099
3933
 
4100
3934
  /**
4101
- * The pure projection at the heart of {@link evaluateInstance}: given an
4102
- * instance, its definition, the resolved actor/grants, and a snapshot,
4103
- * compute "what can this actor do right now, and why not the rest." No
4104
- * I/O feed it a fresh snapshot (e.g. rebuilt from a live store on
4105
- * change) for reactive re-evaluation. Best-effort by design: verdicts are
4106
- * advisory, not enforcement.
3935
+ * Evaluates an
3936
+ * instance, its definition, resolved actor/grants, and a snapshot to
3937
+ * report available actions and their blocking conditions. The
3938
+ * supplied snapshot is never refetched; guards using `->` may call the
3939
+ * supplied {@link EvaluateFromSnapshotArgs.guardDereference} resolver. An optional
3940
+ * {@link EvaluateFromSnapshotArgs.documentAvailability} reader supplies completed
3941
+ * evidence for missing references without replacing held content.
3942
+ * Feed it a fresh snapshot (e.g. rebuilt from a live store on change) for
3943
+ * reactive re-evaluation. Best-effort by design: verdicts are advisory,
3944
+ * not enforcement.
4107
3945
  */
4108
3946
  export declare function evaluateFromSnapshot(
4109
3947
  args: EvaluateFromSnapshotArgs,
@@ -4134,11 +3972,14 @@ export declare interface EvaluateFromSnapshotArgs {
4134
3972
  attributes?: UserAttributes;
4135
3973
  /**
4136
3974
  * The in-memory snapshot to evaluate against. The caller assembles it
4137
- * from whatever source — a fetch (see {@link evaluateInstance}) or a
4138
- * live store. The `_id` of every doc must be in GDR-URI form, as
4139
- * {@link buildSnapshot} produces.
3975
+ * from whatever source — a fetch-backed evaluation or a
3976
+ * live store. Every doc's `_id` must be in GDR-URI form, and `knownIds`
3977
+ * must contain exactly those IDs for missing-reference diagnostics.
3978
+ * Use {@link buildSnapshot} to construct both consistently.
4140
3979
  */
4141
3980
  snapshot: HydratedSnapshot;
3981
+ /** Resolve availability outside the snapshot's perspective. Without a reader, absence is reported without claiming deletion. */
3982
+ documentAvailability?: DocumentAvailabilityReader;
4142
3983
  /**
4143
3984
  * The `$now` reading every condition in this projection shares. Omit to
4144
3985
  * use {@link wallClock}; a reactive consumer (or the bench) passes its
@@ -4151,9 +3992,14 @@ export declare interface EvaluateFromSnapshotArgs {
4151
3992
  * doc, so a guard that matches the instance and denies that write disables
4152
3993
  * every action with `mutation-guard-denied`. Omit to skip the gate in this
4153
3994
  * projection — the engine's verb paths load live guards and re-check at
4154
- * commit time ({@link evaluateInstance} fetches them itself).
3995
+ * commit time (the runtime evaluation path fetches them itself).
4155
3996
  */
4156
3997
  guards?: readonly MutationGuardDoc[];
3998
+ /**
3999
+ * Stored-resource lookup for guard predicates using `->`. Omit when no
4000
+ * guard can dereference; missing lookups resolve `null` and deny fail-closed.
4001
+ */
4002
+ guardDereference?: GuardDereference;
4157
4003
  /**
4158
4004
  * Per-FOREIGN-subject-resource access — the actor's ACL grants PLUS the
4159
4005
  * actor's principal id in that resource's own namespace — keyed by
@@ -4161,20 +4007,22 @@ export declare interface EvaluateFromSnapshotArgs {
4161
4007
  * effects-bearing actions ({@link SubjectPermissionDenial}). A resource
4162
4008
  * appears only when both halves resolved; omit it (or the whole map) to
4163
4009
  * skip that resource's forecast (degrade open — the subject's lake still
4164
- * enforces). {@link evaluateInstance} resolves this through each
4165
- * resource's own client via {@link subjectResourceGrants}.
4010
+ * enforces). The runtime evaluation path resolves this through each
4011
+ * resource's own client.
4166
4012
  */
4167
4013
  resourceGrants?: ReadonlyMap<string, SubjectResourceAccess>;
4168
4014
  }
4169
4015
 
4170
4016
  /**
4171
4017
  * Evaluate a guard predicate against a mutation. Returns `true` only when the
4172
- * predicate is strictly `true` (ALLOW). Empty predicate denies. Fail-closed:
4173
- * any thrown error or non-`true` result denies.
4018
+ * predicate is strictly `true` (ALLOW). Empty predicates, parse failures, and
4019
+ * non-`true` results deny. A supplied dereference resolver's failure propagates
4020
+ * so infrastructure errors cannot masquerade as guard verdicts.
4174
4021
  */
4175
4022
  export declare function evaluateMutationGuard(args: {
4176
4023
  guard: MutationGuardDoc;
4177
4024
  context: MutationContext;
4025
+ dereference?: GuardDereference;
4178
4026
  }): Promise<boolean>;
4179
4027
 
4180
4028
  /** Args for `evaluateStart` — the pre-flight read of `startInstance`'s gates
@@ -4297,14 +4145,14 @@ export declare type ExecutorClassification =
4297
4145
  * alias isn't bound: the check that stops a portable definition from deploying
4298
4146
  * against the wrong (or no) resource.
4299
4147
  *
4300
- * Runs at deploy (inside {@link planDefinitionDeploy}), BEFORE the content
4148
+ * Runs during deploy planning, BEFORE the content
4301
4149
  * fingerprint, so a deployed definition never carries a logical alias. The
4302
4150
  * stored references are physical, and a rebind (same source, a different alias
4303
4151
  * map) surfaces as changed content — a new version, never a silent shift in what
4304
4152
  * the workflow reads. A no-op when the definition references no aliases.
4305
4153
  *
4306
- * Rewrites string VALUES only (via the shared {@link mapJsonStrings} deep-walk),
4307
- * skipping the prose fields in {@link PROSE_KEYS}. A reference that stands alone
4154
+ * Rewrites string VALUES only through a shared deep walk, skipping known prose
4155
+ * fields. A reference that stands alone
4308
4156
  * (the whole value is `@<alias>:<id>`, e.g. a literal `doc.ref`) must expand to a
4309
4157
  * well-formed GDR — a malformed one (`@content:a:b`, an empty id) is rejected
4310
4158
  * here rather than failing when an instance later reads it.
@@ -4356,11 +4204,7 @@ export declare function extractDocumentId(gdrUriString: string): string;
4356
4204
  /** `resourcePath` is caller-supplied so this works for both project ACLs and a dedicated workflow-collaboration resource. */
4357
4205
  declare function fetchGrants(args: {
4358
4206
  client: {
4359
- request: <T>(opts: {
4360
- url: string;
4361
- signal?: AbortSignal;
4362
- tag?: string;
4363
- }) => Promise<T>;
4207
+ request: NonNullable<WorkflowClient["request"]>;
4364
4208
  };
4365
4209
  resourcePath: string;
4366
4210
  signal?: AbortSignal;
@@ -4449,13 +4293,6 @@ export declare const FIELD_KIND_DISPLAY: {
4449
4293
  };
4450
4294
  };
4451
4295
 
4452
- /**
4453
- * The three field scopes a field entry can live in. Also the
4454
- * group-declaration levels: a `groups` array lives at exactly these three
4455
- * nodes, so `DefinitionGroupSite.level` reuses this vocabulary.
4456
- */
4457
- declare const FIELD_SCOPES: readonly ["workflow", "stage", "activity"];
4458
-
4459
4296
  /**
4460
4297
  * The kinds a VALUE can take — scalars aligned to Sanity's names, the
4461
4298
  * reference kinds, the actor/assignee identities, and the two compositional
@@ -4490,8 +4327,7 @@ declare const FIELD_VALUE_KINDS: readonly [
4490
4327
  "array",
4491
4328
  ];
4492
4329
 
4493
- /** Type-mirror of {@link fieldBase}, parameterised over the `editable` and
4494
- * `group` grammars (stored membership is the canonical list form). */
4330
+ /** @inline */
4495
4331
  declare type FieldBase<TEditable, TGroup> = {
4496
4332
  name: string;
4497
4333
  title?: string | undefined;
@@ -4509,11 +4345,33 @@ export declare interface FieldDescription {
4509
4345
  proposals: InsightPhrase[];
4510
4346
  }
4511
4347
 
4512
- /** One declared field entry as authored and stored: name, value kind, and its scope's sourcing and editability. */
4348
+ /**
4349
+ * A field declaration whose location determines its scope and lifetime.
4350
+ * Workflow fields initialize at start; stage and activity fields initialize
4351
+ * on each stage visit. {@link FieldSource} controls initialization;
4352
+ * {@link Editable} controls direct edits independently.
4353
+ *
4354
+ * `required: true` is valid only on workflow-scope fields with an `input`
4355
+ * source. It requires a non-null value at start or spawn. On `subject`,
4356
+ * `doc.ref`, and `doc.refs`, selected targets must also remain readable in the
4357
+ * workflow perspective after initialization. Missing targets block normal
4358
+ * actions, triggered actions, and transitions. Abort and permitted field edits remain available.
4359
+ * `subject` is also
4360
+ * workflow-scope-only, with at most one subject per definition. Each scope
4361
+ * may declare at most one `dueDate` or `dueDatetime` field, always top-level.
4362
+ *
4363
+ * `types` is a nonempty list of accepted document types on `subject`,
4364
+ * `doc.ref`, or `doc.refs`; omit it to accept any document type. `roles`
4365
+ * constrains assignment eligibility only on `assignee` and `assignees`.
4366
+ * {@link FieldShape}, {@link ChoiceOptions}, and {@link ScalarValidation}
4367
+ * define the nested-shape and scalar constraints. Authoring conveniences are
4368
+ * accepted by {@link AuthoringFieldEntry}.
4369
+ *
4370
+ * @interface
4371
+ */
4513
4372
  export declare type FieldEntry = FieldEntryFields<Editable, string[]>;
4514
4373
 
4515
- /** Type-mirror of {@link fieldEntryFields}: a raw field entry of the given
4516
- * editability and group-membership grammars. */
4374
+ /** @inline */
4517
4375
  declare type FieldEntryFields<TEditable, TGroup> = FieldBase<
4518
4376
  TEditable,
4519
4377
  TGroup
@@ -4551,10 +4409,73 @@ export declare interface FieldInsight {
4551
4409
  export declare type FieldKind = keyof FieldValueMap;
4552
4410
 
4553
4411
  /**
4554
- * A stored field mutation. `field.inc` and `field.dec` use the same names as
4555
- * `@sanity/client` patches and default an omitted `value` to a delta of `1`.
4412
+ * A field mutation targeting a declared field. Resolved values must satisfy
4413
+ * that field's shape, choices, validation, and assignment constraints.
4414
+ *
4415
+ * `field.setIfMissing` supports nullable fields only. If a value exists, it
4416
+ * leaves the value unchanged and records no `opApplied` history event.
4417
+ * `field.inc` and `field.dec` require an initialized `number` field; their
4418
+ * delta defaults to `1`. Both the delta and resulting value must be finite,
4419
+ * and the result must satisfy the field's validation bounds.
4420
+ *
4421
+ * `field.append` adds one valid list member. `field.updateWhere` accepts only
4422
+ * `array` fields and merges an object into matching rows. The merge cannot
4423
+ * write `_key` or `_type`, and each resulting row must satisfy its declared
4424
+ * shape. `field.removeWhere` supports list fields. See {@link Op} for row
4425
+ * selection and history behavior.
4426
+ */
4427
+ export declare type FieldMutationOp<
4428
+ TTarget extends {
4429
+ field: string;
4430
+ },
4431
+ > =
4432
+ | {
4433
+ type: "field.set";
4434
+ target: TTarget;
4435
+ value: ValueExpr;
4436
+ }
4437
+ | {
4438
+ type: "field.setIfMissing";
4439
+ target: TTarget;
4440
+ value: ValueExpr;
4441
+ }
4442
+ | {
4443
+ type: "field.unset";
4444
+ target: TTarget;
4445
+ }
4446
+ | {
4447
+ type: "field.append";
4448
+ target: TTarget;
4449
+ value: ValueExpr;
4450
+ }
4451
+ | {
4452
+ type: "field.inc";
4453
+ target: TTarget;
4454
+ value?: ValueExpr | undefined;
4455
+ }
4456
+ | {
4457
+ type: "field.dec";
4458
+ target: TTarget;
4459
+ value?: ValueExpr | undefined;
4460
+ }
4461
+ | {
4462
+ type: "field.updateWhere";
4463
+ target: TTarget;
4464
+ where: Condition;
4465
+ value: ValueExpr;
4466
+ }
4467
+ | {
4468
+ type: "field.removeWhere";
4469
+ target: TTarget;
4470
+ where: Condition;
4471
+ };
4472
+
4473
+ /**
4474
+ * A {@link FieldMutationOp} whose target scope is explicit. Actions can write
4475
+ * fields in their activity, stage, or workflow. Effect completions accept only
4476
+ * workflow- or stage-scoped field operations, never activity status changes.
4556
4477
  */
4557
- export declare type FieldOp = v.InferOutput<typeof StoredFieldOpSchema>;
4478
+ export declare type FieldOp = FieldMutationOp<StoredFieldRef>;
4558
4479
 
4559
4480
  /**
4560
4481
  * A concrete value a blocking atom pins for this field, with the verified
@@ -4568,6 +4489,7 @@ export declare interface FieldProposal {
4568
4489
  consequences: SiteConsequence[];
4569
4490
  }
4570
4491
 
4492
+ /** @inline */
4571
4493
  declare type FieldReadExpr = {
4572
4494
  type: "fieldRead";
4573
4495
  scope?: "workflow" | "stage" | undefined;
@@ -4575,15 +4497,24 @@ declare type FieldReadExpr = {
4575
4497
  path?: string | undefined;
4576
4498
  };
4577
4499
 
4578
- export declare type FieldScope = (typeof FIELD_SCOPES)[number];
4500
+ /**
4501
+ * The three field scopes a field entry can live in. Also the
4502
+ * group-declaration levels: a `groups` array lives at exactly these three
4503
+ * nodes, so `DefinitionGroupSite.level` reuses this vocabulary.
4504
+ */
4505
+ export declare type FieldScope = "workflow" | "stage" | "activity";
4579
4506
 
4580
4507
  /**
4581
- * A sub-field shape used inside an `object`'s `fields` or an `array`'s `of`
4582
- * lighter than {@link FieldEntry}: no `initialValue`/`editable`/`required`,
4583
- * since a sub-field's value comes from the parent. An `object` kind requires
4584
- * non-empty `fields` and no `of`; an `array` kind requires non-empty `of` and
4585
- * no `fields`; every other kind requires neither enforced at parse, not
4586
- * visible in this type.
4508
+ * A nested field shape inside an object's `fields`, an array's `of`, or an
4509
+ * effect's `outputs`. It has no initialization, direct editability, or required
4510
+ * setting; those belong to {@link FieldEntry}.
4511
+ *
4512
+ * An `object` requires nonempty `fields` and no `of`. An `array` requires
4513
+ * nonempty `of` and no `fields`. Other types accept neither. Sibling names
4514
+ * must be unique. Use ordinary `date` and `datetime` here; `dueDate` and
4515
+ * `dueDatetime` are not valid nested fields or effect outputs.
4516
+ * {@link ChoiceOptions} and {@link ScalarValidation} constrain supported
4517
+ * scalar types. `roles` is valid only on `assignee` and `assignees` shapes.
4587
4518
  */
4588
4519
  export declare interface FieldShape {
4589
4520
  type: FieldValueKind;
@@ -4599,14 +4530,32 @@ export declare interface FieldShape {
4599
4530
  }
4600
4531
 
4601
4532
  /**
4602
- * How a field seeds its `initialValue`, once at materialisation (advisory
4603
- * after the field stays freely editable). Absent means working memory: the
4604
- * field starts empty and an op fills it later, spelled by omission rather
4605
- * than an arm. Distinct from {@link ValueExpr}, an op's write payload; they
4606
- * overlap only on the literal and field-read arms.
4533
+ * Supplies a field's `initialValue` once, when the field is initialized.
4534
+ * Omitting the source starts the field empty; an operation can fill it later.
4535
+ * The source does not grant permission to edit. Direct editing requires an
4536
+ * {@link Editable | editable} declaration.
4537
+ *
4538
+ * Distinct from {@link ValueExpr}, which supplies an operation's write value.
4539
+ * Only the literal and field-read forms are shared.
4540
+ *
4541
+ * `input` reads workflow inputs supplied at start or spawn. Stage and activity
4542
+ * input seeds receive no caller value; activity input seeds produce a deploy
4543
+ * warning. `literal` supplies a fixed value. `query` runs against the Content
4544
+ * Lake with earlier fields in the same scope available as `$fields`.
4545
+ * Reference normalization can omit unrecognized values without recording
4546
+ * `fieldQueryDiscarded`. A result that fails validation after normalization
4547
+ * uses the field's empty value (`null` or `[]`) and records that event.
4548
+ * A failed query throws.
4549
+ *
4550
+ * A `fieldRead` seed reads earlier fields in its own scope when `scope` is
4551
+ * omitted. A stage or activity seed can read workflow fields with
4552
+ * `scope: 'workflow'`. An activity seed cannot read stage fields. At workflow
4553
+ * scope, omit `scope` to read an earlier workflow field. `path` selects a
4554
+ * nested value; these reads do not load referenced documents.
4607
4555
  */
4608
4556
  export declare type FieldSource = FieldSourceInternal;
4609
4557
 
4558
+ /** @inline */
4610
4559
  declare type FieldSourceInternal =
4611
4560
  | {
4612
4561
  type: "input";
@@ -4618,6 +4567,11 @@ declare type FieldSourceInternal =
4618
4567
  | LiteralExpr
4619
4568
  | FieldReadExpr;
4620
4569
 
4570
+ /** Shared diagnostic field-address label for workspace consumers; unsupported outside this workspace.
4571
+ * @internal
4572
+ */
4573
+ export declare function _fieldTargetLabel(target: EditFieldTarget): string;
4574
+
4621
4575
  /**
4622
4576
  * Every leaf replaced by its type name (`null` distinct from `object`); keys sorted by
4623
4577
  * UTF-16 code unit, not locale collation, so the shape canonicalises identically on every
@@ -4655,8 +4609,8 @@ export declare interface FieldValueMap {
4655
4609
  dueDatetime: string | null;
4656
4610
  url: string | null;
4657
4611
  actor: Actor | null;
4658
- /** A single {@link Assignee} the singular of {@link FieldValueMap.assignees}. */
4659
- assignee: Assignee | null;
4612
+ /** Assignment members with at most one user; role members do not consume that cardinality. */
4613
+ assignee: Assignee[];
4660
4614
  assignees: Assignee[];
4661
4615
  /** An object with named sub-fields; the value is keyed by sub-field name. */
4662
4616
  object: Record<string, unknown> | null;
@@ -4775,16 +4729,19 @@ export declare interface FiringConsequence {
4775
4729
  export { formatRead };
4776
4730
 
4777
4731
  /**
4778
- * Build a GDR URI from a workflow resource config + a document id
4779
- * within that resource. This is how the engine mints `_id`s for
4780
- * definitions / instances / ancestor refs into its own resource.
4732
+ * Creates a {@link GdrUri} for a document in the supplied resource. Dataset
4733
+ * document IDs must be stable; `drafts.` and `versions.<release>.` prefixes
4734
+ * throw. Select draft or release content through {@link WorkflowInstance.perspective}.
4781
4735
  */
4782
4736
  export declare function gdrFromResource(
4783
4737
  res: WorkflowResource,
4784
4738
  documentId: string,
4785
4739
  ): GdrUri;
4786
4740
 
4787
- /** Build a GDR (id + type) pointing at a document within a workflow resource. */
4741
+ /**
4742
+ * Creates a typed document reference in the supplied resource. Dataset
4743
+ * references require a stable document ID, as described by {@link gdrFromResource}.
4744
+ */
4788
4745
  export declare function gdrRef<TType extends string = string>({
4789
4746
  res,
4790
4747
  documentId,
@@ -4820,18 +4777,21 @@ export declare type GdrScheme =
4820
4777
  | "dashboard";
4821
4778
 
4822
4779
  /**
4823
- * Typed GDR URI string. The compiler rejects bare doc ids (`"doc-1"`)
4824
- * only `<scheme>:<...id-parts>` values typecheck. Construct one via
4825
- * `gdrUri()` / `gdrFromResource()` / `refDataset()` etc., or by hand
4826
- * with the scheme prefix baked in (`` `dataset:proj:ds:${docId}` `` ).
4780
+ * Resource-qualified document URI with a {@link GdrScheme} prefix. Construct
4781
+ * it with {@link gdrUri}, {@link gdrFromResource}, or {@link refDataset}.
4782
+ * Use {@link parseGdr} to validate a string's complete addressing format.
4827
4783
  *
4828
- * Combined with schema validation at the API boundary, this is the
4829
- * type + runtime guarantee that no bare-string id reaches the
4830
- * snapshot, field entry, or filter layer.
4784
+ * Dataset URIs require the stable document ID, such as `article-1`, without
4785
+ * a `drafts.` or `versions.<release>.` prefix. Select draft and release
4786
+ * content through {@link WorkflowInstance.perspective}.
4831
4787
  */
4832
4788
  export declare type GdrUri = `${GdrScheme}:${string}`;
4833
4789
 
4834
- /** Compose a GDR URI from parts. Inverse of `parseGdr`. */
4790
+ /**
4791
+ * Creates a {@link GdrUri} from addressing parts. For datasets, `documentId`
4792
+ * must be the stable ID; `drafts.` and `versions.<release>.` prefixes throw.
4793
+ * Select draft or release content through {@link WorkflowInstance.perspective}.
4794
+ */
4835
4795
  export declare function gdrUri(
4836
4796
  parts:
4837
4797
  | {
@@ -4916,8 +4876,13 @@ declare function grantsPermissionOn(args: {
4916
4876
  userId?: string;
4917
4877
  }): Promise<boolean>;
4918
4878
 
4919
- /** A named readiness condition. Activities accept only `'groq'`; workflow
4920
- * `start.requirements` also accepts `'singleSubject'` see {@link StartRequirement}. */
4879
+ /**
4880
+ * A named GROQ readiness condition. Its name must be unique in the containing
4881
+ * requirements array. Activity requirements use instance and caller variables;
4882
+ * workflow requirements use the input and projected dataset in {@link StartBlock}.
4883
+ * Every requirement must pass before the corresponding caller action or fresh
4884
+ * standalone start can commit.
4885
+ */
4921
4886
  export declare type GroqRequirement = RequirementBase & {
4922
4887
  type: "groq";
4923
4888
  query: string;
@@ -5018,33 +4983,15 @@ export declare function groupSitesOf(
5018
4983
  ): DefinitionGroupSite[];
5019
4984
 
5020
4985
  /**
5021
- * A lake mutation guard. A FOREIGN CONTRACT mirrored 1:1: `match`,
5022
- * `predicate`, and `metadata` are the content lake's persisted guard-document
5023
- * API, not engine-invented surface — the stored form keeps the lake's
5024
- * vocabulary verbatim. The engine adds exactly two things: `name` (a
5025
- * lake-id-segment, `^[a-z0-9][a-z0-9-]*$`, unique per definition — the lake
5026
- * `_id` derives from `(instanceId, name)` at stage entry) and the deploy-time
5027
- * read VALUES on `match.idRefs` / `metadata` (a typed {@link GuardRead} when
5028
- * authoring, resolved to bare values at deploy). `match` selects mutations by
5029
- * `types` (empty matches any), `idRefs` (field reads resolved to bare ids),
5030
- * `idPatterns` (bare glob ids), and `actions` (at least one). `predicate` is
5031
- * lake GROQ in a distinct delta-mode eval context (`before()`/`after()`,
5032
- * `mutation`, `guard`, `identity()`, bare ids/fields only): strictly `true`
5033
- * ALLOWS the mutation; anything else — false, null, an evaluation error, or
5034
- * an omitted/empty predicate — DENIES. `metadata` is the only bridge from
5035
- * that eval context (which cannot see `$fields`) to workflow fields, read as
5036
- * `guard.metadata.*` and re-synced by the post-field-op guard refresh. The
5037
- * lake does not enforce the guard document type yet: a deployed guard denies
5038
- * optimistically engine-side, and the lake ACL is the only hard gate until
5039
- * guard enforcement ships.
4986
+ * A stored workflow guard. Its string reads and authored lifecycle actions
4987
+ * remain unresolved until stage entry produces the Lake-shaped documents
4988
+ * deployed for that stage.
4989
+ *
4990
+ * @interface
5040
4991
  */
5041
4992
  export declare type Guard = v.InferOutput<typeof GuardSchema>;
5042
4993
 
5043
4994
  /**
5044
- * The lake document type for a mutation guard. Single source of truth — both
5045
- * the runtime value (id construction, `compileGuard`, queries) and the
5046
- * {@link MutationGuardDoc} `_type` literal derive from here.
5047
- *
5048
4995
  * The enforcement story hangs off this type: the lake does not evaluate
5049
4996
  * this doc type — it is the engine's placeholder for the lake's
5050
4997
  * forthcoming guard primitive (the lake reserves `system.*`). Until that
@@ -5061,21 +5008,24 @@ export declare const GUARD_OWNER = "robot:workflow-engine";
5061
5008
  * The identifiers a lake mutation guard's `predicate` reads — the wire
5062
5009
  * dialect, not the condition scope (so no {@link ConditionVarBinding}: these
5063
5010
  * bind only when a guard evaluates a mutation). `before()`/`after()`/
5064
- * `identity()` are groq-js delta-mode natives on top of these. Bound in one
5065
- * place: `guardPredicateParams` in the guard evaluator.
5011
+ * `identity()` are groq-js delta-mode natives on top of these. The guard
5012
+ * evaluator must bind every entry here at the predicate root.
5066
5013
  */
5067
5014
  export declare const GUARD_PREDICATE_VARS: readonly {
5068
5015
  name: string;
5069
5016
  description: string;
5070
5017
  }[];
5071
5018
 
5072
- export declare type GuardAction = v.InferOutput<typeof GuardActionSchema>;
5019
+ export declare type GuardAction = MutationGuardAction;
5073
5020
 
5074
- declare const GuardActionSchema: v.PicklistSchema<
5075
- readonly ["create", "update", "delete", "publish", "unpublish"],
5076
- string
5077
- >;
5021
+ export declare type GuardDereference = (ref: {
5022
+ _ref: string;
5023
+ }) => PromiseLike<Record<string, unknown> | null>;
5078
5024
 
5025
+ /**
5026
+ * A stored guard's match criteria. See {@link AuthoringGuard} for matching
5027
+ * rules; stored `idRefs` contains strings instead of typed {@link GuardRead}s.
5028
+ */
5079
5029
  export declare type GuardMatch = Guard["match"];
5080
5030
 
5081
5031
  /**
@@ -5096,96 +5046,31 @@ export declare function guardMatches({
5096
5046
  }): boolean;
5097
5047
 
5098
5048
  /**
5099
- * A deploy-time value read on a guard's `match.idRefs` / `metadata`, typed
5100
- * like {@link ValueExpr} (`self`/`now`/`fieldRead`, plus the guard-only
5101
- * `effectsRead` for a completed effect's output). Workflow-scope only a
5102
- * guard outlives any activity, so `fieldRead` here carries no `scope`.
5103
- * Desugar prints the STORED string spelling the deploy resolver and guard
5104
- * refresh parse (`"$self"`, `"$now"`, `"$fields.<name>[.path]"`,
5105
- * `"$effects['<name>'][.path]"`); those spellings are single-line strings
5106
- * matched by anchored regexes, so a line break in a path would print an
5107
- * unparseable read.
5049
+ * A value read for a guard's `match.idRefs` or `metadata`, resolved when the
5050
+ * guard is created or refreshed. `fieldRead` reads workflow fields only;
5051
+ * stage and activity fields are unavailable. `effectsRead` reads a completed
5052
+ * effect's output. `self` supplies the instance's GDR URI and `now` its ISO
5053
+ * clock value.
5054
+ * Paths cannot contain line breaks, and effect names cannot contain `'`.
5055
+ * Stored {@link Guard} declarations carry string forms of these reads.
5108
5056
  */
5109
- export declare type GuardRead = v.InferOutput<typeof GuardReadSchema>;
5110
-
5111
- declare const GuardReadSchema: v.VariantSchema<
5112
- "type",
5113
- [
5114
- v.StrictObjectSchema<
5115
- {
5116
- readonly type: v.LiteralSchema<"self", undefined>;
5117
- },
5118
- undefined
5119
- >,
5120
- v.StrictObjectSchema<
5121
- {
5122
- readonly type: v.LiteralSchema<"now", undefined>;
5123
- },
5124
- undefined
5125
- >,
5126
- v.StrictObjectSchema<
5127
- {
5128
- readonly type: v.LiteralSchema<"fieldRead", undefined>;
5129
- readonly field: v.SchemaWithPipe<
5130
- readonly [v.StringSchema<undefined>, v.RegexAction<string, string>]
5131
- >;
5132
- readonly path: v.OptionalSchema<
5133
- v.SchemaWithPipe<
5134
- readonly [
5135
- v.SchemaWithPipe<
5136
- readonly [
5137
- v.StringSchema<undefined>,
5138
- v.MinLengthAction<string, 1, "must be a non-empty string">,
5139
- ]
5140
- >,
5141
- v.CheckAction<
5142
- string,
5143
- "a guard read path cannot contain a line break"
5144
- >,
5145
- ]
5146
- >,
5147
- undefined
5148
- >;
5149
- },
5150
- undefined
5151
- >,
5152
- v.StrictObjectSchema<
5153
- {
5154
- readonly type: v.LiteralSchema<"effectsRead", undefined>;
5155
- readonly effect: v.SchemaWithPipe<
5156
- readonly [
5157
- v.SchemaWithPipe<
5158
- readonly [
5159
- v.StringSchema<undefined>,
5160
- v.MinLengthAction<string, 1, "must be a non-empty string">,
5161
- ]
5162
- >,
5163
- v.CheckAction<string, "an effect name cannot contain `'`">,
5164
- ]
5165
- >;
5166
- readonly path: v.OptionalSchema<
5167
- v.SchemaWithPipe<
5168
- readonly [
5169
- v.SchemaWithPipe<
5170
- readonly [
5171
- v.StringSchema<undefined>,
5172
- v.MinLengthAction<string, 1, "must be a non-empty string">,
5173
- ]
5174
- >,
5175
- v.CheckAction<
5176
- string,
5177
- "a guard read path cannot contain a line break"
5178
- >,
5179
- ]
5180
- >,
5181
- undefined
5182
- >;
5183
- },
5184
- undefined
5185
- >,
5186
- ],
5187
- undefined
5188
- >;
5057
+ export declare type GuardRead =
5058
+ | {
5059
+ type: "self";
5060
+ }
5061
+ | {
5062
+ type: "now";
5063
+ }
5064
+ | {
5065
+ type: "fieldRead";
5066
+ field: string;
5067
+ path?: string | undefined;
5068
+ }
5069
+ | {
5070
+ type: "effectsRead";
5071
+ effect: string;
5072
+ path?: string | undefined;
5073
+ };
5189
5074
 
5190
5075
  declare const GuardSchema: v.StrictObjectSchema<
5191
5076
  {
@@ -5235,21 +5120,12 @@ declare const GuardSchema: v.StrictObjectSchema<
5235
5120
  >,
5236
5121
  undefined
5237
5122
  >;
5238
- actions: v.SchemaWithPipe<
5239
- readonly [
5240
- v.ArraySchema<
5241
- v.PicklistSchema<
5242
- readonly ["create", "update", "delete", "publish", "unpublish"],
5243
- string
5244
- >,
5245
- undefined
5246
- >,
5247
- v.MinLengthAction<
5248
- ("create" | "update" | "delete" | "publish" | "unpublish")[],
5249
- 1,
5250
- "a guard must match at least one action"
5251
- >,
5252
- ]
5123
+ actions: v.ArraySchema<
5124
+ v.PicklistSchema<
5125
+ readonly ["create", "update", "delete", "publish", "unpublish"],
5126
+ string
5127
+ >,
5128
+ undefined
5253
5129
  >;
5254
5130
  },
5255
5131
  undefined
@@ -5282,7 +5158,7 @@ declare const GuardSchema: v.StrictObjectSchema<
5282
5158
  * its guards statically name — no live instance required. Guard docs are
5283
5159
  * stamped with the version-less definition, so this spans the datasources
5284
5160
  * declared across ALL deployed versions
5285
- * ({@link DefinitionGuardsQueryArgs.definitions}), not just the latest.
5161
+ * (`definitions`), not just the latest.
5286
5162
  *
5287
5163
  * A datasource is statically reachable when a guard idRef resolves to a
5288
5164
  * hardcoded GDR literal — directly, or via a `fieldRead` of a field entry whose
@@ -5320,15 +5196,13 @@ export declare function guardsForResource(
5320
5196
  export { guillemets };
5321
5197
 
5322
5198
  /**
5323
- * Content fingerprint of an authored definition: the canonical JSON of its
5324
- * content, hashed. Stamped on the deployed document ({@link DeployedDefinition})
5325
- * and pinned on every instance, so a redeploy of identical content is a no-op
5326
- * and a definition that drifted from what an instance pinned is detectable.
5327
- *
5328
- * Advisory, like every engine check (the lake is the only enforcement point):
5329
- * FNV-1a is a fast, deterministic, dependency-free, isomorphic digest — enough
5330
- * to detect honest change and drift, not a tamper-proof seal. Kept synchronous
5331
- * so the pure planning path ({@link planDefinitionDeploy}) needs no `await`.
5199
+ * Computes a deterministic, non-cryptographic fingerprint of authored
5200
+ * definition content. The result is 16 lowercase hexadecimal characters.
5201
+ * Object-key order does not affect it; array order and field values do.
5202
+ * Pass authored content without stored-document envelope fields: this
5203
+ * function strips none of them. The authoring-only `runtime` block is the one
5204
+ * key it ignores, so two definitions that differ only in a hosting kind
5205
+ * fingerprint identically.
5332
5206
  */
5333
5207
  export declare function hashDefinitionContent(def: WorkflowDefinition): string;
5334
5208
 
@@ -5424,6 +5298,7 @@ export declare type HistoryEntry = HistoryEvent & {
5424
5298
  executionContext?: ExecutionContext;
5425
5299
  };
5426
5300
 
5301
+ /** @inline */
5427
5302
  declare type HistoryEvent =
5428
5303
  | {
5429
5304
  _key: string;
@@ -5589,10 +5464,18 @@ export { humanize };
5589
5464
  export declare interface HydratedSnapshot {
5590
5465
  /** Hydrated docs, keyed by GDR URI as `_id`. */
5591
5466
  docs: SanityDocument[];
5592
- /** Existence-check helper; the core eval pipeline itself doesn't read it. */
5467
+ /** The GDR URIs of every document in `docs`, used to diagnose missing references. */
5593
5468
  knownIds: Set<string>;
5594
5469
  }
5595
5470
 
5471
+ /** Assignment ownership for list/read surfaces. Role aliases deliberately do
5472
+ * not apply: aliases widen authorization, not whose inbox a literal pool
5473
+ * member routes work into. */
5474
+ export declare function identityMatchesAssignment(
5475
+ members: readonly Assignee[],
5476
+ identity: AssignmentIdentity,
5477
+ ): boolean;
5478
+
5596
5479
  /**
5597
5480
  * The in-flight arm — the one spelling of "not completed/aborted" every
5598
5481
  * list surface's `includeCompleted` filter negates (the engine stamps
@@ -5712,6 +5595,12 @@ export declare type InsightSite =
5712
5595
  activity?: string;
5713
5596
  };
5714
5597
 
5598
+ /** Viewer-scoped assignment counts across active activities in the open stage. */
5599
+ export declare function instanceAssignmentStateCounts(
5600
+ instance: AssignmentInstance,
5601
+ identity: AssignmentIdentity,
5602
+ ): AssignmentStateCounts;
5603
+
5715
5604
  /**
5716
5605
  * The tag's instance partition as a listen filter — the one shared change
5717
5606
  * feed a preview store keeps itself fresh from (an event names the touched
@@ -5725,9 +5614,9 @@ export declare function instanceChangesQuery(args: {
5725
5614
 
5726
5615
  /**
5727
5616
  * Mint the Sanity document `_id` for a workflow instance — a fresh
5728
- * {@link randomKey} suffix, so every instance (root or spawned child) gets a
5617
+ * random suffix, so every instance (root or spawned child) gets a
5729
5618
  * unique doc id under its tag. Lives in the shell, not `core/`, because it
5730
- * draws randomness; the deterministic {@link definitionDocId} is the pure-core
5619
+ * draws randomness; the deterministic `definitionDocId` is the pure-core
5731
5620
  * counterpart. Bare form — Sanity rejects `:` in document IDs, so this is
5732
5621
  * never a GDR URI.
5733
5622
  */
@@ -5745,7 +5634,7 @@ export declare function instanceDocId(tag: string): string;
5745
5634
  */
5746
5635
  export declare function instanceGuardQuery(instanceId: string): CompiledQuery;
5747
5636
 
5748
- declare interface InstanceGuardsQueryArgs {
5637
+ export declare interface InstanceGuardsQueryArgs {
5749
5638
  client: WorkflowClient;
5750
5639
  clientForGdr: ClientForGdr;
5751
5640
  instance: WorkflowInstance;
@@ -5822,8 +5711,10 @@ export declare interface InstanceSession {
5822
5711
  /** Best-effort projection against the held content + held guards. The first
5823
5712
  * call resolves the caller's identity/grants from the client's token over
5824
5713
  * the network (cached per client) — plus each foreign subject resource's
5825
- * grants through its own client, for the subject-write forecast;
5826
- * evaluation itself runs in-memory on groq-js. */
5714
+ * grants through its own client, for the subject-write forecast. The held
5715
+ * snapshot is not refetched. Missing references receive completed availability
5716
+ * metadata checks; a guard predicate using `->` reads its target
5717
+ * through the bound engine client. */
5827
5718
  evaluate(): Promise<WorkflowEvaluation>;
5828
5719
  /** Advance the instance against the held content: cascade auto-transitions,
5829
5720
  * deploy guards, queue effects, commit with `ifRevisionId`. */
@@ -5930,6 +5821,14 @@ export declare interface InstancesQueryFilter {
5930
5821
  definition?: string;
5931
5822
  /** Current stage name. */
5932
5823
  stage?: string;
5824
+ /** Current viewer assignment filter. `unrouted` needs no identity match;
5825
+ * `routed` matches literal role members only while no user holds the
5826
+ * activity; `held` matches the direct user and shadows every role. */
5827
+ assignment?: {
5828
+ userId: string;
5829
+ roles?: readonly string[] | undefined;
5830
+ states?: readonly AssignmentState[] | undefined;
5831
+ };
5933
5832
  /** Include completed/aborted instances (default: in-flight only). */
5934
5833
  includeCompleted?: boolean;
5935
5834
  /**
@@ -5957,9 +5856,9 @@ export declare interface InstancesQueryFilter {
5957
5856
  /**
5958
5857
  * Whether {@link document} is in {@link instance}'s reactive watch-set — the
5959
5858
  * reverse of {@link subscriptionDocumentsForInstance}. Both derive from
5960
- * {@link collectWatchRefs}, the single source of truth, so "which docs does
5859
+ * the shared watch-ref collector, the single source of truth, so "which docs does
5961
5860
  * this instance watch" and "which instances watch this doc" stay in lockstep
5962
- * — the same way {@link hydrateSnapshot}'s load-set does. Matching is on the
5861
+ * — the same way `hydrateSnapshot`'s load-set does. Matching is on the
5963
5862
  * resource-qualified GDR URI, so a cross-dataset subject (`dataset:A:ds:doc`)
5964
5863
  * never matches a same-id doc in another resource (`dataset:B:ds:doc`).
5965
5864
  *
@@ -6190,6 +6089,9 @@ export declare function lakeGuardId(args: {
6190
6089
  guardName: string;
6191
6090
  }): string;
6192
6091
 
6092
+ /** The write operations Content Lake exposes to mutation guards. */
6093
+ export declare type LakeMutationGuardAction = "create" | "update" | "delete";
6094
+
6193
6095
  /**
6194
6096
  * The one rule every lake-facing identity check (guard previews/pre-flights, `$can` grant filters)
6195
6097
  * must resolve through to agree with the lake's own `identity()`; binding `actor.id` directly at a
@@ -6248,6 +6150,7 @@ export declare function lintEffectOutputs(
6248
6150
  definition: WorkflowDefinition,
6249
6151
  ): string[];
6250
6152
 
6153
+ /** @inline */
6251
6154
  declare type LiteralExpr = {
6252
6155
  type: "literal";
6253
6156
  value: unknown;
@@ -6275,9 +6178,15 @@ export declare interface LogicalRef {
6275
6178
  * reference whose resolved document the consumer opens; deploy checks the
6276
6179
  * `field` variant points at a doc-valued entry.
6277
6180
  */
6278
- export declare type ManualTarget = v.InferOutput<
6279
- typeof StoredManualTargetSchema
6280
- >;
6181
+ export declare type ManualTarget =
6182
+ | {
6183
+ type: "url";
6184
+ url: string;
6185
+ }
6186
+ | {
6187
+ type: "field";
6188
+ field: StoredFieldRef;
6189
+ };
6281
6190
 
6282
6191
  /** Returns true iff `document` survives `filter`'s GROQ predicate under the supplied identity. */
6283
6192
  declare function matchesFilter(args: {
@@ -6293,11 +6202,34 @@ declare function matchesFilter(args: {
6293
6202
  export { MAX_COUNTERFACTUAL_INDEX };
6294
6203
 
6295
6204
  /**
6296
- * The engine always writes both stamps together, so a bare `modelVersion` with no
6297
- * `minReaderModel` is malformed foreign data; that case reads the version itself as the
6298
- * floor (conservative fallback).
6205
+ * The engine always writes both stamps together, so a bare `modelVersion` with no
6206
+ * `minReaderModel` is malformed foreign data; that case reads the version itself as the
6207
+ * floor (conservative fallback).
6208
+ */
6209
+ export declare function minReaderModelOf(doc: object): number;
6210
+
6211
+ /**
6212
+ * A selected document absent from the evaluated snapshot. Absence alone does
6213
+ * not prove deletion. When present, `availability` carries the completed check.
6214
+ * This evidence is derived for the evaluation and is never persisted.
6215
+ */
6216
+ export declare interface MissingDocument {
6217
+ target: EditFieldTarget;
6218
+ reference: GlobalDocumentReference;
6219
+ /** The declared field title, when available. */
6220
+ title?: string;
6221
+ /** Completed availability evidence. Failed or unsupported checks yield `unreadable`.
6222
+ * Omitted when the caller supplied only a content snapshot. */
6223
+ availability?: DocumentAvailability;
6224
+ }
6225
+
6226
+ /**
6227
+ * Shared formatter for Workflows integrations; not a supported consumer API.
6228
+ * @internal
6299
6229
  */
6300
- export declare function minReaderModelOf(doc: object): number;
6230
+ export declare function _missingDocumentsSummary(
6231
+ documents: readonly MissingDocument[],
6232
+ ): string;
6301
6233
 
6302
6234
  export declare interface MissingHandlerDeployInfo {
6303
6235
  phase: "deploy";
@@ -6314,7 +6246,7 @@ export declare interface MissingHandlerDrainInfo {
6314
6246
  }
6315
6247
 
6316
6248
  /**
6317
- * The `missingHandler: 'fail'` policy tripped: an effect names a handler the
6249
+ * The `effects.missingHandler: 'fail'` policy tripped: an effect names a handler the
6318
6250
  * runtime never registered. `info` carries the phase-specific location
6319
6251
  * (deploy verification vs a drain attempt) so the runtime that opted into
6320
6252
  * failing can report exactly which handler is missing where.
@@ -6339,9 +6271,9 @@ export declare type MissingHandlerPolicy =
6339
6271
  * required when it is `required` AND `input`-sourced (the only combination
6340
6272
  * deploy admits), and as provided when a supplied value matches its name AND
6341
6273
  * kind with a real (non-null) value. Keys on the same name+type as the input
6342
- * read in {@link resolveInputValue}, but is stricter: a present-but-null/
6274
+ * read during input resolution, but is stricter: a present-but-null/
6343
6275
  * undefined value counts as absent here (a required field needs a real
6344
- * value), whereas {@link resolveInputValue} passes a null fill straight
6276
+ * value), whereas input resolution passes a null fill straight
6345
6277
  * through. Exported so pre-flight validators (e.g. mapping validation) share
6346
6278
  * the engine's own rule instead of mirroring it.
6347
6279
  */
@@ -6373,15 +6305,6 @@ export declare class ModelVersionAheadError extends WorkflowError<"model-version
6373
6305
  /** A document with no stamp, or a non-number stamp (foreign data this engine never wrote), reads as model 0. */
6374
6306
  export declare function modelVersionOf(doc: object): number;
6375
6307
 
6376
- /** The lake operations a guard can gate — see the guard types in ./authorization.ts. */
6377
- declare const MUTATION_GUARD_ACTIONS: readonly [
6378
- "create",
6379
- "update",
6380
- "delete",
6381
- "publish",
6382
- "unpublish",
6383
- ];
6384
-
6385
6308
  /**
6386
6309
  * Inputs to predicate evaluation: the delta-mode natives `before()`/`after()`,
6387
6310
  * the `mutation`, the `guard`, and `identity()`. `before` is null on create,
@@ -6400,7 +6323,7 @@ export declare interface MutationContext {
6400
6323
  _type: string;
6401
6324
  } & Record<string, unknown>)
6402
6325
  | null;
6403
- action: MutationGuardAction;
6326
+ action: LakeMutationGuardAction;
6404
6327
  /**
6405
6328
  * The caller's principal id in the guarded resource's own namespace
6406
6329
  * (what that lake's `identity()` returns), resolved as `identity()` in
@@ -6410,8 +6333,11 @@ export declare interface MutationContext {
6410
6333
  identity?: string;
6411
6334
  }
6412
6335
 
6336
+ /** Lake operations plus the authored lifecycle actions the compiler translates. */
6413
6337
  export declare type MutationGuardAction =
6414
- (typeof MUTATION_GUARD_ACTIONS)[number];
6338
+ | LakeMutationGuardAction
6339
+ | "publish"
6340
+ | "unpublish";
6415
6341
 
6416
6342
  /**
6417
6343
  * The persisted body of a mutation guard — every field except the lake system
@@ -6444,7 +6370,11 @@ export declare interface MutationGuardBody {
6444
6370
  description?: string;
6445
6371
  /** Bare document ids (resource-local; both published and `drafts.` forms). */
6446
6372
  match: MutationGuardMatch;
6447
- /** GROQ; empty string = unconditional deny. Bare ids/fields only — no GDRs. */
6373
+ /**
6374
+ * Lake delta-mode GROQ. The root exposes `document.before`,
6375
+ * `document.after`, `mutation`, and `guard`; `identity()` and resource-local
6376
+ * reference dereferencing are available. Empty string is unconditional deny.
6377
+ */
6448
6378
  predicate: string;
6449
6379
  /** Caller-owned projected state the predicate reads as `guard.metadata.*`. */
6450
6380
  metadata: Record<string, unknown>;
@@ -6483,7 +6413,7 @@ export declare class MutationGuardDeniedError extends WorkflowError<"mutation-gu
6483
6413
  */
6484
6414
  static fromGuards(args: {
6485
6415
  documentId: string;
6486
- action: MutationGuardAction;
6416
+ action: LakeMutationGuardAction;
6487
6417
  guards: readonly MutationGuardDoc[];
6488
6418
  }): MutationGuardDeniedError;
6489
6419
  }
@@ -6541,15 +6471,27 @@ export declare interface NoteItem {
6541
6471
  at?: string | null;
6542
6472
  }
6543
6473
 
6544
- /** An append-only audit/comment log: sugar over `array of object {body, actor, at}` — the `actor`/`at`
6545
- * names match the `audit` op's stamp fields, so it pairs with it. Never a stored kind. */
6474
+ /** @inline */
6546
6475
  declare type NotesField = FieldBase<AuthoringEditable, GroupMembership> & {
6547
6476
  type: "notes";
6548
6477
  };
6549
6478
 
6550
- /** A `field.updateWhere` / `field.removeWhere` op's `where` selects rows to
6551
- * mutate with rendered-scope GROQ (`$row`, `$params` bound) row selection, not a gate; an unevaluable row never matches. */
6552
- export declare type Op = v.InferOutput<typeof StoredOpSchema>;
6479
+ /**
6480
+ * An action operation: a {@link FieldOp} or a status change on an activity in
6481
+ * the current stage.
6482
+ *
6483
+ * For `field.updateWhere` and `field.removeWhere`, `where` evaluates each row
6484
+ * as `$row`. Caller-fired actions also supply `$params`. Referenced document
6485
+ * content is not loaded for row selection, and an unevaluable row never
6486
+ * matches. An operation matching no rows still records `opApplied` history.
6487
+ */
6488
+ export declare type Op =
6489
+ | FieldOp
6490
+ | {
6491
+ type: "status.set";
6492
+ activity: string;
6493
+ status: ActivityStatus;
6494
+ };
6553
6495
 
6554
6496
  /**
6555
6497
  * Op `type` discriminators — the stored mutation primitives.
@@ -6602,6 +6544,11 @@ export declare interface OpAppliedSummary {
6602
6544
  resolved?: Record<string, unknown>;
6603
6545
  }
6604
6546
 
6547
+ /** Assignment members for each active activity in the instance's open stage. */
6548
+ export declare function openActivityAssignments(
6549
+ instance: AssignmentInstance,
6550
+ ): readonly (readonly Assignee[])[];
6551
+
6605
6552
  export declare interface OperationArgs {
6606
6553
  instanceId: string;
6607
6554
  /**
@@ -6612,9 +6559,10 @@ export declare interface OperationArgs {
6612
6559
 
6613
6560
  /**
6614
6561
  * What a state-changing verb reports back. Every mutating verb —
6615
- * `startInstance`, `fireAction`, `editField`, `completeEffect`, `tick`,
6616
- * `setStage`, `abortInstance` — returns this one shape, on the namespace,
6617
- * the `Engine`, and the reactive session alike.
6562
+ * `startInstance`, `fireAction`, `editField`, `completeEffect`,
6563
+ * `commitEffectOps`, `tick`, `setStage`, `abortInstance`, `resetActivity`
6564
+ * returns this one shape, on the namespace, the `Engine`, and the reactive
6565
+ * session alike.
6618
6566
  */
6619
6567
  export declare interface OperationResult {
6620
6568
  /** The instance after the operation + all cascading auto-transitions. */
@@ -6634,6 +6582,18 @@ export declare interface OperationResult {
6634
6582
  * during the action commit. Surfaced for caller-side assertions and
6635
6583
  * audit. */
6636
6584
  ranOps?: OpAppliedSummary[];
6585
+ /**
6586
+ * The earliest future ISO 8601 instant the engine can derive for a time-based
6587
+ * change to the instance's evaluation. Schedule the next {@link Engine.tick | tick} for it.
6588
+ * Excludes gates reading `$now` beside a caller variable;
6589
+ * {@link WorkflowEvaluation.nextEvaluationAt} carries those boundaries.
6590
+ * Derived per call, never persisted.
6591
+ *
6592
+ * Absent on a terminal instance or when the engine cannot derive a boundary.
6593
+ * Conditions using date arithmetic may yield no boundary. Time can still
6594
+ * affect a nonterminal instance when this value is absent.
6595
+ */
6596
+ nextEvaluationAt?: string;
6637
6597
  }
6638
6598
 
6639
6599
  export { OUTCOME_MARKS };
@@ -6649,10 +6609,11 @@ export declare function parentRef(
6649
6609
  /**
6650
6610
  * Parse one incoming definition at the deploy/diff boundary (`caller` prefixes
6651
6611
  * the error). Accepts authored content or a fetched definition document — the
6652
- * document envelope is stripped (the inverse of the deploy serialisation, so a
6653
- * fetched document round-trips to `unchanged` instead of fingerprinting its
6654
- * envelope as content), then the remainder strict-parses against the stored
6655
- * schema: any unknown key anywhere in the tree fails loud.
6612
+ * document envelope and the authoring-only `runtime` block are stripped (the
6613
+ * inverse of the deploy serialisation, so a fetched document round-trips to
6614
+ * `unchanged` instead of fingerprinting its envelope as content, and a hosting
6615
+ * kind never changes a definition's version), then the remainder strict-parses
6616
+ * against the stored schema: any unknown key anywhere in the tree fails loud.
6656
6617
  */
6657
6618
  export declare function parseDefinitionInput(
6658
6619
  def: Record<string, unknown>,
@@ -6687,8 +6648,10 @@ export declare interface ParsedGdr {
6687
6648
  }
6688
6649
 
6689
6650
  /**
6690
- * Parse a GDR URI into its scheme + addressing parts. Throws on
6691
- * unknown scheme or malformed shape.
6651
+ * Parses a GDR URI into its scheme and addressing parts. Throws for an
6652
+ * unknown scheme, malformed addressing, or a dataset document ID prefixed
6653
+ * with `drafts.` or `versions.<release>.`. Use the stable document ID and
6654
+ * select draft or release content through {@link WorkflowInstance.perspective}.
6692
6655
  */
6693
6656
  export declare function parseGdr(uri: string): ParsedGdr;
6694
6657
 
@@ -6725,7 +6688,7 @@ export declare function parseResourceGdr(uri: string): WorkflowResource;
6725
6688
  /**
6726
6689
  * A stage's multi-guard deploy failed *after* at least one guard already landed.
6727
6690
  * Those partial locks can't be cleanly undone (guard docs have no transactional
6728
- * deploy). Inside the engine {@link deployOrRollback} rolls the state move back
6691
+ * deploy). Inside the engine `deployOrRollback` rolls the state move back
6729
6692
  * and escalates this to a loud {@link WorkflowStateDivergedError}; a caller that
6730
6693
  * invokes {@link deployStageGuards} directly (without that rollback wrapper) can
6731
6694
  * also see it, so it's exported to be catchable by type.
@@ -6733,7 +6696,14 @@ export declare function parseResourceGdr(uri: string): WorkflowResource;
6733
6696
  export declare class PartialGuardDeployError extends WorkflowError<"partial-guard-deploy"> {
6734
6697
  readonly stageName: string;
6735
6698
  readonly deployed: number;
6736
- constructor(args: { stageName: string; deployed: number; cause: unknown });
6699
+ /** The cleanup failure, when newly created guards could not be retracted. */
6700
+ readonly rollbackError?: unknown;
6701
+ constructor(args: {
6702
+ stageName: string;
6703
+ deployed: number;
6704
+ cause: unknown;
6705
+ rollbackError?: unknown;
6706
+ });
6737
6707
  }
6738
6708
 
6739
6709
  export declare interface PendingEffect {
@@ -6913,8 +6883,8 @@ export declare function projectStartSliceRow(
6913
6883
  * representation's stored id rides along as `_originalId` — session-side
6914
6884
  * conditions (including the `_originalId in path("versions.**")` shape) then
6915
6885
  * read the same projected identity as the engine's perspective-aware hydration.
6916
- * Strict by construction: only the ids in
6917
- * {@link watchRefRepresentations} are accepted — an id that merely *ends* in
6886
+ * Strict by construction: only a canonical watch-reference representation is
6887
+ * accepted — an id that merely *ends* in
6918
6888
  * the watched id (another doc's dotted id under a version prefix), a release
6919
6889
  * the perspective doesn't read, or a draft the perspective makes invisible is
6920
6890
  * a store routing bug, and projecting it would make content the engine's read
@@ -6964,8 +6934,8 @@ export declare class ReaderModelAcknowledgementError extends WorkflowError<"read
6964
6934
  readonly expectedMinReaderModel: unknown;
6965
6935
  readonly requiredMinReaderModel: number;
6966
6936
  readonly engineMinReaderModel = 4;
6967
- readonly engineMaxReaderModel = 8;
6968
- readonly engineModelVersion = 8;
6937
+ readonly engineMaxReaderModel = 10;
6938
+ readonly engineModelVersion = 10;
6969
6939
  readonly documentationUrl = "https://www.sanity.io/docs/workflows/prerelease";
6970
6940
  constructor(
6971
6941
  expectedMinReaderModel: unknown,
@@ -6997,7 +6967,7 @@ export declare function readInstancePreviewDoc(
6997
6967
  * perspective; everything else is content and resolves to its
6998
6968
  * version/draft/published form. This is the single encoding of the rule
6999
6969
  * the {@link WatchSet} `perspective` contract describes to consumers, and
7000
- * the rule {@link hydrateSnapshot} applies on the fetch side.
6970
+ * the rule `hydrateSnapshot` applies on the fetch side.
7001
6971
  */
7002
6972
  export declare function readsRaw(ref: { type: string }): boolean;
7003
6973
 
@@ -7021,7 +6991,11 @@ export declare function refDashboard<TType extends string = string>({
7021
6991
  type,
7022
6992
  }: ResourceRefArgs<TType>): GlobalDocumentReference<TType>;
7023
6993
 
7024
- /** Make a GDR pointer to a project-dataset doc. */
6994
+ /**
6995
+ * Creates a typed reference to a dataset document. Pass the stable document
6996
+ * ID; `drafts.` and `versions.<release>.` prefixes throw. Select draft or
6997
+ * release content through {@link WorkflowInstance.perspective}.
6998
+ */
7025
6999
  export declare function refDataset<TType extends string = string>({
7026
7000
  projectId,
7027
7001
  dataset,
@@ -7122,7 +7096,7 @@ export declare function releaseRef({
7122
7096
  * half. Empty unless the instance is `stuck`: a `waiting` instance advances on
7123
7097
  * its own next action (see `availableActions`), and terminal or `progressing`
7124
7098
  * ones need nothing. Each verb is flagged
7125
- * {@link SuggestedRemediation.available} from {@link RUNNABLE_VERBS}.
7099
+ * {@link SuggestedRemediation.available} from the runnable-verb vocabulary.
7126
7100
  */
7127
7101
  export declare function remediationsFor(
7128
7102
  diagnosis: Diagnosis,
@@ -7141,6 +7115,12 @@ export declare type RemediationVerb =
7141
7115
  | "set-stage"
7142
7116
  | "abort";
7143
7117
 
7118
+ /** @internal Validated project-member reads shared by workspace adapters; not a supported consumer API. */
7119
+ export declare function _requestProjectMembers(
7120
+ request: (options: { url: string }) => Promise<unknown>,
7121
+ projectId: string,
7122
+ ): Promise<_ClientProjectMember[]>;
7123
+
7144
7124
  /** The reader model a deployment must acknowledge for its submitted definitions. */
7145
7125
  export declare function requiredDefinitionReaderModel(
7146
7126
  definitions: readonly unknown[],
@@ -7180,13 +7160,17 @@ export declare function requiredReaderModel(
7180
7160
  document: unknown,
7181
7161
  ): number;
7182
7162
 
7163
+ /** @inline */
7183
7164
  declare type RequirementBase = {
7184
7165
  name: string;
7185
7166
  title?: string | undefined;
7186
7167
  description?: string | undefined;
7187
7168
  };
7188
7169
 
7189
- /** Authored identity and display copy for one readiness requirement. */
7170
+ /**
7171
+ * Identity and display copy for an unmet requirement. Authored requirements use
7172
+ * their declared names; required-reference readability checks use `field:<name>`.
7173
+ */
7190
7174
  export declare interface RequirementDescriptor {
7191
7175
  name: string;
7192
7176
  title?: string | undefined;
@@ -7201,17 +7185,14 @@ export declare interface RequirementDescriptor {
7201
7185
  */
7202
7186
  export declare const RESERVED_CONDITION_VARS: readonly string[];
7203
7187
 
7204
- declare const RESET_ACTIVITY_TARGETS: readonly ["active", "skipped"];
7205
-
7206
7188
  export declare interface ResetActivityArgs extends DedupableOperationArgs {
7207
7189
  /** Name of the activity to reset, within the instance's current stage. */
7208
7190
  activity: string;
7209
7191
  /**
7210
- * What to reset it into. `active` (the default) re-runs the activity — back
7211
- * in progress, for a caller to drive to completion again; `skipped` bypasses
7212
- * it terminal but resolved, so a `$allActivitiesDone`-gated exit transition
7213
- * can fire. `done` is intentionally not offered: a reset is recovery, not a
7214
- * silent success.
7192
+ * The target status. `active` (the default) reopens the activity for
7193
+ * caller-fired actions. `skipped` counts the activity as resolved for
7194
+ * `$allActivitiesDone`. Returning to `active` does not repeat a `when`
7195
+ * action that already fired during this stage visit.
7215
7196
  */
7216
7197
  to?: ResetActivityTarget;
7217
7198
  }
@@ -7236,8 +7217,7 @@ export declare type ResetActivityResult =
7236
7217
  * fire). `done` is deliberately absent: a reset is recovery, not a silent
7237
7218
  * declaration that the work succeeded.
7238
7219
  */
7239
- export declare type ResetActivityTarget =
7240
- (typeof RESET_ACTIVITY_TARGETS)[number];
7220
+ export declare type ResetActivityTarget = "active" | "skipped";
7241
7221
 
7242
7222
  /**
7243
7223
  * Resolve the engine's `WorkflowAccess` for a client — actor and grants
@@ -7279,6 +7259,12 @@ export declare interface ResolveClientActorArgs {
7279
7259
  readonly projectId: string;
7280
7260
  }
7281
7261
 
7262
+ /** {@link EngineEffectsArgs} after the engine applied its defaults. */
7263
+ export declare interface ResolvedEngineEffects {
7264
+ readonly handlers: Readonly<Record<string, EffectHandler>>;
7265
+ readonly missingHandler: MissingHandlerPolicy;
7266
+ }
7267
+
7282
7268
  /**
7283
7269
  * A resolved field entry as the engine persists it on an instance.
7284
7270
  * Discriminated by `_type` (bare — unique within this union); the `value`
@@ -7337,9 +7323,22 @@ export declare function resolveFieldEntry(
7337
7323
  ): ResolvedFieldEntry | undefined;
7338
7324
 
7339
7325
  /**
7340
- * Resolve advisory `$attributes` for the caller-bound projection — project →
7341
- * org global-host attributes page. Cached per (client, orgId). Expected
7342
- * absences (401–404) leave the bag unbound; unexpected failures throw.
7326
+ * Resolves telemetry build or execution mode from `NODE_ENV`.
7327
+ * `production` stays `production`; `development` and `test` map to `development`.
7328
+ * Other values use the required fallback: CLI and MCP pass `production`, SDK
7329
+ * passes `development`. This does not identify the target deployment or dataset.
7330
+ * Unsupported outside the Workflows packages.
7331
+ * @internal
7332
+ */
7333
+ export declare function _resolveTelemetryEnvironment(
7334
+ nodeEnv: string | undefined,
7335
+ fallback: "development" | "production",
7336
+ ): "development" | "production";
7337
+
7338
+ /**
7339
+ * Resolve the caller's advisory `$attributes`. Results are cached per client
7340
+ * and organization. Expected absences (401–404) leave attributes undefined;
7341
+ * unexpected failures throw.
7343
7342
  * Call only from soft-gate paths (evaluate / fireAction filter re-check /
7344
7343
  * editField), never from ticks or drainers.
7345
7344
  */
@@ -7398,7 +7397,7 @@ export declare function resourceFromParsed(parsed: ParsedGdr): WorkflowResource;
7398
7397
  export declare function resourceGdr(res: WorkflowResource): string;
7399
7398
 
7400
7399
  /** Args for the single-resource ref constructors ({@link refCanvas}, {@link refMediaLibrary}, {@link refDashboard}). */
7401
- declare interface ResourceRefArgs<TType extends string> {
7400
+ export declare interface ResourceRefArgs<TType extends string> {
7402
7401
  resourceId: string;
7403
7402
  documentId: string;
7404
7403
  type: TType;
@@ -7436,35 +7435,30 @@ export declare function retractStageGuards(args: StageGuardArgs): Promise<void>;
7436
7435
  * literal ownership values and are not widened by this map. The authored `"*"`
7437
7436
  * key lists universal fulfillers and is normalized before persistence.
7438
7437
  */
7439
- export declare type RoleAliases = v.InferOutput<typeof RoleAliasesSchema>;
7438
+ export declare type RoleAliases = Record<string, string[]>;
7440
7439
 
7441
- declare const RoleAliasesSchema: v.RecordSchema<
7442
- v.SchemaWithPipe<
7443
- readonly [
7444
- v.StringSchema<undefined>,
7445
- v.MinLengthAction<string, 1, "must be a non-empty string">,
7446
- ]
7447
- >,
7448
- v.SchemaWithPipe<
7449
- readonly [
7450
- v.ArraySchema<
7451
- v.SchemaWithPipe<
7452
- readonly [
7453
- v.StringSchema<undefined>,
7454
- v.MinLengthAction<string, 1, "must be a non-empty string">,
7455
- ]
7456
- >,
7457
- undefined
7458
- >,
7459
- v.MinLengthAction<
7460
- string[],
7461
- 1,
7462
- "a role alias must list at least one fulfilling role"
7463
- >,
7464
- ]
7465
- >,
7466
- undefined
7467
- >;
7440
+ /**
7441
+ * The `runtime` block on a deployment and on `defineWorkflow`. A workflow that
7442
+ * declares none inherits its deployment's kind, and a deployment that declares
7443
+ * none hosts on `'function'`. Authoring-only: the deploy strips it and stores
7444
+ * nothing.
7445
+ *
7446
+ * It is a hint to the generator and to callers, never a rule the engine
7447
+ * enforces. The engine never sees it: any engine built anywhere with a handler
7448
+ * for an effect drains that effect when it calls `drainEffects`, whatever kind
7449
+ * the node declares, so a `'selfHosted'` effect is drained by whoever registers
7450
+ * its handler, the Studio included.
7451
+ */
7452
+ export declare interface RuntimeBlock {
7453
+ kind: RuntimeKind;
7454
+ }
7455
+
7456
+ /**
7457
+ * Where the generated unattended runtime hosts a workflow or an effect.
7458
+ * `'function'` is a plain Sanity Function, `'durableFunction'` a durable one,
7459
+ * and `'selfHosted'` a process you run yourself.
7460
+ */
7461
+ export declare type RuntimeKind = "function" | "durableFunction" | "selfHosted";
7468
7462
 
7469
7463
  /** Whether two workflow resources address the same place. */
7470
7464
  export declare function sameResource(
@@ -7472,8 +7466,15 @@ export declare function sameResource(
7472
7466
  b: WorkflowResource,
7473
7467
  ): boolean;
7474
7468
 
7475
- /** Inclusive scalar bounds. String/text bounds measure character length;
7476
- * number bounds measure the numeric value. */
7469
+ /**
7470
+ * Inclusive bounds for `string`, `text`, `number`, or `progress` values.
7471
+ * String/text bounds count characters and must be non-negative integers.
7472
+ * Number bounds are finite numeric values. Progress bounds may only narrow
7473
+ * its inclusive 0–100 range.
7474
+ *
7475
+ * Supply at least one bound. When both are present, `min` must not exceed
7476
+ * `max`. Null values remain allowed unless an input is required separately.
7477
+ */
7477
7478
  export declare interface ScalarValidation {
7478
7479
  min?: number | undefined;
7479
7480
  max?: number | undefined;
@@ -7549,6 +7550,13 @@ export declare type SignalSemantic = (typeof SIGNAL_SEMANTICS)[number];
7549
7550
  */
7550
7551
  export declare const silentLogger: EngineLogger;
7551
7552
 
7553
+ /**
7554
+ * A start requirement that rejects a fresh start when an unfinished run of
7555
+ * this definition holds the same subject, across deployed versions.
7556
+ * The workflow must declare an input-sourced `subject` field. Names are unique
7557
+ * within the requirements array. Like other engine checks, this is advisory;
7558
+ * it is not Content Lake enforcement.
7559
+ */
7552
7560
  export declare type SingleSubjectRequirement = RequirementBase & {
7553
7561
  type: "singleSubject";
7554
7562
  };
@@ -7584,6 +7592,24 @@ export declare interface SiteConsequence {
7584
7592
  after: ConditionOutcome;
7585
7593
  }
7586
7594
 
7595
+ /**
7596
+ * Suspends for `ms` before resolving. The engine's only deliberate wait is a
7597
+ * `retry` policy's backoff between attempts inside one `drainEffects` call, so
7598
+ * a deterministic harness substitutes one that moves its {@link Clock} instead
7599
+ * of spending real time. Injected once beside the clock, never per call.
7600
+ *
7601
+ * A substitute must not resolve before `ms` has passed on whatever clock the
7602
+ * engine reads: a policy's pacing and its `expiryMs` window are both judged
7603
+ * against that clock.
7604
+ */
7605
+ export declare type Sleeper = (ms: number) => Promise<void>;
7606
+
7607
+ /** Pure resource-local dereferencing for held snapshot evaluation. */
7608
+ export declare function snapshotGuardDereference(args: {
7609
+ snapshot: HydratedSnapshot;
7610
+ resource: WorkflowResource;
7611
+ }): GuardDereference;
7612
+
7587
7613
  /** One statically invalid parent-to-child spawn contract found at deploy. */
7588
7614
  export declare type SpawnContractIssue =
7589
7615
  | {
@@ -7606,16 +7632,18 @@ export declare class SpawnContractsInvalidError extends WorkflowError<"spawn-con
7606
7632
  }
7607
7633
 
7608
7634
  /**
7609
- * A pure container — name, fields, guards, activities, transitions, no
7610
- * behaviour of its own. Activities own enter, transitions own exit and
7611
- * arrival; a stage with no transitions IS terminal (structural, nothing to
7612
- * declare or mis-declare). `guards` are lake mutation guards active while
7613
- * the stage holds, each compiling to a persisted guard document deployed on
7614
- * stage entry and retracted on exit. `editable` is a tighten-only override
7615
- * for the time the stage holds, keyed by an in-scope field name: the field's
7616
- * own `editable` is the ceiling, ANDed with the stage value at runtime, so an
7617
- * override can only NARROW never open a field the baseline left closed. An
7618
- * unlisted field inherits its baseline.
7635
+ * The fields, activities, guards, and outgoing routes for one stage visit.
7636
+ * A stage with no transitions is terminal: entering it completes the instance,
7637
+ * and it cannot declare activities. Put completion work in the source stage
7638
+ * or give the working stage an outgoing transition.
7639
+ *
7640
+ * Guards are registered on entry and retracted on exit. `editable` overrides
7641
+ * are keyed by in-scope field name and apply while the stage is current.
7642
+ * Each combines with the field's own edit condition using AND, so an override
7643
+ * can restrict editing but cannot open a field whose baseline is closed.
7644
+ * An unlisted field inherits its baseline.
7645
+ *
7646
+ * @interface
7619
7647
  */
7620
7648
  export declare type Stage = StageFields<
7621
7649
  FieldEntry,
@@ -7662,7 +7690,7 @@ export declare interface StageEvaluation {
7662
7690
  autonomy: StageAutonomy;
7663
7691
  }
7664
7692
 
7665
- /** Type-mirror of {@link stageFields}, parameterised over field/activity/transition/guard/editable. */
7693
+ /** @inline */
7666
7694
  declare type StageFields<TField, TActivity, TTransition, TGuard, TEditable> = {
7667
7695
  name: string;
7668
7696
  semantics?: Semantic[] | undefined;
@@ -7676,7 +7704,7 @@ declare type StageFields<TField, TActivity, TTransition, TGuard, TEditable> = {
7676
7704
  editable?: Record<string, TEditable> | undefined;
7677
7705
  };
7678
7706
 
7679
- declare interface StageGuardArgs {
7707
+ export declare interface StageGuardArgs {
7680
7708
  client: WorkflowClient;
7681
7709
  clientForGdr: ClientForGdr;
7682
7710
  instance: WorkflowInstance;
@@ -7737,8 +7765,6 @@ export declare const START_FILTER_VARS: readonly {
7737
7765
  description: string;
7738
7766
  }[];
7739
7767
 
7740
- declare const START_KINDS: readonly ["interactive", "autonomous"];
7741
-
7742
7768
  /**
7743
7769
  * The vars a definition's start GROQ requirements read — the start-time readiness
7744
7770
  * dialect: everything the filter context binds ({@link START_FILTER_VARS})
@@ -7755,17 +7781,24 @@ export declare const START_REQUIREMENT_VARS: readonly {
7755
7781
  }[];
7756
7782
 
7757
7783
  /**
7758
- * How standalone runs of this workflow begin. `filter` is a READ-SIDE
7759
- * visibility predicate "should a start surface offer this workflow for
7760
- * this document?" evaluated by `definitionsForDocument`/applicability in
7761
- * the browse-time-pure start-filter context (`$tag`/`$definition`/`$now`
7762
- * bound; `$fields` cannot exist before inputs do, so a `$fields` read here
7763
- * is deploy-rejected). It is NOT a `startInstance` gate; the verb never
7764
- * reads it. `requirements` are named readiness checks evaluated in author
7765
- * order in the start-time context (GROQ nodes add `$fields`; `singleSubject`
7766
- * is the one-in-flight-run-per-subject rule) every node must pass before
7767
- * `startInstance` commits. Both are advisory like every engine-side check;
7768
- * the Content Lake remains the only enforcement point.
7784
+ * Discovery and readiness rules for standalone starts.
7785
+ * `filter` evaluates against a candidate document with `$tag`, `$definition`,
7786
+ * and `$now`. It controls discovery and never gates `startInstance`.
7787
+ * It cannot read `$fields` or caller variables.
7788
+ *
7789
+ * `requirements` evaluates named checks in declaration order before a fresh
7790
+ * standalone start. All must pass. Resuming an existing start and spawning
7791
+ * children do not rerun these checks. A GROQ requirement binds `$tag`,
7792
+ * `$definition`, `$now`, and `$fields`, with no candidate document root.
7793
+ * `$fields` contains supplied input values, including GDR reference envelopes;
7794
+ * it excludes computed defaults and hydrated document content.
7795
+ *
7796
+ * At both sites, `*` scans projected instances in the engine's tag. Each row
7797
+ * contains only `definition` (name), `subject` (GDR URI or null), and
7798
+ * `completedAt` (ISO timestamp or null). Completed and aborted runs are
7799
+ * included. Raw fields such as `_type`, `tag`, and `fields` are unavailable.
7800
+ * Use {@link SingleSubjectRequirement} for one unfinished run per subject.
7801
+ * These checks are advisory; the Content Lake remains the enforcement point.
7769
7802
  */
7770
7803
  export declare type StartBlock = StartFields & {
7771
7804
  kind: StartKind;
@@ -7828,6 +7861,7 @@ export declare interface StartEvaluation {
7828
7861
  invalidInitialFields: InitialFieldIssue[];
7829
7862
  }
7830
7863
 
7864
+ /** @inline */
7831
7865
  declare type StartFields = {
7832
7866
  filter?: string | undefined;
7833
7867
  requirements?: StartRequirement[] | undefined;
@@ -7836,7 +7870,7 @@ declare type StartFields = {
7836
7870
  /**
7837
7871
  * Project caller-supplied `initialFields` into the `$fields` map the
7838
7872
  * start-requirement context binds: one key per declared `input`-sourced entry,
7839
- * resolved through {@link suppliedFieldFor} — the predicate can only ever see
7873
+ * resolved through the supplied-field lookup — the predicate can only ever see
7840
7874
  * a value the input resolution would persist, and an undeclared supplied name
7841
7875
  * never leaks in. Unsupplied (or null-supplied) entries stay unbound, so a
7842
7876
  * read of one is GROQ null. Document references bind as their GDR envelopes
@@ -7870,15 +7904,19 @@ export declare interface StartInstanceArgs {
7870
7904
  initialFields?: InitialFieldValue[];
7871
7905
  ancestors?: GlobalDocumentReference[];
7872
7906
  /**
7873
- * The instance's start seed stable named values set once at start (or
7874
- * handed down by a parent's `spawn.context`) and never mutated after.
7907
+ * Stable named values supplied when starting this instance. They cannot
7908
+ * be changed after start.
7875
7909
  * Effect bindings and conditions read them as `$context.<name>`; the
7876
7910
  * `$effects` bag is separate (completed effects' outputs only).
7877
7911
  *
7878
- * Each value may be any JSON a scalar, a {@link GlobalDocumentReference},
7912
+ * Values supplied directly to start may be any JSON: a scalar,
7913
+ * a {@link GlobalDocumentReference},
7879
7914
  * or an arbitrary object/array. Scalars and GDRs store as their typed
7880
7915
  * `context` entries; anything else stores as one `context.json`
7881
7916
  * entry, so all forms read back the same under `$context.<name>`.
7917
+ * A parent's `spawn.context` has a narrower contract: only strings, numbers,
7918
+ * booleans, and full GDRs are accepted; nullish results are omitted, and
7919
+ * other objects or arrays reject the spawn.
7882
7920
  */
7883
7921
  context?: StartContext;
7884
7922
  /**
@@ -7904,15 +7942,22 @@ export declare interface StartInstanceArgs {
7904
7942
  */
7905
7943
  grantsFromPath?: string;
7906
7944
  /**
7907
- * Optional read-side perspective for this instance. Threaded into
7908
- * field-entry query resolution and spawn `forEach.groq` discovery so
7909
- * a workflow can scope its reads to a Content Release stack. Child
7910
- * instances inherit the parent's perspective on spawn.
7945
+ * Perspective for content reads, including field queries and subworkflow
7946
+ * discovery. An explicit value applies to workflow-field initialization
7947
+ * and subsequent reads.
7948
+ *
7949
+ * When omitted, workflow-field queries at start use `drafts`. After those
7950
+ * fields resolve, the instance uses `[releaseName]` from its first populated
7951
+ * workflow `release.ref` field, or `drafts` when none is populated.
7952
+ * Under `drafts`, drafts take precedence over published content.
7953
+ *
7954
+ * A child's workflow fields initialize under its parent's perspective.
7955
+ * Afterward, the child's first populated workflow `release.ref` field
7956
+ * selects its release perspective; otherwise it inherits the parent's.
7911
7957
  *
7912
- * Pass `[releaseName]` for a workflow whose subject is a release;
7913
- * pass `[releaseName, "drafts"]` to also include drafts; omit for
7914
- * the engine's default (no perspective override = `"raw"` on the
7915
- * test client).
7958
+ * Pass `[releaseName]` to read under a Content Release, or
7959
+ * `[releaseName, 'drafts']` to include drafts. Engine-owned instance and
7960
+ * definition documents, and `system.release` documents, always read under `raw`.
7916
7961
  */
7917
7962
  perspective?: WorkflowPerspective;
7918
7963
  }
@@ -7926,7 +7971,7 @@ export declare interface StartInstanceArgs {
7926
7971
  * path for every kind, and an interactive start of an autonomous workflow is
7927
7972
  * legal.
7928
7973
  */
7929
- export declare type StartKind = (typeof START_KINDS)[number];
7974
+ export declare type StartKind = "interactive" | "autonomous";
7930
7975
 
7931
7976
  /**
7932
7977
  * The declared {@link StartKind} of a definition, defaulting the absent
@@ -7996,282 +8041,65 @@ export declare class StartNotSettledError extends WorkflowError<"start-not-settl
7996
8041
  /** Advisory only, per {@link isStartableDefinition} — a start surface has no parent context to give a spawn-only child, so it rejects fast with this message instead. */
7997
8042
  export declare function startRefusal(definition: {
7998
8043
  lifecycle?: WorkflowLifecycle | undefined;
7999
- }): string | undefined;
8000
-
8001
- /** Every named readiness requirement accepted by workflow `start.requirements`. */
8002
- export declare type StartRequirement =
8003
- | GroqRequirement
8004
- | SingleSubjectRequirement;
8005
-
8006
- export declare interface StartRequirementEvaluation extends RequirementDescriptor {
8007
- /** Whether this requirement is satisfied, unsatisfied, or not yet decidable. */
8008
- outcome: ConditionOutcome;
8009
- /** GROQ explanation; absent for non-GROQ requirement kinds. */
8010
- insight?: ConditionInsight | undefined;
8011
- }
8012
-
8013
- /**
8014
- * The caller-side half of the start contexts — everything the evaluating
8015
- * surface knows that the definition doesn't. Every member is optional
8016
- * because the surfaces genuinely differ (a pure consumer may hold no clock):
8017
- * An absent binding evaluates each read of it to GROQ null, and where that
8018
- * null lands decides the verdict — a predicate that can't decide without
8019
- * the binding fails closed, while a count-of-matches clause over values
8020
- * every row stores passes vacuously (in GROQ null equals only null, so the
8021
- * unbound read matches no stored value). The vars themselves are
8022
- * inventoried in `START_FILTER_VARS` / `START_REQUIREMENT_VARS`; the caller's
8023
- * `$fields` map is NOT scope — `start.filter` never binds it, and
8024
- * `explainStartRequirement` takes it as its own argument.
8025
- */
8026
- export declare interface StartScope {
8027
- /** The engine's tag partition — binds `$tag`. */
8028
- tag?: string | undefined;
8029
- /** ISO clock reading — binds `$now`. */
8030
- now?: string | undefined;
8031
- /** Resource-qualified identity of the prospective subject. Unlike a loaded
8032
- * document's bare `_id`, this stays collision-free across resources. */
8033
- subject?: GdrUri | undefined;
8034
- /**
8035
- * The engine-owned start slice, for predicates that read `*[...]` or for a
8036
- * `singleSubject` requirement — invoked lazily only when evaluation needs it.
8037
- * Each row exposes exactly `{definition, subject, completedAt}`; completed
8038
- * rows are included, so authors qualify in-flight
8039
- * themselves (`!defined(completedAt)`). Absent ⇒ a dataset-reading filter
8040
- * fails closed (this surface cannot see the dataset, so it cannot decide),
8041
- * while a dataset-reading requirement THROWS — see
8042
- * {@link explainStartRequirement}.
8043
- */
8044
- fetchDataset?: (() => Promise<unknown[]>) | undefined;
8045
- }
8046
-
8047
- export declare interface StartSliceRow {
8048
- definition: string;
8049
- subject: GdrUri | null;
8050
- completedAt: string | null;
8051
- }
8052
-
8053
- declare const StoredEditableSchema: v.UnionSchema<
8054
- [
8055
- v.LiteralSchema<true, undefined>,
8056
- v.SchemaWithPipe<
8057
- readonly [
8058
- v.StringSchema<undefined>,
8059
- v.MinLengthAction<string, 1, "must be a non-empty string">,
8060
- ]
8061
- >,
8062
- ],
8063
- undefined
8064
- >;
8065
-
8066
- /**
8067
- * The `field.*` subset — every mutation op EXCEPT `status.set`. Shared by the
8068
- * boundaries that write fields but must not set an activity status: a transition
8069
- * (its stage's activities are tearing down, so `status.set` has no coherent
8070
- * target) and an effect's completion (an effect is OUTSIDE the activity's own
8071
- * awaiting — it reports its result through fields, never by flipping a status;
8072
- * the activity/stage gate then reads those fields). The full {@link StoredOpSchema}
8073
- * (these plus `status.set`) is what actions and activity boundaries carry.
8074
- */
8075
- declare const StoredFieldOpSchema: v.VariantSchema<
8076
- "type",
8077
- [
8078
- v.StrictObjectSchema<
8079
- {
8080
- readonly type: v.LiteralSchema<"field.set", undefined>;
8081
- readonly target: v.StrictObjectSchema<
8082
- {
8083
- readonly scope: v.PicklistSchema<
8084
- readonly ["workflow", "stage", "activity"],
8085
- string
8086
- >;
8087
- readonly field: v.SchemaWithPipe<
8088
- readonly [
8089
- v.StringSchema<undefined>,
8090
- v.MinLengthAction<string, 1, "must be a non-empty string">,
8091
- ]
8092
- >;
8093
- },
8094
- undefined
8095
- >;
8096
- readonly value: v.GenericSchema<ValueExprInternal>;
8097
- },
8098
- undefined
8099
- >,
8100
- v.StrictObjectSchema<
8101
- {
8102
- readonly type: v.LiteralSchema<"field.setIfMissing", undefined>;
8103
- readonly target: v.StrictObjectSchema<
8104
- {
8105
- readonly scope: v.PicklistSchema<
8106
- readonly ["workflow", "stage", "activity"],
8107
- string
8108
- >;
8109
- readonly field: v.SchemaWithPipe<
8110
- readonly [
8111
- v.StringSchema<undefined>,
8112
- v.MinLengthAction<string, 1, "must be a non-empty string">,
8113
- ]
8114
- >;
8115
- },
8116
- undefined
8117
- >;
8118
- readonly value: v.GenericSchema<ValueExprInternal>;
8119
- },
8120
- undefined
8121
- >,
8122
- v.StrictObjectSchema<
8123
- {
8124
- readonly type: v.LiteralSchema<"field.unset", undefined>;
8125
- readonly target: v.StrictObjectSchema<
8126
- {
8127
- readonly scope: v.PicklistSchema<
8128
- readonly ["workflow", "stage", "activity"],
8129
- string
8130
- >;
8131
- readonly field: v.SchemaWithPipe<
8132
- readonly [
8133
- v.StringSchema<undefined>,
8134
- v.MinLengthAction<string, 1, "must be a non-empty string">,
8135
- ]
8136
- >;
8137
- },
8138
- undefined
8139
- >;
8140
- },
8141
- undefined
8142
- >,
8143
- v.StrictObjectSchema<
8144
- {
8145
- readonly type: v.LiteralSchema<"field.append", undefined>;
8146
- readonly target: v.StrictObjectSchema<
8147
- {
8148
- readonly scope: v.PicklistSchema<
8149
- readonly ["workflow", "stage", "activity"],
8150
- string
8151
- >;
8152
- readonly field: v.SchemaWithPipe<
8153
- readonly [
8154
- v.StringSchema<undefined>,
8155
- v.MinLengthAction<string, 1, "must be a non-empty string">,
8156
- ]
8157
- >;
8158
- },
8159
- undefined
8160
- >;
8161
- readonly value: v.GenericSchema<ValueExprInternal>;
8162
- },
8163
- undefined
8164
- >,
8165
- v.StrictObjectSchema<
8166
- {
8167
- readonly type: v.LiteralSchema<"field.inc", undefined>;
8168
- readonly target: v.StrictObjectSchema<
8169
- {
8170
- readonly scope: v.PicklistSchema<
8171
- readonly ["workflow", "stage", "activity"],
8172
- string
8173
- >;
8174
- readonly field: v.SchemaWithPipe<
8175
- readonly [
8176
- v.StringSchema<undefined>,
8177
- v.MinLengthAction<string, 1, "must be a non-empty string">,
8178
- ]
8179
- >;
8180
- },
8181
- undefined
8182
- >;
8183
- readonly value: v.OptionalSchema<
8184
- v.GenericSchema<ValueExprInternal>,
8185
- undefined
8186
- >;
8187
- },
8188
- undefined
8189
- >,
8190
- v.StrictObjectSchema<
8191
- {
8192
- readonly type: v.LiteralSchema<"field.dec", undefined>;
8193
- readonly target: v.StrictObjectSchema<
8194
- {
8195
- readonly scope: v.PicklistSchema<
8196
- readonly ["workflow", "stage", "activity"],
8197
- string
8198
- >;
8199
- readonly field: v.SchemaWithPipe<
8200
- readonly [
8201
- v.StringSchema<undefined>,
8202
- v.MinLengthAction<string, 1, "must be a non-empty string">,
8203
- ]
8204
- >;
8205
- },
8206
- undefined
8207
- >;
8208
- readonly value: v.OptionalSchema<
8209
- v.GenericSchema<ValueExprInternal>,
8210
- undefined
8211
- >;
8212
- },
8213
- undefined
8214
- >,
8215
- v.StrictObjectSchema<
8216
- {
8217
- readonly type: v.LiteralSchema<"field.updateWhere", undefined>;
8218
- readonly target: v.StrictObjectSchema<
8219
- {
8220
- readonly scope: v.PicklistSchema<
8221
- readonly ["workflow", "stage", "activity"],
8222
- string
8223
- >;
8224
- readonly field: v.SchemaWithPipe<
8225
- readonly [
8226
- v.StringSchema<undefined>,
8227
- v.MinLengthAction<string, 1, "must be a non-empty string">,
8228
- ]
8229
- >;
8230
- },
8231
- undefined
8232
- >;
8233
- readonly where: v.SchemaWithPipe<
8234
- readonly [
8235
- v.StringSchema<undefined>,
8236
- v.MinLengthAction<string, 1, "must be a non-empty string">,
8237
- ]
8238
- >;
8239
- readonly value: v.GenericSchema<ValueExprInternal>;
8240
- },
8241
- undefined
8242
- >,
8243
- v.StrictObjectSchema<
8244
- {
8245
- readonly type: v.LiteralSchema<"field.removeWhere", undefined>;
8246
- readonly target: v.StrictObjectSchema<
8247
- {
8248
- readonly scope: v.PicklistSchema<
8249
- readonly ["workflow", "stage", "activity"],
8250
- string
8251
- >;
8252
- readonly field: v.SchemaWithPipe<
8253
- readonly [
8254
- v.StringSchema<undefined>,
8255
- v.MinLengthAction<string, 1, "must be a non-empty string">,
8256
- ]
8257
- >;
8258
- },
8259
- undefined
8260
- >;
8261
- readonly where: v.SchemaWithPipe<
8262
- readonly [
8263
- v.StringSchema<undefined>,
8264
- v.MinLengthAction<string, 1, "must be a non-empty string">,
8265
- ]
8266
- >;
8267
- },
8268
- undefined
8269
- >,
8270
- ],
8271
- undefined
8272
- >;
8044
+ }): string | undefined;
8045
+
8046
+ /** Every named readiness requirement accepted by workflow `start.requirements`. */
8047
+ export declare type StartRequirement =
8048
+ | GroqRequirement
8049
+ | SingleSubjectRequirement;
8050
+
8051
+ export declare interface StartRequirementEvaluation extends RequirementDescriptor {
8052
+ /** Whether this requirement is satisfied, unsatisfied, or not yet decidable. */
8053
+ outcome: ConditionOutcome;
8054
+ /** GROQ explanation; absent for non-GROQ requirement kinds. */
8055
+ insight?: ConditionInsight | undefined;
8056
+ }
8057
+
8058
+ /**
8059
+ * The caller-side half of the start contexts — everything the evaluating
8060
+ * surface knows that the definition doesn't. Every member is optional
8061
+ * because the surfaces genuinely differ (a pure consumer may hold no clock):
8062
+ * An absent binding evaluates each read of it to GROQ null, and where that
8063
+ * null lands decides the verdict — a predicate that can't decide without
8064
+ * the binding fails closed, while a count-of-matches clause over values
8065
+ * every row stores passes vacuously (in GROQ null equals only null, so the
8066
+ * unbound read matches no stored value). The vars themselves are
8067
+ * inventoried in `START_FILTER_VARS` / `START_REQUIREMENT_VARS`; the caller's
8068
+ * `$fields` map is NOT scope — `start.filter` never binds it, and
8069
+ * `explainStartRequirement` takes it as its own argument.
8070
+ */
8071
+ export declare interface StartScope {
8072
+ /** The engine's tag partition — binds `$tag`. */
8073
+ tag?: string | undefined;
8074
+ /** ISO clock reading — binds `$now`. */
8075
+ now?: string | undefined;
8076
+ /** Resource-qualified identity of the prospective subject. Unlike a loaded
8077
+ * document's bare `_id`, this stays collision-free across resources. */
8078
+ subject?: GdrUri | undefined;
8079
+ /**
8080
+ * The engine-owned start slice, for predicates that read `*[...]` or for a
8081
+ * `singleSubject` requirement — invoked lazily only when evaluation needs it.
8082
+ * Each row exposes exactly `{definition, subject, completedAt}`; completed
8083
+ * rows are included, so authors qualify in-flight
8084
+ * themselves (`!defined(completedAt)`). Absent ⇒ a dataset-reading filter
8085
+ * fails closed (this surface cannot see the dataset, so it cannot decide),
8086
+ * while a dataset-reading requirement THROWS — see
8087
+ * {@link explainStartRequirement}.
8088
+ */
8089
+ fetchDataset?: (() => Promise<unknown[]>) | undefined;
8090
+ }
8091
+
8092
+ export declare interface StartSliceRow {
8093
+ definition: string;
8094
+ subject: GdrUri | null;
8095
+ completedAt: string | null;
8096
+ }
8273
8097
 
8274
- /** A field reference with `scope` already resolved — the form every op target carries. */
8098
+ /**
8099
+ * A field reference with `scope` already resolved — the form every op target carries.
8100
+ *
8101
+ * @interface
8102
+ */
8275
8103
  export declare type StoredFieldRef = v.InferOutput<typeof StoredFieldRefSchema>;
8276
8104
 
8277
8105
  declare const StoredFieldRefSchema: v.StrictObjectSchema<
@@ -8290,273 +8118,16 @@ declare const StoredFieldRefSchema: v.StrictObjectSchema<
8290
8118
  undefined
8291
8119
  >;
8292
8120
 
8293
- declare const StoredManualTargetSchema: v.VariantSchema<
8294
- "type",
8295
- [
8296
- v.StrictObjectSchema<
8297
- {
8298
- readonly type: v.LiteralSchema<"url", undefined>;
8299
- readonly url: v.SchemaWithPipe<
8300
- readonly [
8301
- v.StringSchema<undefined>,
8302
- v.UrlAction<string, "must be a valid URL">,
8303
- v.CheckAction<string, "must be an http(s) URL">,
8304
- ]
8305
- >;
8306
- },
8307
- undefined
8308
- >,
8309
- v.StrictObjectSchema<
8310
- {
8311
- readonly type: v.LiteralSchema<"field", undefined>;
8312
- readonly field: v.StrictObjectSchema<
8313
- {
8314
- readonly scope: v.PicklistSchema<
8315
- readonly ["workflow", "stage", "activity"],
8316
- string
8317
- >;
8318
- readonly field: v.SchemaWithPipe<
8319
- readonly [
8320
- v.StringSchema<undefined>,
8321
- v.MinLengthAction<string, 1, "must be a non-empty string">,
8322
- ]
8323
- >;
8324
- },
8325
- undefined
8326
- >;
8327
- },
8328
- undefined
8329
- >,
8330
- ],
8331
- undefined
8332
- >;
8333
-
8334
- declare const StoredOpSchema: v.VariantSchema<
8335
- "type",
8336
- [
8337
- v.StrictObjectSchema<
8338
- {
8339
- readonly type: v.LiteralSchema<"field.set", undefined>;
8340
- readonly target: v.StrictObjectSchema<
8341
- {
8342
- readonly scope: v.PicklistSchema<
8343
- readonly ["workflow", "stage", "activity"],
8344
- string
8345
- >;
8346
- readonly field: v.SchemaWithPipe<
8347
- readonly [
8348
- v.StringSchema<undefined>,
8349
- v.MinLengthAction<string, 1, "must be a non-empty string">,
8350
- ]
8351
- >;
8352
- },
8353
- undefined
8354
- >;
8355
- readonly value: v.GenericSchema<ValueExprInternal>;
8356
- },
8357
- undefined
8358
- >,
8359
- v.StrictObjectSchema<
8360
- {
8361
- readonly type: v.LiteralSchema<"field.setIfMissing", undefined>;
8362
- readonly target: v.StrictObjectSchema<
8363
- {
8364
- readonly scope: v.PicklistSchema<
8365
- readonly ["workflow", "stage", "activity"],
8366
- string
8367
- >;
8368
- readonly field: v.SchemaWithPipe<
8369
- readonly [
8370
- v.StringSchema<undefined>,
8371
- v.MinLengthAction<string, 1, "must be a non-empty string">,
8372
- ]
8373
- >;
8374
- },
8375
- undefined
8376
- >;
8377
- readonly value: v.GenericSchema<ValueExprInternal>;
8378
- },
8379
- undefined
8380
- >,
8381
- v.StrictObjectSchema<
8382
- {
8383
- readonly type: v.LiteralSchema<"field.unset", undefined>;
8384
- readonly target: v.StrictObjectSchema<
8385
- {
8386
- readonly scope: v.PicklistSchema<
8387
- readonly ["workflow", "stage", "activity"],
8388
- string
8389
- >;
8390
- readonly field: v.SchemaWithPipe<
8391
- readonly [
8392
- v.StringSchema<undefined>,
8393
- v.MinLengthAction<string, 1, "must be a non-empty string">,
8394
- ]
8395
- >;
8396
- },
8397
- undefined
8398
- >;
8399
- },
8400
- undefined
8401
- >,
8402
- v.StrictObjectSchema<
8403
- {
8404
- readonly type: v.LiteralSchema<"field.append", undefined>;
8405
- readonly target: v.StrictObjectSchema<
8406
- {
8407
- readonly scope: v.PicklistSchema<
8408
- readonly ["workflow", "stage", "activity"],
8409
- string
8410
- >;
8411
- readonly field: v.SchemaWithPipe<
8412
- readonly [
8413
- v.StringSchema<undefined>,
8414
- v.MinLengthAction<string, 1, "must be a non-empty string">,
8415
- ]
8416
- >;
8417
- },
8418
- undefined
8419
- >;
8420
- readonly value: v.GenericSchema<ValueExprInternal>;
8421
- },
8422
- undefined
8423
- >,
8424
- v.StrictObjectSchema<
8425
- {
8426
- readonly type: v.LiteralSchema<"field.inc", undefined>;
8427
- readonly target: v.StrictObjectSchema<
8428
- {
8429
- readonly scope: v.PicklistSchema<
8430
- readonly ["workflow", "stage", "activity"],
8431
- string
8432
- >;
8433
- readonly field: v.SchemaWithPipe<
8434
- readonly [
8435
- v.StringSchema<undefined>,
8436
- v.MinLengthAction<string, 1, "must be a non-empty string">,
8437
- ]
8438
- >;
8439
- },
8440
- undefined
8441
- >;
8442
- readonly value: v.OptionalSchema<
8443
- v.GenericSchema<ValueExprInternal>,
8444
- undefined
8445
- >;
8446
- },
8447
- undefined
8448
- >,
8449
- v.StrictObjectSchema<
8450
- {
8451
- readonly type: v.LiteralSchema<"field.dec", undefined>;
8452
- readonly target: v.StrictObjectSchema<
8453
- {
8454
- readonly scope: v.PicklistSchema<
8455
- readonly ["workflow", "stage", "activity"],
8456
- string
8457
- >;
8458
- readonly field: v.SchemaWithPipe<
8459
- readonly [
8460
- v.StringSchema<undefined>,
8461
- v.MinLengthAction<string, 1, "must be a non-empty string">,
8462
- ]
8463
- >;
8464
- },
8465
- undefined
8466
- >;
8467
- readonly value: v.OptionalSchema<
8468
- v.GenericSchema<ValueExprInternal>,
8469
- undefined
8470
- >;
8471
- },
8472
- undefined
8473
- >,
8474
- v.StrictObjectSchema<
8475
- {
8476
- readonly type: v.LiteralSchema<"field.updateWhere", undefined>;
8477
- readonly target: v.StrictObjectSchema<
8478
- {
8479
- readonly scope: v.PicklistSchema<
8480
- readonly ["workflow", "stage", "activity"],
8481
- string
8482
- >;
8483
- readonly field: v.SchemaWithPipe<
8484
- readonly [
8485
- v.StringSchema<undefined>,
8486
- v.MinLengthAction<string, 1, "must be a non-empty string">,
8487
- ]
8488
- >;
8489
- },
8490
- undefined
8491
- >;
8492
- readonly where: v.SchemaWithPipe<
8493
- readonly [
8494
- v.StringSchema<undefined>,
8495
- v.MinLengthAction<string, 1, "must be a non-empty string">,
8496
- ]
8497
- >;
8498
- readonly value: v.GenericSchema<ValueExprInternal>;
8499
- },
8500
- undefined
8501
- >,
8502
- v.StrictObjectSchema<
8503
- {
8504
- readonly type: v.LiteralSchema<"field.removeWhere", undefined>;
8505
- readonly target: v.StrictObjectSchema<
8506
- {
8507
- readonly scope: v.PicklistSchema<
8508
- readonly ["workflow", "stage", "activity"],
8509
- string
8510
- >;
8511
- readonly field: v.SchemaWithPipe<
8512
- readonly [
8513
- v.StringSchema<undefined>,
8514
- v.MinLengthAction<string, 1, "must be a non-empty string">,
8515
- ]
8516
- >;
8517
- },
8518
- undefined
8519
- >;
8520
- readonly where: v.SchemaWithPipe<
8521
- readonly [
8522
- v.StringSchema<undefined>,
8523
- v.MinLengthAction<string, 1, "must be a non-empty string">,
8524
- ]
8525
- >;
8526
- },
8527
- undefined
8528
- >,
8529
- v.StrictObjectSchema<
8530
- {
8531
- readonly type: v.LiteralSchema<"status.set", undefined>;
8532
- readonly activity: v.SchemaWithPipe<
8533
- readonly [
8534
- v.StringSchema<undefined>,
8535
- v.MinLengthAction<string, 1, "must be a non-empty string">,
8536
- ]
8537
- >;
8538
- readonly status: v.PicklistSchema<
8539
- readonly ["active", "done", "skipped", "failed"],
8540
- string
8541
- >;
8542
- },
8543
- undefined
8544
- >,
8545
- ],
8546
- undefined
8547
- >;
8548
-
8549
8121
  export declare function stripSystemFields(
8550
8122
  doc: Record<string, unknown>,
8551
8123
  ): Record<string, unknown>;
8552
8124
 
8553
8125
  /**
8554
- * Why an in-flight instance is genuinely blocked — nothing advances it on its
8555
- * own OR via a normal action. Ordered most- to least-actionable in
8556
- * {@link diagnoseInstance}: a failed effect is the root cause even when it left
8557
- * its activity looking merely "active", so it wins over the activity- and
8558
- * transition-level symptoms it produces. Note an active activity awaiting a human
8559
- * action is NOT here — that's the healthy {@link Diagnosis} `waiting` state.
8126
+ * A fault or missing dependency in an in-flight instance. Missing documents
8127
+ * follow effect/activity faults and precede transition faults. The diagnosis
8128
+ * is advisory: it does not prohibit actions that can still run.
8129
+ * An active activity awaiting a human action is the healthy
8130
+ * {@link Diagnosis} `waiting` state.
8560
8131
  *
8561
8132
  * `transition-unevaluable` is the recoverable arm: every activity resolved,
8562
8133
  * but an exit transition's `when` came back GROQ `null` (a referenced operand
@@ -8565,6 +8136,10 @@ export declare function stripSystemFields(
8565
8136
  * definite `false`. It carries the undecidable transitions.
8566
8137
  */
8567
8138
  export declare type StuckCause =
8139
+ | {
8140
+ kind: "document-missing";
8141
+ documents: MissingDocument[];
8142
+ }
8568
8143
  | {
8569
8144
  kind: "failed-effect";
8570
8145
  effect: EffectHistoryEntry;
@@ -8609,7 +8184,7 @@ export declare interface SubjectPermissionDenial {
8609
8184
  permission: DocumentValuePermission;
8610
8185
  }
8611
8186
 
8612
- declare interface SubjectResourceAccess {
8187
+ export declare interface SubjectResourceAccess {
8613
8188
  grants: Grant[];
8614
8189
  /** The actor's principal id in this resource's own namespace: per-project user id for a dataset resource, account-global id for an org-level one. */
8615
8190
  actorId: string;
@@ -8719,17 +8294,29 @@ export declare interface SubworkflowEntry {
8719
8294
  }
8720
8295
 
8721
8296
  /**
8722
- * Fan-out declared as an action's `spawn`, read back as `$subworkflows`.
8723
- * `forEach` is GROQ producing one row per subworkflow (bound as `$row`); each
8724
- * row needs an identity the engine can adopt on re-entry (`_key` ?? `_id` ??
8725
- * GDR `id`, or the value itself for a scalar row) or the spawn fails.
8726
- * `definition` resolves by stable `name`, ordered `version desc` unless
8727
- * pinned. `with` seeds each child's initial fields; `context` delivers extra
8728
- * parent-scope values into the child's `$context`. `onExit` governs only
8729
- * still-live children when the cohort's scope stops applying: `'detach'`
8730
- * (default) lets them run to completion, `'abort'` kills them recursively —
8731
- * always an authored choice, never automatic. Whether the PARENT may move at
8732
- * all is a separate gate over `$subworkflows`.
8297
+ * Child workflows created by an action's `spawn`, exposed as `$subworkflows`.
8298
+ * `definition` selects the highest deployed version unless a version is pinned.
8299
+ *
8300
+ * `forEach` evaluates with workflow fields only and no caller variables, even
8301
+ * for a caller-fired action. Rows need unique identities: a nonempty `_key`,
8302
+ * then `_id`, then a GDR's `id`, or a scalar's string representation.
8303
+ * Missing or duplicate identities reject the spawn. Re-entry adopts matching
8304
+ * live children from the same activity, action, and definition instead of
8305
+ * duplicating them.
8306
+ *
8307
+ * `with` maps child input-field names to expressions evaluated with `$row`.
8308
+ * `context` evaluates once without `$row` and supplies the child's `$context`.
8309
+ * Both use the parent activity's field scope and the acting identity when
8310
+ * available. Neither binds `$can`, `$attributes`, or `$params`.
8311
+ * Context results must be strings, numbers, booleans, or full GDRs; null and
8312
+ * undefined omit the entry. Other objects and arrays reject the spawn.
8313
+ *
8314
+ * `onExit` governs live children when their cohort leaves scope: `detach`
8315
+ * (the default) leaves them running; `abort` stops them recursively. Aborting
8316
+ * the parent always stops its children. Parent transitions must separately
8317
+ * declare whether they wait for the cohort to settle.
8318
+ *
8319
+ * @interface
8733
8320
  */
8734
8321
  export declare type Subworkflows = v.InferOutput<typeof SubworkflowsSchema>;
8735
8322
 
@@ -8861,13 +8448,15 @@ export declare const SYSTEM_IDENTITY = "<system>";
8861
8448
  export declare function tagScopeFilter(): string;
8862
8449
 
8863
8450
  /**
8864
- * Internal telemetry-injection seam for the raw `workflow.*` verbs — the
8865
- * telemetry twin of the `Clocked` seam in `clock.ts`, deliberately not
8866
- * re-exported from the package root. Production injects a logger ONCE via
8867
- * `createEngine({ telemetry })`; a raw-namespace caller that omits it
8868
- * emits nothing (the verbs default to {@link noopTelemetry}).
8451
+ * Optional telemetry-injection field on the raw `workflow.*` verbs — the
8452
+ * telemetry twin of the `Clocked` seam in `clock.ts`. It is exported
8453
+ * because those verbs expose this composition helper in their public
8454
+ * signatures, but production normally injects a logger once via
8455
+ * `createEngine({ telemetry })`, not as an everyday per-call option. A
8456
+ * raw-namespace caller that omits it emits nothing (the verbs default to
8457
+ * {@link noopTelemetry}).
8869
8458
  */
8870
- declare type Telemetered<T> = T & {
8459
+ export declare type Telemetered<T> = T & {
8871
8460
  telemetry?: WorkflowTelemetryLogger;
8872
8461
  };
8873
8462
 
@@ -8897,7 +8486,7 @@ export declare interface TelemetryIntake {
8897
8486
  * closes the socket (a `Promise.race` alone cannot). */
8898
8487
  export declare interface TelemetryIntakeClient {
8899
8488
  request: <T>(opts: {
8900
- uri: string;
8489
+ url: string;
8901
8490
  method?: string;
8902
8491
  body?: unknown;
8903
8492
  tag?: string;
@@ -8913,14 +8502,7 @@ export declare interface TelemetryIntakeClient {
8913
8502
  * `$allActivitiesDone` — a `failed` activity blocks it permanently, surfacing
8914
8503
  * via `$anyActivityFailed`.
8915
8504
  */
8916
- declare const TERMINAL_ACTIVITY_STATUSES: readonly [
8917
- "done",
8918
- "skipped",
8919
- "failed",
8920
- ];
8921
-
8922
- export declare type TerminalActivityStatus =
8923
- (typeof TERMINAL_ACTIVITY_STATUSES)[number];
8505
+ export declare type TerminalActivityStatus = "done" | "skipped" | "failed";
8924
8506
 
8925
8507
  /** See {@link terminalState}. */
8926
8508
  export declare type TerminalState = "aborted" | "completed" | "in-flight";
@@ -8943,8 +8525,7 @@ export declare function terminalState(
8943
8525
  */
8944
8526
  export declare function toBareId(id: string): string;
8945
8527
 
8946
- /** Ad-hoc, status-tracked work items: sugar over `array of object {label, status, assignee?, dueDate?}`; a plain checklist is that with `{label, status}` alone.
8947
- * Its `dueDate` is a `date` column named `dueDate`, not the elevated `dueDate` kind, which reserves one deadline slot per level. Never a stored kind. */
8528
+ /** @inline */
8948
8529
  declare type TodoListField = FieldBase<AuthoringEditable, GroupMembership> & {
8949
8530
  type: "todoList";
8950
8531
  };
@@ -8962,19 +8543,20 @@ export declare interface TodoListItem {
8962
8543
  _key: string;
8963
8544
  label: string;
8964
8545
  status?: string | null;
8965
- assignee?: Assignee | null;
8546
+ /** Singular assignment slot: any number of routing roles and at most one user. */
8547
+ assignee?: Assignee[];
8966
8548
  dueDate?: string | null;
8967
8549
  }
8968
8550
 
8969
8551
  /**
8970
- * A pure edge — `{name, when, to}` plus presentation, no ops or effects
8971
- * (structure never does; only actions do). Every transition is evaluated on
8972
- * every commit and cascade; the first truthy `when` in declaration order
8973
- * fires. No action coupling: a routing difference is written into fields by
8974
- * an action and read by the trigger — arrival work is a `when: 'true'`
8975
- * action in the destination stage, and exit work is an action in the source
8976
- * stage whose `when` repeats this transition's condition (the hop rule
8977
- * guarantees it commits before the move).
8552
+ * A one-way route to another stage, without operations or effects. Selection
8553
+ * checks `when` conditions in declaration order. The first satisfied condition
8554
+ * fires; an earlier unevaluable condition, such as GROQ null, stops selection
8555
+ * without considering later routes. A false condition permits the next route.
8556
+ *
8557
+ * Actions write routing decisions into fields; transitions read that state.
8558
+ * Source-stage triggered actions run before transition selection. Arrival work
8559
+ * belongs to a triggered action in a nonterminal destination stage.
8978
8560
  */
8979
8561
  export declare type Transition = TransitionFields & {
8980
8562
  when: string;
@@ -9003,8 +8585,7 @@ export declare interface TransitionEvaluation {
9003
8585
  insight: ConditionInsight;
9004
8586
  }
9005
8587
 
9006
- /** Type-mirror of {@link transitionFields} minus `when` — stored requires it,
9007
- * authoring omits it (desugar fills the default), so each variant declares it. */
8588
+ /** @inline */
9008
8589
  declare type TransitionFields = {
9009
8590
  name: string;
9010
8591
  title?: string | undefined;
@@ -9094,19 +8675,28 @@ export declare function validateDefinition(
9094
8675
 
9095
8676
  export declare function validateTag(tag: string): void;
9096
8677
 
9097
- declare interface ValidationIssue {
8678
+ export declare interface ValidationIssue {
9098
8679
  path: ReadonlyArray<PropertyKey>;
9099
8680
  message: string;
9100
8681
  }
9101
8682
 
9102
8683
  /**
9103
- * An op's write payload, resolved to concrete JSON when the op applies. Each
9104
- * context-bound arm has a rendered `$`-twin in conditions (`actor`
9105
- * `$actor`, `now` `$now`, `self` `$self`), so learning one side teaches
9106
- * the other. Distinct from {@link FieldSource}, a field's seed recipe.
8684
+ * An operation's write value, resolved when the operation applies.
8685
+ * `param` reads a caller-supplied action argument; `actor` records the acting
8686
+ * identity. `now` supplies the operation's ISO timestamp, `self` its instance's
8687
+ * GDR URI, and `stage` the current stage name. `object` resolves its fields
8688
+ * recursively.
8689
+ *
8690
+ * A `fieldRead` with no scope searches activity, stage, then workflow fields.
8691
+ * An explicit scope searches only that scope. A pathless read from a subject
8692
+ * or `doc.ref` into another subject or `doc.ref` preserves the stored reference.
8693
+ * Other reads use the referenced snapshot document, or only its `_id` and
8694
+ * `_type` when it is not loaded. No additional documents are fetched.
8695
+ * Initialization uses {@link FieldSource}, whose field-read scope rules differ.
9107
8696
  */
9108
8697
  export declare type ValueExpr = ValueExprInternal;
9109
8698
 
8699
+ /** @inline */
9110
8700
  declare type ValueExprInternal =
9111
8701
  | LiteralExpr
9112
8702
  | FieldReadExpr
@@ -9207,17 +8797,20 @@ export { withAssignment };
9207
8797
 
9208
8798
  export declare const workflow: {
9209
8799
  /**
9210
- * Deploy a set of definitions as one call. Definitions are immutable and
9211
- * content-addressed: the author writes no version, identical content no-ops
9212
- * (`unchanged`), and any change mints the next version (`created`) — deploy
9213
- * never patches a deployed version out from under the instances pinned to it.
9214
- * The engine orders the batch itself (children before the parents that spawn
9215
- * them). Refs may point inside the batch or at already-deployed definitions;
9216
- * a ref resolving to neither, or a cycle, errors before any write. Input is
9217
- * authored content or a fetched definition document the document envelope
9218
- * (`_*` system fields, `tag`, `version`, `contentHash`) is stripped at the
9219
- * boundary and never fingerprinted, so a fetched document redeploys as
9220
- * `unchanged`; any other unknown key fails loud.
8800
+ * Deploys immutable definition versions. The engine assigns each version:
8801
+ * content matching the latest deployed fingerprint returns `unchanged`;
8802
+ * otherwise deployment creates the next version and returns `created`.
8803
+ * Redeploying older content creates a new version; existing versions and
8804
+ * their pinned instances are unchanged.
8805
+ *
8806
+ * Children deploy before parents. References may resolve within the batch
8807
+ * or to deployed definitions; unresolved references and cycles reject the
8808
+ * batch before any write.
8809
+ *
8810
+ * Accepts authored content or a fetched definition document. The document
8811
+ * envelope (`_*` system fields, `tag`, `version`, `contentHash`) is excluded
8812
+ * from the fingerprint. Fetched content follows the same latest-version
8813
+ * comparison; any other unknown input key is rejected.
9221
8814
  */
9222
8815
  deployDefinitions: <T extends WorkflowDefinitionInput<T>>(
9223
8816
  rawArgs: Telemetered<DeployDefinitionsArgs<T> & EngineScopeArgs>,
@@ -9225,9 +8818,8 @@ export declare const workflow: {
9225
8818
  /**
9226
8819
  * Remove a deployed definition (all versions, or one via `version`). Refuses
9227
8820
  * while non-terminal instances exist unless `cascade` aborts them first —
9228
- * instances are never deleted, only aborted in place; see
9229
- * {@link deleteDefinitionInternal} for the full contract (spawn-referrer
9230
- * check, guard-doc housekeeping).
8821
+ * instances are never deleted, only aborted in place. The operation also
8822
+ * checks spawn referrers and cleans up guard documents.
9231
8823
  */
9232
8824
  deleteDefinition: (
9233
8825
  rawArgs: Clocked<Telemetered<DeleteDefinitionArgs & EngineScopeArgs>>,
@@ -9344,8 +8936,8 @@ export declare const workflow: {
9344
8936
  ) => Promise<OperationResult>;
9345
8937
  /**
9346
8938
  * Admin override — hard-stop an in-flight instance where it stands. No stage
9347
- * move, no transition effects, pending effects cancelled; see
9348
- * {@link abortAndPropagate} for the abort + ancestor-propagation contract.
8939
+ * move, no transition effects, pending effects cancelled. The abort
8940
+ * propagates through affected ancestor instances.
9349
8941
  * Propagated, not cascaded — the instance is terminal, so `cascaded` is
9350
8942
  * always `0` and ancestor movement is reported on the ancestors, not here.
9351
8943
  * `changed: false` means the instance was already terminal.
@@ -9534,8 +9126,6 @@ export declare const WORKFLOW_DEFINITION_TYPE = "sanity.workflow.definition";
9534
9126
  */
9535
9127
  export declare const WORKFLOW_INSTANCE_TYPE = "sanity.workflow.instance";
9536
9128
 
9537
- declare const WORKFLOW_LIFECYCLES: readonly ["standalone", "child"];
9538
-
9539
9129
  /**
9540
9130
  * The engine's view of "who am I, what can I do?". `actor` is who
9541
9131
  * the engine stamps onto history / `completedBy` / `ValueExpr.actor` —
@@ -9593,17 +9183,20 @@ export declare interface WorkflowAutonomy extends AutonomyAnswer {
9593
9183
  }
9594
9184
 
9595
9185
  export declare interface WorkflowClient {
9186
+ /** Build a resource-bound data URL, as on SanityClient. Used to confirm document availability. */
9187
+ getDataUrl?: (operation: string, path?: string) => string;
9596
9188
  /**
9597
- * Read the effective client configuration. The engine reads two fields from
9598
- * it. `apiHost` is probed before deriving the global `/users/me` sibling,
9599
- * because `@sanity/client` shallow-merges `withConfig` overrides and
9600
- * otherwise preserves an explicit project host even when
9601
- * `useProjectHostname` is set to `false`. `projectId` addresses the project's
9602
- * user directory when a project-scoped principal has to be bridged to its
9603
- * account-global id a client reporting none has no directory to ask, and
9604
- * such a session is refused rather than stamped locally.
9189
+ * Read the effective client configuration. The engine uses `apiHost` for
9190
+ * account-global identity routing and `projectId` for project directory and
9191
+ * organization lookups. Without `projectId`, organization attributes cannot
9192
+ * be loaded and project-scoped principals cannot use the directory bridge.
9193
+ *
9194
+ * For clients without {@link WorkflowClient.withConfig}, an omitted
9195
+ * `apiVersion` means the implementation must already serve
9196
+ * {@link ENGINE_API_VERSION}. A declared `apiVersion` other than that version
9197
+ * skips organization attributes with a warning.
9605
9198
  */
9606
- config?: () => WorkflowClientConfig;
9199
+ config?: () => WorkflowClientConfigState;
9607
9200
  fetch: <T = unknown>(
9608
9201
  query: string,
9609
9202
  params?: Record<string, unknown>,
@@ -9704,21 +9297,12 @@ export declare interface WorkflowClient {
9704
9297
  * discovery uses its dry-run fallback, while a definition containing
9705
9298
  * role-constrained assignment fields fails loudly because the engine cannot
9706
9299
  * read the project membership directory required to validate assignees.
9300
+ *
9301
+ * Raw request transport. The engine passes the request target through
9302
+ * `url`; relative paths must resolve against the client's configured API
9303
+ * host, matching supported `SanityClient.request` implementations.
9707
9304
  */
9708
- request?: <T>(opts: {
9709
- /** Raw URL (host + path). One of `url` / `uri` required. */
9710
- url?: string;
9711
- /**
9712
- * Project-scoped path resolved against the `@sanity/client`'s
9713
- * apiHost (e.g. `/users/me` → `https://api.sanity.io/v1/users/me`).
9714
- * Use this for global endpoints like `/users/me`. Mirrors
9715
- * `SanityClient.request({uri})` in `@sanity/client`.
9716
- */
9717
- uri?: string;
9718
- signal?: AbortSignal;
9719
- /** Optional `?tag=` query for observability — supported by `@sanity/client`. */
9720
- tag?: string;
9721
- }) => Promise<T>;
9305
+ request?: <T>(opts: WorkflowRequestOptions) => Promise<T>;
9722
9306
  }
9723
9307
 
9724
9308
  /**
@@ -9744,6 +9328,17 @@ export declare interface WorkflowClientConfig {
9744
9328
  useProjectHostname?: boolean;
9745
9329
  }
9746
9330
 
9331
+ /** The engine reads only project and API metadata from this value. */
9332
+ export declare interface WorkflowClientConfigState extends Omit<
9333
+ WorkflowClientConfig,
9334
+ "resource"
9335
+ > {
9336
+ resource?: {
9337
+ type: string;
9338
+ id: string;
9339
+ };
9340
+ }
9341
+
9747
9342
  export declare interface WorkflowCommitOptions {
9748
9343
  /**
9749
9344
  * When the mutation becomes visible to subsequent queries. The engine
@@ -9775,6 +9370,8 @@ export declare interface WorkflowCommitOptions {
9775
9370
  * logger unconditionally (CI and `DO_NOT_TRACK` included), and consent,
9776
9371
  * environment suppression, and transport become this implementation's
9777
9372
  * business.
9373
+ *
9374
+ * @interface
9778
9375
  */
9779
9376
  export declare type WorkflowConfig = v.InferOutput<typeof WorkflowConfigSchema>;
9780
9377
 
@@ -10051,44 +9648,22 @@ declare const WorkflowConfigSchema: v.ObjectSchema<
10051
9648
  readonly [
10052
9649
  v.ArraySchema<
10053
9650
  v.CustomSchema<
10054
- {
10055
- name: string;
10056
- semantics?: Semantic[] | undefined;
10057
- title: string;
10058
- description?: string | undefined;
10059
- groups?: Group[] | undefined;
10060
- lifecycle?: WorkflowLifecycle | undefined;
10061
- start?: StartBlock | undefined;
10062
- initialStage: string;
10063
- fields?: FieldEntry[] | undefined;
10064
- stages: Stage[];
10065
- predicates?: Record<string, string> | undefined;
10066
- roleAliases?: RoleAliases | undefined;
10067
- },
9651
+ DefinedWorkflow,
10068
9652
  v.ErrorMessage<v.CustomIssue> | undefined
10069
9653
  >,
10070
9654
  undefined
10071
9655
  >,
10072
9656
  v.MinLengthAction<
10073
- {
10074
- name: string;
10075
- semantics?: Semantic[] | undefined;
10076
- title: string;
10077
- description?: string | undefined;
10078
- groups?: Group[] | undefined;
10079
- lifecycle?: WorkflowLifecycle | undefined;
10080
- start?: StartBlock | undefined;
10081
- initialStage: string;
10082
- fields?: FieldEntry[] | undefined;
10083
- stages: Stage[];
10084
- predicates?: Record<string, string> | undefined;
10085
- roleAliases?: RoleAliases | undefined;
10086
- }[],
9657
+ DefinedWorkflow[],
10087
9658
  1,
10088
9659
  "a deployment needs at least one definition"
10089
9660
  >,
10090
9661
  ]
10091
9662
  >;
9663
+ readonly runtime: v.OptionalSchema<
9664
+ v.GenericSchema<RuntimeBlock>,
9665
+ undefined
9666
+ >;
10092
9667
  },
10093
9668
  undefined
10094
9669
  >,
@@ -10138,20 +9713,8 @@ declare const WorkflowConfigSchema: v.ObjectSchema<
10138
9713
  };
10139
9714
  }[]
10140
9715
  | undefined;
10141
- definitions: {
10142
- name: string;
10143
- semantics?: Semantic[] | undefined;
10144
- title: string;
10145
- description?: string | undefined;
10146
- groups?: Group[] | undefined;
10147
- lifecycle?: WorkflowLifecycle | undefined;
10148
- start?: StartBlock | undefined;
10149
- initialStage: string;
10150
- fields?: FieldEntry[] | undefined;
10151
- stages: Stage[];
10152
- predicates?: Record<string, string> | undefined;
10153
- roleAliases?: RoleAliases | undefined;
10154
- }[];
9716
+ definitions: DefinedWorkflow[];
9717
+ runtime?: RuntimeBlock | undefined;
10155
9718
  }[],
10156
9719
  1,
10157
9720
  "a config needs at least one deployment"
@@ -10200,20 +9763,8 @@ declare const WorkflowConfigSchema: v.ObjectSchema<
10200
9763
  };
10201
9764
  }[]
10202
9765
  | undefined;
10203
- definitions: {
10204
- name: string;
10205
- semantics?: Semantic[] | undefined;
10206
- title: string;
10207
- description?: string | undefined;
10208
- groups?: Group[] | undefined;
10209
- lifecycle?: WorkflowLifecycle | undefined;
10210
- start?: StartBlock | undefined;
10211
- initialStage: string;
10212
- fields?: FieldEntry[] | undefined;
10213
- stages: Stage[];
10214
- predicates?: Record<string, string> | undefined;
10215
- roleAliases?: RoleAliases | undefined;
10216
- }[];
9766
+ definitions: DefinedWorkflow[];
9767
+ runtime?: RuntimeBlock | undefined;
10217
9768
  }[],
10218
9769
  (
10219
9770
  issue: v.CheckIssue<
@@ -10260,20 +9811,8 @@ declare const WorkflowConfigSchema: v.ObjectSchema<
10260
9811
  };
10261
9812
  }[]
10262
9813
  | undefined;
10263
- definitions: {
10264
- name: string;
10265
- semantics?: Semantic[] | undefined;
10266
- title: string;
10267
- description?: string | undefined;
10268
- groups?: Group[] | undefined;
10269
- lifecycle?: WorkflowLifecycle | undefined;
10270
- start?: StartBlock | undefined;
10271
- initialStage: string;
10272
- fields?: FieldEntry[] | undefined;
10273
- stages: Stage[];
10274
- predicates?: Record<string, string> | undefined;
10275
- roleAliases?: RoleAliases | undefined;
10276
- }[];
9814
+ definitions: DefinedWorkflow[];
9815
+ runtime?: RuntimeBlock | undefined;
10277
9816
  }[]
10278
9817
  >,
10279
9818
  ) => string
@@ -10322,20 +9861,8 @@ declare const WorkflowConfigSchema: v.ObjectSchema<
10322
9861
  };
10323
9862
  }[]
10324
9863
  | undefined;
10325
- definitions: {
10326
- name: string;
10327
- semantics?: Semantic[] | undefined;
10328
- title: string;
10329
- description?: string | undefined;
10330
- groups?: Group[] | undefined;
10331
- lifecycle?: WorkflowLifecycle | undefined;
10332
- start?: StartBlock | undefined;
10333
- initialStage: string;
10334
- fields?: FieldEntry[] | undefined;
10335
- stages: Stage[];
10336
- predicates?: Record<string, string> | undefined;
10337
- roleAliases?: RoleAliases | undefined;
10338
- }[];
9864
+ definitions: DefinedWorkflow[];
9865
+ runtime?: RuntimeBlock | undefined;
10339
9866
  }[],
10340
9867
  (
10341
9868
  issue: v.CheckIssue<
@@ -10382,20 +9909,8 @@ declare const WorkflowConfigSchema: v.ObjectSchema<
10382
9909
  };
10383
9910
  }[]
10384
9911
  | undefined;
10385
- definitions: {
10386
- name: string;
10387
- semantics?: Semantic[] | undefined;
10388
- title: string;
10389
- description?: string | undefined;
10390
- groups?: Group[] | undefined;
10391
- lifecycle?: WorkflowLifecycle | undefined;
10392
- start?: StartBlock | undefined;
10393
- initialStage: string;
10394
- fields?: FieldEntry[] | undefined;
10395
- stages: Stage[];
10396
- predicates?: Record<string, string> | undefined;
10397
- roleAliases?: RoleAliases | undefined;
10398
- }[];
9912
+ definitions: DefinedWorkflow[];
9913
+ runtime?: RuntimeBlock | undefined;
10399
9914
  }[]
10400
9915
  >,
10401
9916
  ) => string
@@ -10427,6 +9942,8 @@ declare const WorkflowConfigSchema: v.ObjectSchema<
10427
9942
  * conditions — each `name: groq` entry is pre-evaluated and bound as the
10428
9943
  * boolean `$name` var; redefining a built-in var is a deploy error, never a
10429
9944
  * silent shadow.
9945
+ *
9946
+ * @interface
10430
9947
  */
10431
9948
  export declare type WorkflowDefinition = v.InferOutput<
10432
9949
  typeof WorkflowDefinitionSchema
@@ -10481,35 +9998,22 @@ export declare interface WorkflowDefinitionDeployedData {
10481
9998
  * of a literal is a finite key union that `string` never extends) — i.e. how
10482
9999
  * fetch results are typed (`Record<string, unknown>`), which pass through to
10483
10000
  * the runtime boundary parse. Everything precisely typed gets the exact
10484
- * {@link WorkflowDefinition} contract: beyond the document envelope
10485
- * ({@link DocumentEnvelopeKey}, so a typed {@link DeployedDefinition} passes
10486
- * castless), unknown keys are `never` a typo'd literal is a compile error,
10487
- * never a silent collapse to the record arm.
10001
+ * {@link WorkflowDefinition} contract with two accepted exceptions: the
10002
+ * document envelope (the closed system-key union, so a typed
10003
+ * {@link DeployedDefinition} passes castless) and the authoring-only root
10004
+ * `runtime` block, so a {@link DefinedWorkflow} passes castless too. Every
10005
+ * other unknown key is `never`, making a typo'd literal a compile error rather
10006
+ * than a silent collapse to the record arm.
10488
10007
  */
10489
10008
  export declare type WorkflowDefinitionInput<T> = string extends keyof T
10490
10009
  ? Record<string, unknown>
10491
10010
  : WorkflowDefinition & {
10492
10011
  [K in Exclude<
10493
10012
  keyof T,
10494
- keyof WorkflowDefinition | DocumentEnvelopeKey
10013
+ keyof WorkflowDefinition | DocumentEnvelopeKey | AuthoringRuntimeKey
10495
10014
  >]?: never;
10496
10015
  };
10497
10016
 
10498
- /**
10499
- * Structural schema for a STORED workflow definition — primitives only,
10500
- * every reference scope resolved. Cross-field invariants (unique names,
10501
- * transition targets, effect-name uniqueness, predicate shadowing) are
10502
- * checked by `checkWorkflowInvariants` after desugar — see `defineWorkflow`.
10503
- * Carries NO `version`: a definition's version and content fingerprint are
10504
- * stamped onto the deployed document at deploy time, derived from the
10505
- * content itself, so redeploying identical content is a no-op and any
10506
- * change mints the next version.
10507
- *
10508
- * Exported (module-level, not package API) for the model-surface gate's
10509
- * coverage test and for `parseStoredDefinition` — the boundary parse for a
10510
- * definition that did not come out of `defineWorkflow` in-process; trusted
10511
- * in-process desugar output is never re-parsed.
10512
- */
10513
10017
  declare const WorkflowDefinitionSchema: v.GenericSchema<
10514
10018
  WorkflowFields<FieldEntry, Stage, StartBlock>
10515
10019
  >;
@@ -10521,10 +10025,22 @@ declare const WorkflowDefinitionSchema: v.GenericSchema<
10521
10025
  export declare type WorkflowDeployment = WorkflowConfig["deployments"][number];
10522
10026
 
10523
10027
  /**
10524
- * What an author writes for one deployment: the highest reader model verified
10525
- * across runtimes sharing its workflow resource. Runtime validation compares
10526
- * it with the submitted definitions, so a dependency upgrade alone does not
10527
- * require changing the literal.
10028
+ * Author one deployment with a nonempty `definitions` array and a
10029
+ * {@link WorkflowResource}. Dataset resource IDs use `<projectId>.<dataset>`.
10030
+ *
10031
+ * `name` and `tag` must contain only ASCII lowercase letters, digits, and dashes,
10032
+ * starting with a letter or digit. Deployment names and `(workflowResource, tag)`
10033
+ * pairs must be unique across the config. Optional `resourceAliases` use the same
10034
+ * name grammar, with unique names within this deployment.
10035
+ *
10036
+ * `expectedMinReaderModel` is the highest reader model you have verified across
10037
+ * runtimes sharing the workflow resource. Supply a reviewed numeric literal.
10038
+ * Definition submission checks it against the required reader floor; upgrading
10039
+ * a dependency alone does not require changing it.
10040
+ *
10041
+ * `runtime` is the default hosting kind for this deployment's workflows, which
10042
+ * each workflow and effect may override. Omitted, its workflows host on
10043
+ * `'function'`.
10528
10044
  */
10529
10045
  export declare type WorkflowDeploymentInput = Omit<
10530
10046
  WorkflowDeployment,
@@ -10602,6 +10118,7 @@ export declare type WorkflowErrorKind =
10602
10118
  | "partial-guard-deploy"
10603
10119
  | "start-not-primed"
10604
10120
  | "start-not-settled"
10121
+ | "concurrent-cascade"
10605
10122
  | "concurrent-fire-action"
10606
10123
  | "concurrent-edit-field"
10607
10124
  | "concurrent-complete-effect"
@@ -10625,11 +10142,21 @@ export declare type WorkflowErrorKind =
10625
10142
  export declare interface WorkflowEvaluation {
10626
10143
  instance: WorkflowInstance;
10627
10144
  definition: WorkflowDefinition;
10145
+ /** Missing targets of populated subject, doc.ref, and doc.refs fields in active
10146
+ * scopes. Clears on resolution; empty fields and exited-stage fields are excluded.
10147
+ * Required reference declarations and runtime conditions determine whether absence blocks progress. */
10148
+ missingDocuments?: MissingDocument[];
10149
+ /**
10150
+ * Missing required reference targets, or references read by unmet runtime requirements or transition conditions,
10151
+ * including named predicates in their evaluated scope. Empty when missing references
10152
+ * are optional for current progress. Omitted when no references are missing.
10153
+ */
10154
+ blockingMissingDocuments?: MissingDocument[];
10628
10155
  /** The workflow's advisory meaning, unchanged from its definition. */
10629
10156
  semantics?: Semantic[] | undefined;
10630
10157
  actor: Actor;
10631
10158
  currentStage: StageEvaluation;
10632
- /** Active activities whose assignees-kind field entry matches the actor. */
10159
+ /** Active activities whose singular or plural assignment entry matches the actor. */
10633
10160
  pendingOnYou: ActivityEvaluation[];
10634
10161
  /** True if at least one action on any active activity is allowed. */
10635
10162
  canInteract: boolean;
@@ -10655,6 +10182,17 @@ export declare interface WorkflowEvaluation {
10655
10182
  * evaluation time, so their legs report `conditional`.
10656
10183
  */
10657
10184
  autonomy: WorkflowAutonomy;
10185
+ /**
10186
+ * The earliest future ISO 8601 instant the engine can derive for a time-based
10187
+ * change to this evaluation. Re-evaluate then. Includes a gate reading `$now`
10188
+ * beside `$actor`, `$assigned`, `$can`, or `$attributes`, evaluated in this
10189
+ * actor's scopes. Derived per call, never persisted.
10190
+ *
10191
+ * Absent on a terminal instance or when the engine cannot derive a boundary.
10192
+ * Conditions using date arithmetic may yield no boundary. Time can still
10193
+ * affect a nonterminal instance when this value is absent.
10194
+ */
10195
+ nextEvaluationAt?: string;
10658
10196
  }
10659
10197
 
10660
10198
  export declare interface WorkflowFetchOptions {
@@ -10682,7 +10220,7 @@ export declare interface WorkflowFieldEditedData extends InstanceScopedEventData
10682
10220
  mode: EditMode;
10683
10221
  }
10684
10222
 
10685
- /** Type-mirror of {@link workflowFields}, parameterised over field/stage/start. */
10223
+ /** @inline */
10686
10224
  declare type WorkflowFields<TField, TStage, TStart> = {
10687
10225
  name: string;
10688
10226
  semantics?: Semantic[] | undefined;
@@ -10743,15 +10281,14 @@ export declare interface WorkflowInstance extends SanityDocument {
10743
10281
  /** Frozen JSON snapshot of the definition at the moment the instance started. */
10744
10282
  definitionSnapshot: string;
10745
10283
  /**
10746
- * Workflow-level resolved field entries.
10747
- * Populated from the workflow definition's `fields[]` declarations plus
10748
- * the caller-supplied `initialFields` at `startInstance`. Persists for
10749
- * the lifetime of the instance.
10284
+ * Resolved workflow fields, retained for the instance's lifetime. Their
10285
+ * initial values come from the definition's `fields` declarations and
10286
+ * {@link StartInstanceArgs.initialFields}.
10750
10287
  *
10751
- * To declare "the subject document of this workflow", add a
10752
- * `{ type: "doc.ref", name: "subject", initialValue: { type: "input" } }`
10753
- * entry to the workflow definition. Conditions then read it as
10754
- * `$fields.subject`. There is no other subject mechanism.
10288
+ * To declare the workflow's subject document, use
10289
+ * `{type: 'subject', name: 'subject', initialValue: {type: 'input'}}`.
10290
+ * Conditions read that entry as `$fields.subject`. The `subject` field
10291
+ * type identifies its role; naming a `doc.ref` field `subject` does not.
10755
10292
  */
10756
10293
  fields: ResolvedFieldEntry[];
10757
10294
  /**
@@ -10767,14 +10304,13 @@ export declare interface WorkflowInstance extends SanityDocument {
10767
10304
  */
10768
10305
  ancestors: GlobalDocumentReference[];
10769
10306
  /**
10770
- * Optional perspective applied to field-entry query reads and spawn
10771
- * `forEach.groq` discovery. When unset the engine treats reads as
10772
- * `"raw"` (no filtering). Set at `startInstance` time to scope a
10773
- * workflow's reads to a Content Release stack (e.g. `[releaseName]`
10774
- * or `[releaseName, "drafts"]`).
10307
+ * Perspective for content reads, including field queries and subworkflow
10308
+ * discovery. Defaults to {@link DEFAULT_CONTENT_PERSPECTIVE}, where drafts
10309
+ * take precedence over published content. Set it through
10310
+ * {@link StartInstanceArgs.perspective}; child instances inherit it.
10775
10311
  *
10776
- * Engine-internal reads of instance / definition documents are
10777
- * always raw, regardless of this field.
10312
+ * Engine-owned instance and definition documents, and `system.release`
10313
+ * documents, always read under `raw`.
10778
10314
  */
10779
10315
  perspective?: WorkflowPerspective;
10780
10316
  currentStage: StageName;
@@ -10905,7 +10441,7 @@ export declare interface WorkflowInstanceTickedData extends InstanceScopedEventD
10905
10441
  /** How instances of a definition come to exist: started standalone (the
10906
10442
  * default) or spawned by a parent. `'child'` is spawn-only — see
10907
10443
  * {@link isStartableDefinition}. */
10908
- export declare type WorkflowLifecycle = (typeof WORKFLOW_LIFECYCLES)[number];
10444
+ export declare type WorkflowLifecycle = "standalone" | "child";
10909
10445
 
10910
10446
  /**
10911
10447
  * The subset of `@sanity/client` the engine actually needs. The
@@ -10948,6 +10484,14 @@ export declare type WorkflowPerspective =
10948
10484
  | "drafts"
10949
10485
  | string[];
10950
10486
 
10487
+ export declare interface WorkflowRequestOptions {
10488
+ /** API-relative path resolved against the configured API host, or an absolute URL. */
10489
+ url: string;
10490
+ signal?: AbortSignal;
10491
+ /** Optional `?tag=` query for observability — supported by `@sanity/client`. */
10492
+ tag?: string;
10493
+ }
10494
+
10951
10495
  /**
10952
10496
  * The resource a Sanity client is configured against — mirrors
10953
10497
  * `@sanity/client`'s `ClientConfigResource` discriminator. For