@voltro/workflow 0.69.1 → 0.71.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/CHANGELOG.md +1369 -111
- package/dist/cluster-BRSoL1tb.js +489 -0
- package/dist/cluster.d.ts +598 -7
- package/dist/cluster.js +2 -2
- package/dist/clusterDiagnostics-jpkNVay6.js +379 -0
- package/dist/clusterTestSuite.js +4 -4
- package/dist/index.d.ts +1063 -95
- package/dist/index.js +4 -4
- package/dist/{primitives-CqHxfASq.js → primitives-DsMsMr5S.js} +141 -122
- package/dist/primitives.js +2 -2
- package/dist/src-OEBqLBJl.js +4842 -0
- package/package.json +4 -4
- package/dist/cluster-DoLWW-cp.js +0 -309
- package/dist/clusterDiagnostics-CNtl5LX9.js +0 -20
- package/dist/src-TRpoU54e.js +0 -2666
package/dist/index.d.ts
CHANGED
|
@@ -20,9 +20,34 @@ import { WorkflowAccessOptions } from '@voltro/protocol';
|
|
|
20
20
|
import { WorkflowEngine } from '@effect/workflow';
|
|
21
21
|
import { Workflow as workflowModule } from '@effect/workflow';
|
|
22
22
|
import { WorkflowParentClosePolicy } from '@voltro/protocol';
|
|
23
|
+
import { WorkflowQueuedCancellationResult } from '@voltro/protocol';
|
|
24
|
+
|
|
25
|
+
/** Dispatch an already committed admission using the same attempt/ACK boundary
|
|
26
|
+
* as the drainer. Returning requires durable acceptance, not just a prepared ID.
|
|
27
|
+
* A concurrent recovery may have supplied that acceptance. */
|
|
28
|
+
export declare const acceptAdmissionSubmission: (deps: AdmissionDrainDeps, submission: AdmissionSubmission, control: ResolvedFlowControl, keys: ReturnType<typeof resolveAdmissionKeys>, now: number) => Promise<string>;
|
|
29
|
+
|
|
30
|
+
/** Resident, database-only acceptance boundary. Allocate the request identity
|
|
31
|
+
* before entering the admission transaction. Acceptance does not change the run
|
|
32
|
+
* and does not prove that an engine observed the request. */
|
|
33
|
+
export declare const acceptWorkflowControlInTransaction: (tx: Store, input: Omit<WorkflowControlRequest, "dispatchAttempts" | "result" | "owner" | "resumeJournal">) => Promise<WorkflowControlRequest>;
|
|
34
|
+
|
|
35
|
+
/** Persist an observed engine acceptance together with the lease linkage.
|
|
36
|
+
* A lost acknowledgement can be retried, but cannot remap a submission to a
|
|
37
|
+
* different execution. No engine call belongs inside this transaction. */
|
|
38
|
+
export declare const acknowledgeAdmissionSubmission: (store: Pick<DataStore, "insertIgnoreWithOutcome" | "transactional">, id: string, accepted: {
|
|
39
|
+
readonly executionId: string;
|
|
40
|
+
readonly runId: string | null;
|
|
41
|
+
}) => Promise<AdmissionSubmission>;
|
|
23
42
|
|
|
24
43
|
/** The narrow slice of `DataStore` flow control needs. */
|
|
25
44
|
export declare interface AdmissionDataStore {
|
|
45
|
+
/** Native arbitration, preserved by every resident transaction adapter. */
|
|
46
|
+
readonly insertIgnoreWithOutcome: DataStore['insertIgnoreWithOutcome'];
|
|
47
|
+
/** Host schema codecs: queue rows carry encoded values, controls and the
|
|
48
|
+
* engine consume decoded payloads. Absent for a JSON-only low-level host. */
|
|
49
|
+
readonly encodeWorkflowPayload?: (workflowName: string, payload: unknown) => unknown;
|
|
50
|
+
readonly decodeWorkflowPayload?: (workflowName: string, payload: unknown) => unknown;
|
|
26
51
|
query(descriptor: QueryDescriptor): Promise<ReadonlyArray<Row>>;
|
|
27
52
|
insert(table: string, row: Row): Promise<Row>;
|
|
28
53
|
update(table: string, primaryKey: string, patch: Readonly<Record<string, unknown>>): Promise<Row | null>;
|
|
@@ -65,7 +90,20 @@ export declare type AdmissionDecision = {
|
|
|
65
90
|
};
|
|
66
91
|
|
|
67
92
|
export declare interface AdmissionDrainDeps {
|
|
93
|
+
/** Cross-store capacity check after resident commit and before engine I/O.
|
|
94
|
+
* Replays must reuse this submission's durable permit. False is ordinary
|
|
95
|
+
* waiting, not a rejected or failed engine attempt. Never call inside SQL. */
|
|
96
|
+
readonly acquireSubmissionCapacity?: (submission: AdmissionSubmission) => Promise<boolean>;
|
|
97
|
+
/** Derive the declared engine key without starting work. Called outside SQL
|
|
98
|
+
* transactions, only when the durable submission has no prepared identity. */
|
|
99
|
+
readonly resolveExecutionId: (workflowName: string, payload: unknown) => Promise<string>;
|
|
68
100
|
readonly store: AdmissionDataStore;
|
|
101
|
+
/** Host-wide pauses plus resident pauses, read outside resident transactions.
|
|
102
|
+
* The resident transaction may add a newer local pause, never clear this set. */
|
|
103
|
+
readonly readPauses?: () => Promise<ReadonlySet<string>>;
|
|
104
|
+
/** Own the shared admission transaction. Callback is database-only and may
|
|
105
|
+
* replay; it must serialize with direct arrivals in this resident store. */
|
|
106
|
+
readonly transaction: <A>(work: (tx: AdmissionDataStore) => Promise<A>) => Promise<A>;
|
|
69
107
|
/** Resolved flow control per workflow name. A name missing from this map has
|
|
70
108
|
* no controls, so any pending row under it is an orphan — see `drainTick`. */
|
|
71
109
|
readonly controls: ReadonlyMap<string, ResolvedFlowControl>;
|
|
@@ -81,7 +119,7 @@ export declare interface AdmissionDrainDeps {
|
|
|
81
119
|
* with nothing running. That shipped; the CLI's implementation passes an
|
|
82
120
|
* `admitted` marker that skips the gate.
|
|
83
121
|
*/
|
|
84
|
-
readonly startAdmitted: (workflowName: string, payload: unknown, callerContext: unknown) => Promise<AdmittedStart>;
|
|
122
|
+
readonly startAdmitted: (workflowName: string, payload: unknown, callerContext: unknown, preparedExecutionId?: string) => Promise<AdmittedStart>;
|
|
85
123
|
/**
|
|
86
124
|
* Cancel a run through the durable run-state boundary — engine interrupt,
|
|
87
125
|
* terminal row, event, and child cleanup — used by singleton eviction and
|
|
@@ -108,6 +146,9 @@ export declare interface AdmissionDrainDeps {
|
|
|
108
146
|
* a failure that does not clear, which is no longer transient in any sense a
|
|
109
147
|
* retry can help. Signalled to `onFailure` once and retained, exactly like a
|
|
110
148
|
* permanent payload failure; `voltro workflows flow retry` re-arms it.
|
|
149
|
+
* Unacknowledged submissions instead persist an automatic-retry stop with
|
|
150
|
+
* acceptance unknown: no abandonment report and no concurrency release.
|
|
151
|
+
* Pending-intent retry commands do not reconcile those submissions.
|
|
111
152
|
*/
|
|
112
153
|
readonly deadLetterAfterAttempts?: number | false;
|
|
113
154
|
readonly onAbandoned: (input: {
|
|
@@ -135,8 +176,8 @@ export declare interface AdmissionDrainDeps {
|
|
|
135
176
|
* lastError climb on the row) instead of a silent abandon.
|
|
136
177
|
*/
|
|
137
178
|
readonly registeredWorkflows?: ReadonlySet<string>;
|
|
138
|
-
/** Classify
|
|
139
|
-
*
|
|
179
|
+
/** Classify an input rejection guaranteed to happen BEFORE engine I/O, not
|
|
180
|
+
* merely an error retrying cannot repair. The CLI wires `WorkflowPayloadError`; unknown engine/store errors
|
|
140
181
|
* stay on the retry path because abandoning transient work is worse than a
|
|
141
182
|
* visible retry. */
|
|
142
183
|
readonly isPermanentStartError?: (cause: unknown) => boolean;
|
|
@@ -185,6 +226,8 @@ export declare interface AdmissionState {
|
|
|
185
226
|
readonly firstSeenAt: number;
|
|
186
227
|
};
|
|
187
228
|
readonly singletonHolder?: AdmissionIncumbent;
|
|
229
|
+
/** A reservation exists but its execution identity is not confirmed yet. */
|
|
230
|
+
readonly singletonUnacknowledged?: boolean;
|
|
188
231
|
/** Runs in flight under `concurrencyKey` (leases held, not yet released). */
|
|
189
232
|
readonly inFlight?: number;
|
|
190
233
|
/** Admission timestamps inside the throttle / rate-limit window,
|
|
@@ -193,6 +236,11 @@ export declare interface AdmissionState {
|
|
|
193
236
|
readonly recentAdmissions?: ReadonlyArray<number>;
|
|
194
237
|
}
|
|
195
238
|
|
|
239
|
+
/** Immutable engine input, stored beside its resident queue. Payload is schema
|
|
240
|
+
* encoded. A retry must use this value, not reconstruct it from current defaults
|
|
241
|
+
* or a batch that has accumulated additional items. */
|
|
242
|
+
export declare type AdmissionSubmission = typeof SubmissionSchema.Type;
|
|
243
|
+
|
|
196
244
|
/** What the caller learns about a start that went through flow control. */
|
|
197
245
|
export declare type AdmissionVerdict = {
|
|
198
246
|
/** Start it now. The ledger row is already written; call `linkExecution`
|
|
@@ -266,11 +314,9 @@ export declare interface AdmitStartInput {
|
|
|
266
314
|
* `true` when the caller is BLOCKING for the result (`ctx.workflows.run`, or
|
|
267
315
|
* `start({ wait: true })`).
|
|
268
316
|
*
|
|
269
|
-
*
|
|
270
|
-
*
|
|
271
|
-
*
|
|
272
|
-
* carried so the ledger records WHY a run bypassed the queue, not to change
|
|
273
|
-
* the decision.
|
|
317
|
+
* Observation does not change admission. A deferred caller follows its
|
|
318
|
+
* durable receipt until an execution is accepted or non-execution settles.
|
|
319
|
+
* This flag annotates immediate ledger entries; it never bypasses a control.
|
|
274
320
|
*/
|
|
275
321
|
readonly waiting: boolean;
|
|
276
322
|
}
|
|
@@ -488,6 +534,470 @@ export declare interface AwaitUpdateOptions<A, B = A> {
|
|
|
488
534
|
readonly timeoutMs?: number;
|
|
489
535
|
}
|
|
490
536
|
|
|
537
|
+
/** Persist BEFORE calling the engine. Failed acknowledgements and process
|
|
538
|
+
* death must leave evidence that an earlier call could have been accepted.
|
|
539
|
+
* Return null when this source is no longer dispatchable. Database-only;
|
|
540
|
+
* the returned attempt number fences a later permanent-rejection decision. */
|
|
541
|
+
export declare const beginAdmissionSubmissionDispatchInTransaction: (tx: Pick<DataStore, "query" | "update">, id: string, now: number) => Promise<AdmissionSubmission | null>;
|
|
542
|
+
|
|
543
|
+
/** Persist the attempt before engine I/O. A worker dying after this commit
|
|
544
|
+
* leaves ambiguity, not evidence of rejection. Re-read the resident generation
|
|
545
|
+
* on every attempt; an old control request cannot target a replacement body.
|
|
546
|
+
* The caller must still use an engine operation fenced to this generation:
|
|
547
|
+
* this transaction cannot fence an unqualified interrupt after it commits. */
|
|
548
|
+
export declare const beginWorkflowControlDispatchInTransaction: (tx: Store, id: string) => Promise<{
|
|
549
|
+
kind: "settled";
|
|
550
|
+
request: {
|
|
551
|
+
readonly id: string;
|
|
552
|
+
readonly cause?: {
|
|
553
|
+
readonly detail?: {
|
|
554
|
+
readonly [x: string]: unknown;
|
|
555
|
+
} | undefined;
|
|
556
|
+
readonly reason: string;
|
|
557
|
+
} | null | undefined;
|
|
558
|
+
readonly result: {
|
|
559
|
+
readonly status: "failed" | "cancelled" | "succeeded";
|
|
560
|
+
readonly kind: "confirmed" | "already-terminal";
|
|
561
|
+
readonly errorMessage: string | null;
|
|
562
|
+
readonly output: unknown;
|
|
563
|
+
readonly errorTag: string | null;
|
|
564
|
+
readonly completedAt: number;
|
|
565
|
+
} | {
|
|
566
|
+
readonly status: "running";
|
|
567
|
+
readonly kind: "confirmed";
|
|
568
|
+
readonly generation: string;
|
|
569
|
+
readonly enteredAt: number;
|
|
570
|
+
} | null;
|
|
571
|
+
readonly requestedAt: number;
|
|
572
|
+
readonly executionId: string;
|
|
573
|
+
readonly runId: string;
|
|
574
|
+
readonly workflowName: string;
|
|
575
|
+
readonly operation: "resume" | "cancel" | "terminate";
|
|
576
|
+
readonly generation: string;
|
|
577
|
+
readonly owner: {
|
|
578
|
+
readonly tenantId: string | null;
|
|
579
|
+
} | null;
|
|
580
|
+
readonly resumeJournal: {
|
|
581
|
+
readonly requestId: string;
|
|
582
|
+
readonly replyId: string;
|
|
583
|
+
readonly restartToken: string | null;
|
|
584
|
+
} | null;
|
|
585
|
+
readonly dispatchAttempts: number;
|
|
586
|
+
};
|
|
587
|
+
run?: never;
|
|
588
|
+
} | {
|
|
589
|
+
kind: "unknown";
|
|
590
|
+
request: {
|
|
591
|
+
readonly id: string;
|
|
592
|
+
readonly cause?: {
|
|
593
|
+
readonly detail?: {
|
|
594
|
+
readonly [x: string]: unknown;
|
|
595
|
+
} | undefined;
|
|
596
|
+
readonly reason: string;
|
|
597
|
+
} | null | undefined;
|
|
598
|
+
readonly result: {
|
|
599
|
+
readonly status: "failed" | "cancelled" | "succeeded";
|
|
600
|
+
readonly kind: "confirmed" | "already-terminal";
|
|
601
|
+
readonly errorMessage: string | null;
|
|
602
|
+
readonly output: unknown;
|
|
603
|
+
readonly errorTag: string | null;
|
|
604
|
+
readonly completedAt: number;
|
|
605
|
+
} | {
|
|
606
|
+
readonly status: "running";
|
|
607
|
+
readonly kind: "confirmed";
|
|
608
|
+
readonly generation: string;
|
|
609
|
+
readonly enteredAt: number;
|
|
610
|
+
} | null;
|
|
611
|
+
readonly requestedAt: number;
|
|
612
|
+
readonly executionId: string;
|
|
613
|
+
readonly runId: string;
|
|
614
|
+
readonly workflowName: string;
|
|
615
|
+
readonly operation: "resume" | "cancel" | "terminate";
|
|
616
|
+
readonly generation: string;
|
|
617
|
+
readonly owner: {
|
|
618
|
+
readonly tenantId: string | null;
|
|
619
|
+
} | null;
|
|
620
|
+
readonly resumeJournal: {
|
|
621
|
+
readonly requestId: string;
|
|
622
|
+
readonly replyId: string;
|
|
623
|
+
readonly restartToken: string | null;
|
|
624
|
+
} | null;
|
|
625
|
+
readonly dispatchAttempts: number;
|
|
626
|
+
};
|
|
627
|
+
run?: never;
|
|
628
|
+
} | {
|
|
629
|
+
kind: "superseded";
|
|
630
|
+
request: {
|
|
631
|
+
readonly id: string;
|
|
632
|
+
readonly cause?: {
|
|
633
|
+
readonly detail?: {
|
|
634
|
+
readonly [x: string]: unknown;
|
|
635
|
+
} | undefined;
|
|
636
|
+
readonly reason: string;
|
|
637
|
+
} | null | undefined;
|
|
638
|
+
readonly result: {
|
|
639
|
+
readonly status: "failed" | "cancelled" | "succeeded";
|
|
640
|
+
readonly kind: "confirmed" | "already-terminal";
|
|
641
|
+
readonly errorMessage: string | null;
|
|
642
|
+
readonly output: unknown;
|
|
643
|
+
readonly errorTag: string | null;
|
|
644
|
+
readonly completedAt: number;
|
|
645
|
+
} | {
|
|
646
|
+
readonly status: "running";
|
|
647
|
+
readonly kind: "confirmed";
|
|
648
|
+
readonly generation: string;
|
|
649
|
+
readonly enteredAt: number;
|
|
650
|
+
} | null;
|
|
651
|
+
readonly requestedAt: number;
|
|
652
|
+
readonly executionId: string;
|
|
653
|
+
readonly runId: string;
|
|
654
|
+
readonly workflowName: string;
|
|
655
|
+
readonly operation: "resume" | "cancel" | "terminate";
|
|
656
|
+
readonly generation: string;
|
|
657
|
+
readonly owner: {
|
|
658
|
+
readonly tenantId: string | null;
|
|
659
|
+
} | null;
|
|
660
|
+
readonly resumeJournal: {
|
|
661
|
+
readonly requestId: string;
|
|
662
|
+
readonly replyId: string;
|
|
663
|
+
readonly restartToken: string | null;
|
|
664
|
+
} | null;
|
|
665
|
+
readonly dispatchAttempts: number;
|
|
666
|
+
};
|
|
667
|
+
run?: never;
|
|
668
|
+
} | {
|
|
669
|
+
kind: "already-terminal";
|
|
670
|
+
request: {
|
|
671
|
+
readonly id: string;
|
|
672
|
+
readonly cause?: {
|
|
673
|
+
readonly detail?: {
|
|
674
|
+
readonly [x: string]: unknown;
|
|
675
|
+
} | undefined;
|
|
676
|
+
readonly reason: string;
|
|
677
|
+
} | null | undefined;
|
|
678
|
+
readonly result: {
|
|
679
|
+
readonly status: "failed" | "cancelled" | "succeeded";
|
|
680
|
+
readonly kind: "confirmed" | "already-terminal";
|
|
681
|
+
readonly errorMessage: string | null;
|
|
682
|
+
readonly output: unknown;
|
|
683
|
+
readonly errorTag: string | null;
|
|
684
|
+
readonly completedAt: number;
|
|
685
|
+
} | {
|
|
686
|
+
readonly status: "running";
|
|
687
|
+
readonly kind: "confirmed";
|
|
688
|
+
readonly generation: string;
|
|
689
|
+
readonly enteredAt: number;
|
|
690
|
+
} | null;
|
|
691
|
+
readonly requestedAt: number;
|
|
692
|
+
readonly executionId: string;
|
|
693
|
+
readonly runId: string;
|
|
694
|
+
readonly workflowName: string;
|
|
695
|
+
readonly operation: "resume" | "cancel" | "terminate";
|
|
696
|
+
readonly generation: string;
|
|
697
|
+
readonly owner: {
|
|
698
|
+
readonly tenantId: string | null;
|
|
699
|
+
} | null;
|
|
700
|
+
readonly resumeJournal: {
|
|
701
|
+
readonly requestId: string;
|
|
702
|
+
readonly replyId: string;
|
|
703
|
+
readonly restartToken: string | null;
|
|
704
|
+
} | null;
|
|
705
|
+
readonly dispatchAttempts: number;
|
|
706
|
+
};
|
|
707
|
+
run: Readonly<Record<string, unknown>>;
|
|
708
|
+
} | {
|
|
709
|
+
kind: "dispatch";
|
|
710
|
+
request: {
|
|
711
|
+
dispatchAttempts: number;
|
|
712
|
+
id: string;
|
|
713
|
+
cause?: {
|
|
714
|
+
readonly detail?: {
|
|
715
|
+
readonly [x: string]: unknown;
|
|
716
|
+
} | undefined;
|
|
717
|
+
readonly reason: string;
|
|
718
|
+
} | null | undefined;
|
|
719
|
+
result: {
|
|
720
|
+
readonly status: "failed" | "cancelled" | "succeeded";
|
|
721
|
+
readonly kind: "confirmed" | "already-terminal";
|
|
722
|
+
readonly errorMessage: string | null;
|
|
723
|
+
readonly output: unknown;
|
|
724
|
+
readonly errorTag: string | null;
|
|
725
|
+
readonly completedAt: number;
|
|
726
|
+
} | {
|
|
727
|
+
readonly status: "running";
|
|
728
|
+
readonly kind: "confirmed";
|
|
729
|
+
readonly generation: string;
|
|
730
|
+
readonly enteredAt: number;
|
|
731
|
+
} | null;
|
|
732
|
+
requestedAt: number;
|
|
733
|
+
executionId: string;
|
|
734
|
+
runId: string;
|
|
735
|
+
workflowName: string;
|
|
736
|
+
operation: "resume" | "cancel" | "terminate";
|
|
737
|
+
generation: string;
|
|
738
|
+
owner: {
|
|
739
|
+
readonly tenantId: string | null;
|
|
740
|
+
} | null;
|
|
741
|
+
resumeJournal: {
|
|
742
|
+
readonly requestId: string;
|
|
743
|
+
readonly replyId: string;
|
|
744
|
+
readonly restartToken: string | null;
|
|
745
|
+
} | null;
|
|
746
|
+
};
|
|
747
|
+
run?: never;
|
|
748
|
+
}>;
|
|
749
|
+
|
|
750
|
+
/** Database-only capture while holding the resident admission/entry lock.
|
|
751
|
+
* observe reads the journal; it must never wake/reset the engine. Missing
|
|
752
|
+
* journal evidence waits without inventing a binding. After commit, every
|
|
753
|
+
* dispatch uses this immutable observation, including after a lost ACK. */
|
|
754
|
+
export declare const bindWorkflowResumeJournalInTransaction: (tx: Store, id: string, observe: (target: {
|
|
755
|
+
readonly workflowName: string;
|
|
756
|
+
readonly executionId: string;
|
|
757
|
+
readonly requestId: string;
|
|
758
|
+
readonly restartToken: string | null;
|
|
759
|
+
}) => Promise<unknown>) => Promise<{
|
|
760
|
+
kind: "settled";
|
|
761
|
+
request: {
|
|
762
|
+
readonly id: string;
|
|
763
|
+
readonly cause?: {
|
|
764
|
+
readonly detail?: {
|
|
765
|
+
readonly [x: string]: unknown;
|
|
766
|
+
} | undefined;
|
|
767
|
+
readonly reason: string;
|
|
768
|
+
} | null | undefined;
|
|
769
|
+
readonly result: {
|
|
770
|
+
readonly status: "failed" | "cancelled" | "succeeded";
|
|
771
|
+
readonly kind: "confirmed" | "already-terminal";
|
|
772
|
+
readonly errorMessage: string | null;
|
|
773
|
+
readonly output: unknown;
|
|
774
|
+
readonly errorTag: string | null;
|
|
775
|
+
readonly completedAt: number;
|
|
776
|
+
} | {
|
|
777
|
+
readonly status: "running";
|
|
778
|
+
readonly kind: "confirmed";
|
|
779
|
+
readonly generation: string;
|
|
780
|
+
readonly enteredAt: number;
|
|
781
|
+
} | null;
|
|
782
|
+
readonly requestedAt: number;
|
|
783
|
+
readonly executionId: string;
|
|
784
|
+
readonly runId: string;
|
|
785
|
+
readonly workflowName: string;
|
|
786
|
+
readonly operation: "resume" | "cancel" | "terminate";
|
|
787
|
+
readonly generation: string;
|
|
788
|
+
readonly owner: {
|
|
789
|
+
readonly tenantId: string | null;
|
|
790
|
+
} | null;
|
|
791
|
+
readonly resumeJournal: {
|
|
792
|
+
readonly requestId: string;
|
|
793
|
+
readonly replyId: string;
|
|
794
|
+
readonly restartToken: string | null;
|
|
795
|
+
} | null;
|
|
796
|
+
readonly dispatchAttempts: number;
|
|
797
|
+
};
|
|
798
|
+
} | {
|
|
799
|
+
kind: "unknown";
|
|
800
|
+
request: {
|
|
801
|
+
readonly id: string;
|
|
802
|
+
readonly cause?: {
|
|
803
|
+
readonly detail?: {
|
|
804
|
+
readonly [x: string]: unknown;
|
|
805
|
+
} | undefined;
|
|
806
|
+
readonly reason: string;
|
|
807
|
+
} | null | undefined;
|
|
808
|
+
readonly result: {
|
|
809
|
+
readonly status: "failed" | "cancelled" | "succeeded";
|
|
810
|
+
readonly kind: "confirmed" | "already-terminal";
|
|
811
|
+
readonly errorMessage: string | null;
|
|
812
|
+
readonly output: unknown;
|
|
813
|
+
readonly errorTag: string | null;
|
|
814
|
+
readonly completedAt: number;
|
|
815
|
+
} | {
|
|
816
|
+
readonly status: "running";
|
|
817
|
+
readonly kind: "confirmed";
|
|
818
|
+
readonly generation: string;
|
|
819
|
+
readonly enteredAt: number;
|
|
820
|
+
} | null;
|
|
821
|
+
readonly requestedAt: number;
|
|
822
|
+
readonly executionId: string;
|
|
823
|
+
readonly runId: string;
|
|
824
|
+
readonly workflowName: string;
|
|
825
|
+
readonly operation: "resume" | "cancel" | "terminate";
|
|
826
|
+
readonly generation: string;
|
|
827
|
+
readonly owner: {
|
|
828
|
+
readonly tenantId: string | null;
|
|
829
|
+
} | null;
|
|
830
|
+
readonly resumeJournal: {
|
|
831
|
+
readonly requestId: string;
|
|
832
|
+
readonly replyId: string;
|
|
833
|
+
readonly restartToken: string | null;
|
|
834
|
+
} | null;
|
|
835
|
+
readonly dispatchAttempts: number;
|
|
836
|
+
};
|
|
837
|
+
} | {
|
|
838
|
+
kind: "superseded";
|
|
839
|
+
request: {
|
|
840
|
+
readonly id: string;
|
|
841
|
+
readonly cause?: {
|
|
842
|
+
readonly detail?: {
|
|
843
|
+
readonly [x: string]: unknown;
|
|
844
|
+
} | undefined;
|
|
845
|
+
readonly reason: string;
|
|
846
|
+
} | null | undefined;
|
|
847
|
+
readonly result: {
|
|
848
|
+
readonly status: "failed" | "cancelled" | "succeeded";
|
|
849
|
+
readonly kind: "confirmed" | "already-terminal";
|
|
850
|
+
readonly errorMessage: string | null;
|
|
851
|
+
readonly output: unknown;
|
|
852
|
+
readonly errorTag: string | null;
|
|
853
|
+
readonly completedAt: number;
|
|
854
|
+
} | {
|
|
855
|
+
readonly status: "running";
|
|
856
|
+
readonly kind: "confirmed";
|
|
857
|
+
readonly generation: string;
|
|
858
|
+
readonly enteredAt: number;
|
|
859
|
+
} | null;
|
|
860
|
+
readonly requestedAt: number;
|
|
861
|
+
readonly executionId: string;
|
|
862
|
+
readonly runId: string;
|
|
863
|
+
readonly workflowName: string;
|
|
864
|
+
readonly operation: "resume" | "cancel" | "terminate";
|
|
865
|
+
readonly generation: string;
|
|
866
|
+
readonly owner: {
|
|
867
|
+
readonly tenantId: string | null;
|
|
868
|
+
} | null;
|
|
869
|
+
readonly resumeJournal: {
|
|
870
|
+
readonly requestId: string;
|
|
871
|
+
readonly replyId: string;
|
|
872
|
+
readonly restartToken: string | null;
|
|
873
|
+
} | null;
|
|
874
|
+
readonly dispatchAttempts: number;
|
|
875
|
+
};
|
|
876
|
+
} | {
|
|
877
|
+
kind: "not-suspended";
|
|
878
|
+
request: {
|
|
879
|
+
readonly id: string;
|
|
880
|
+
readonly cause?: {
|
|
881
|
+
readonly detail?: {
|
|
882
|
+
readonly [x: string]: unknown;
|
|
883
|
+
} | undefined;
|
|
884
|
+
readonly reason: string;
|
|
885
|
+
} | null | undefined;
|
|
886
|
+
readonly result: {
|
|
887
|
+
readonly status: "failed" | "cancelled" | "succeeded";
|
|
888
|
+
readonly kind: "confirmed" | "already-terminal";
|
|
889
|
+
readonly errorMessage: string | null;
|
|
890
|
+
readonly output: unknown;
|
|
891
|
+
readonly errorTag: string | null;
|
|
892
|
+
readonly completedAt: number;
|
|
893
|
+
} | {
|
|
894
|
+
readonly status: "running";
|
|
895
|
+
readonly kind: "confirmed";
|
|
896
|
+
readonly generation: string;
|
|
897
|
+
readonly enteredAt: number;
|
|
898
|
+
} | null;
|
|
899
|
+
readonly requestedAt: number;
|
|
900
|
+
readonly executionId: string;
|
|
901
|
+
readonly runId: string;
|
|
902
|
+
readonly workflowName: string;
|
|
903
|
+
readonly operation: "resume" | "cancel" | "terminate";
|
|
904
|
+
readonly generation: string;
|
|
905
|
+
readonly owner: {
|
|
906
|
+
readonly tenantId: string | null;
|
|
907
|
+
} | null;
|
|
908
|
+
readonly resumeJournal: {
|
|
909
|
+
readonly requestId: string;
|
|
910
|
+
readonly replyId: string;
|
|
911
|
+
readonly restartToken: string | null;
|
|
912
|
+
} | null;
|
|
913
|
+
readonly dispatchAttempts: number;
|
|
914
|
+
};
|
|
915
|
+
} | {
|
|
916
|
+
kind: "bound";
|
|
917
|
+
request: {
|
|
918
|
+
readonly id: string;
|
|
919
|
+
readonly cause?: {
|
|
920
|
+
readonly detail?: {
|
|
921
|
+
readonly [x: string]: unknown;
|
|
922
|
+
} | undefined;
|
|
923
|
+
readonly reason: string;
|
|
924
|
+
} | null | undefined;
|
|
925
|
+
readonly result: {
|
|
926
|
+
readonly status: "failed" | "cancelled" | "succeeded";
|
|
927
|
+
readonly kind: "confirmed" | "already-terminal";
|
|
928
|
+
readonly errorMessage: string | null;
|
|
929
|
+
readonly output: unknown;
|
|
930
|
+
readonly errorTag: string | null;
|
|
931
|
+
readonly completedAt: number;
|
|
932
|
+
} | {
|
|
933
|
+
readonly status: "running";
|
|
934
|
+
readonly kind: "confirmed";
|
|
935
|
+
readonly generation: string;
|
|
936
|
+
readonly enteredAt: number;
|
|
937
|
+
} | null;
|
|
938
|
+
readonly requestedAt: number;
|
|
939
|
+
readonly executionId: string;
|
|
940
|
+
readonly runId: string;
|
|
941
|
+
readonly workflowName: string;
|
|
942
|
+
readonly operation: "resume" | "cancel" | "terminate";
|
|
943
|
+
readonly generation: string;
|
|
944
|
+
readonly owner: {
|
|
945
|
+
readonly tenantId: string | null;
|
|
946
|
+
} | null;
|
|
947
|
+
readonly resumeJournal: {
|
|
948
|
+
readonly requestId: string;
|
|
949
|
+
readonly replyId: string;
|
|
950
|
+
readonly restartToken: string | null;
|
|
951
|
+
} | null;
|
|
952
|
+
readonly dispatchAttempts: number;
|
|
953
|
+
};
|
|
954
|
+
} | {
|
|
955
|
+
kind: "waiting-journal";
|
|
956
|
+
request: {
|
|
957
|
+
readonly id: string;
|
|
958
|
+
readonly cause?: {
|
|
959
|
+
readonly detail?: {
|
|
960
|
+
readonly [x: string]: unknown;
|
|
961
|
+
} | undefined;
|
|
962
|
+
readonly reason: string;
|
|
963
|
+
} | null | undefined;
|
|
964
|
+
readonly result: {
|
|
965
|
+
readonly status: "failed" | "cancelled" | "succeeded";
|
|
966
|
+
readonly kind: "confirmed" | "already-terminal";
|
|
967
|
+
readonly errorMessage: string | null;
|
|
968
|
+
readonly output: unknown;
|
|
969
|
+
readonly errorTag: string | null;
|
|
970
|
+
readonly completedAt: number;
|
|
971
|
+
} | {
|
|
972
|
+
readonly status: "running";
|
|
973
|
+
readonly kind: "confirmed";
|
|
974
|
+
readonly generation: string;
|
|
975
|
+
readonly enteredAt: number;
|
|
976
|
+
} | null;
|
|
977
|
+
readonly requestedAt: number;
|
|
978
|
+
readonly executionId: string;
|
|
979
|
+
readonly runId: string;
|
|
980
|
+
readonly workflowName: string;
|
|
981
|
+
readonly operation: "resume" | "cancel" | "terminate";
|
|
982
|
+
readonly generation: string;
|
|
983
|
+
readonly owner: {
|
|
984
|
+
readonly tenantId: string | null;
|
|
985
|
+
} | null;
|
|
986
|
+
readonly resumeJournal: {
|
|
987
|
+
readonly requestId: string;
|
|
988
|
+
readonly replyId: string;
|
|
989
|
+
readonly restartToken: string | null;
|
|
990
|
+
} | null;
|
|
991
|
+
readonly dispatchAttempts: number;
|
|
992
|
+
};
|
|
993
|
+
}>;
|
|
994
|
+
|
|
995
|
+
/** Bind only still-pending receipts in the SAME transaction that takes the
|
|
996
|
+
* queue rows. Previously bound receipts may name a reused debounce slot and
|
|
997
|
+
* must never be reassigned. Page by state transition, not OFFSET: every updated
|
|
998
|
+
* row leaves the next read, so a large collapsed burst cannot lose a page. */
|
|
999
|
+
export declare const bindWorkflowStartReceipts: (tx: Pick<DataStore, "query" | "update">, submissionId: string) => Promise<number>;
|
|
1000
|
+
|
|
491
1001
|
export declare const BUDGET_HOLDS_TABLE = "_voltro_budget_holds";
|
|
492
1002
|
|
|
493
1003
|
/** Raised into the workflow when a hold outlived its ceiling. */
|
|
@@ -594,19 +1104,12 @@ export declare interface CancelOnSweepDeps {
|
|
|
594
1104
|
readonly store: CancelOnDataStore;
|
|
595
1105
|
/** Cancel a live run. MUST be idempotent — the boundary instant is re-read
|
|
596
1106
|
* every tick, so a cancel can legitimately be issued twice. */
|
|
597
|
-
readonly cancelRun: (input: {
|
|
1107
|
+
readonly cancelRun: (input: CancelDecision & {
|
|
598
1108
|
readonly workflowName: string;
|
|
599
|
-
readonly runId: string;
|
|
600
|
-
readonly executionId: string;
|
|
601
|
-
readonly reason: string;
|
|
602
|
-
readonly event: string;
|
|
603
1109
|
}) => Promise<void>;
|
|
604
1110
|
/** Discard a queued admission intent. Also idempotent. */
|
|
605
|
-
readonly discardIntent: (input: {
|
|
1111
|
+
readonly discardIntent: (input: DiscardDecision & {
|
|
606
1112
|
readonly workflowName: string;
|
|
607
|
-
readonly intentId: string;
|
|
608
|
-
readonly reason: string;
|
|
609
|
-
readonly event: string;
|
|
610
1113
|
}) => Promise<void>;
|
|
611
1114
|
readonly now?: () => number;
|
|
612
1115
|
readonly log?: {
|
|
@@ -674,18 +1177,17 @@ export declare interface CancelProblem {
|
|
|
674
1177
|
readonly detail: string;
|
|
675
1178
|
}
|
|
676
1179
|
|
|
677
|
-
|
|
1180
|
+
/** Database-only acceptance and observation under the caller's resident
|
|
1181
|
+
* admission transaction. The caller supplies authorized tenant identity. */
|
|
1182
|
+
export declare const cancelQueuedWorkflowStartInTransaction: (tx: AdmissionDataStore, input: ResidentQueuedCancellationTarget & {
|
|
1183
|
+
readonly now: number;
|
|
1184
|
+
readonly cause?: NonNullable<WorkflowControlRequest["cause"]>;
|
|
1185
|
+
}) => Promise<WorkflowQueuedCancellationResult>;
|
|
678
1186
|
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
readonly recorder?: WorkflowRunRecorderService;
|
|
684
|
-
readonly emit?: WorkflowParentCloseEmitter['emit'];
|
|
685
|
-
readonly log?: WorkflowParentCloseLogger;
|
|
686
|
-
readonly limit?: number;
|
|
687
|
-
readonly interruptChild: (workflowName: string, executionId: string, policy: Exclude<WorkflowParentClosePolicy, 'abandon'>) => Promise<void>;
|
|
688
|
-
}
|
|
1187
|
+
/** A clean suspension already ended the application body. Settle only its
|
|
1188
|
+
* generation-bound cancellation, under the same lock that owns reentry.
|
|
1189
|
+
* A late engine wake will observe cancelled and cannot construct a new body. */
|
|
1190
|
+
export declare const cancelSuspendedWorkflowRunInTransaction: (tx: AdmissionDataStore, owner: WorkflowRunGeneration, now: number) => Promise<boolean>;
|
|
689
1191
|
|
|
690
1192
|
/** The engine's own re-read rule: an unprocessed message whose `last_read` is
|
|
691
1193
|
* older than this is re-delivered by the shard's owner on its next poll. A
|
|
@@ -711,6 +1213,25 @@ export declare interface ClusterDiagnosticsOps {
|
|
|
711
1213
|
readonly shardLockHolders: (shardIds: ReadonlyArray<string>) => Effect.Effect<ReadonlyArray<ShardLockHolder>>;
|
|
712
1214
|
/** The runner table — every address that registered, with its heartbeat. */
|
|
713
1215
|
readonly runners: () => Effect.Effect<ReadonlyArray<ClusterRunner>>;
|
|
1216
|
+
/**
|
|
1217
|
+
* Delete the unprocessed messages addressed to one entity — the ONE write on
|
|
1218
|
+
* this service. A run that ended outside the engine (cancelled by a sweep or
|
|
1219
|
+
* an operator, parked as failed) leaves its unanswered requests behind: the
|
|
1220
|
+
* `activity` a killed executor never replied to, the `run` itself if it was
|
|
1221
|
+
* never processed. Every runner that acquires the shard re-reads them for the
|
|
1222
|
+
* re-read window, forever, and an `activity` request for a run that does not
|
|
1223
|
+
* execute waits on a latch that never opens. Nothing consumes them; deleting
|
|
1224
|
+
* is what the engine's own reset does for one request. Returns how many.
|
|
1225
|
+
*
|
|
1226
|
+
* `unreadForMs`: only messages a runner last read at least this long ago —
|
|
1227
|
+
* the guard for the sweep, which must not take a request an operator's
|
|
1228
|
+
* redrive cleared a moment ago and a runner has just re-read.
|
|
1229
|
+
*/
|
|
1230
|
+
readonly discardMessages: (input: {
|
|
1231
|
+
readonly entityType: string;
|
|
1232
|
+
readonly entityId: string;
|
|
1233
|
+
readonly unreadForMs?: number;
|
|
1234
|
+
}) => Effect.Effect<number>;
|
|
714
1235
|
}
|
|
715
1236
|
|
|
716
1237
|
export declare interface ClusterMessageState {
|
|
@@ -782,6 +1303,17 @@ export declare interface CompleteSuspendingSignalInput {
|
|
|
782
1303
|
readonly store?: WorkflowMessageStore;
|
|
783
1304
|
}
|
|
784
1305
|
|
|
1306
|
+
/** Complete an executing body only after its actual exit. Suspended cancellation
|
|
1307
|
+
* is owned by the entry transaction, not by this caller-facing helper. */
|
|
1308
|
+
export declare const completeWorkflowRunGenerationInTransaction: (tx: AdmissionDataStore, input: WorkflowRunCompletion) => Promise<{
|
|
1309
|
+
readonly kind: "superseded" | "not-running";
|
|
1310
|
+
} | {
|
|
1311
|
+
readonly kind: "committed";
|
|
1312
|
+
readonly row: Row;
|
|
1313
|
+
readonly failureId: string | null;
|
|
1314
|
+
readonly terminalEvent: Row;
|
|
1315
|
+
}>;
|
|
1316
|
+
|
|
785
1317
|
/** FiberRef carrying the active workflow's executionId — set by
|
|
786
1318
|
* `wrapWithRunRecording` on every workflow body entry, read by a
|
|
787
1319
|
* child workflow's recorder to populate
|
|
@@ -936,7 +1468,7 @@ export declare const DEFAULT_SUSPEND_HINT_MS: number;
|
|
|
936
1468
|
/** 24 h — see {@link WorkflowScheduleDeclaration.maxRuntime}. */
|
|
937
1469
|
export declare const DEFAULT_WORKFLOW_SCHEDULE_MAX_RUNTIME_MS: number;
|
|
938
1470
|
|
|
939
|
-
export declare type DeferMode = DeferringControl | 'paused';
|
|
1471
|
+
export declare type DeferMode = DeferringControl | 'paused' | 'singleton';
|
|
940
1472
|
|
|
941
1473
|
/**
|
|
942
1474
|
* Controls that can DEFER a start rather than answer it immediately.
|
|
@@ -986,11 +1518,15 @@ export declare interface DiscardDecision {
|
|
|
986
1518
|
* button, a `cancelOn` event) go through here so neither can be the one that
|
|
987
1519
|
* leaves no trace.
|
|
988
1520
|
*
|
|
989
|
-
*
|
|
990
|
-
*
|
|
991
|
-
*
|
|
1521
|
+
* Audit, queued caller settlement and deletion share the resident admission
|
|
1522
|
+
* transaction. A failed write retains the source; competing discard/drain
|
|
1523
|
+
* operations cannot both consume the same queued input.
|
|
992
1524
|
*/
|
|
993
|
-
export declare const discardIntent: (store:
|
|
1525
|
+
export declare const discardIntent: (store: Pick<DataStore, "insertIgnoreWithOutcome" | "transactional">, intentId: string, reason: string, now: number) => Promise<boolean>;
|
|
1526
|
+
|
|
1527
|
+
/** Database-only discard under the resident admission lock. Audit, unbound
|
|
1528
|
+
* caller settlement and source deletion must commit or roll back together. */
|
|
1529
|
+
export declare const discardIntentInTransaction: (store: AdmissionDataStore, intentId: string, reason: string, now: number) => Promise<boolean>;
|
|
994
1530
|
|
|
995
1531
|
/** A row of `_voltro_workflow_events` — a published DOMAIN event. */
|
|
996
1532
|
export declare interface DomainEventRow {
|
|
@@ -1014,7 +1550,7 @@ export declare interface DrainOutcome {
|
|
|
1014
1550
|
readonly expired: number;
|
|
1015
1551
|
readonly evicted: number;
|
|
1016
1552
|
readonly failed: number;
|
|
1017
|
-
/** Pending intents
|
|
1553
|
+
/** Pending intents or rejected submissions removed from the live dispatch set. */
|
|
1018
1554
|
readonly deadLettered: number;
|
|
1019
1555
|
/** Runs cancelled by `timeouts.finish` on this tick. */
|
|
1020
1556
|
readonly timedOut: number;
|
|
@@ -1056,6 +1592,9 @@ export declare const drainTick: (deps: AdmissionDrainDeps, options?: DrainTickOp
|
|
|
1056
1592
|
|
|
1057
1593
|
declare interface DrainTickOptions {
|
|
1058
1594
|
readonly batchSize?: number;
|
|
1595
|
+
/** Host has a change-channel-backed belief that the pending queue is empty.
|
|
1596
|
+
* Submission recovery still runs; pending rows and submissions are not one queue. */
|
|
1597
|
+
readonly skipPending?: boolean;
|
|
1059
1598
|
}
|
|
1060
1599
|
|
|
1061
1600
|
/**
|
|
@@ -1080,6 +1619,27 @@ export { durableQueueModule }
|
|
|
1080
1619
|
|
|
1081
1620
|
export { durableRateLimiterModule }
|
|
1082
1621
|
|
|
1622
|
+
/** Establish the body-entry owner before running application code. Existing
|
|
1623
|
+
* execution identity retains its run ID and original input; return the previous
|
|
1624
|
+
* snapshot so crash/version guards decide from the state they actually replaced.
|
|
1625
|
+
* Both row creation and re-entry execute under the resident admission lock. */
|
|
1626
|
+
export declare const enterWorkflowRunGenerationInTransaction: (tx: AdmissionDataStore, input: {
|
|
1627
|
+
readonly workflowName: string;
|
|
1628
|
+
readonly executionId: string;
|
|
1629
|
+
readonly generation: string;
|
|
1630
|
+
readonly initialRow: Row;
|
|
1631
|
+
readonly now: number;
|
|
1632
|
+
readonly delivery?: {
|
|
1633
|
+
readonly requestId: string;
|
|
1634
|
+
readonly restartToken: string | null;
|
|
1635
|
+
} | null;
|
|
1636
|
+
}) => Promise<{
|
|
1637
|
+
readonly kind: "created" | "entered" | "replayed" | "cancelled" | "already-cancelled";
|
|
1638
|
+
readonly row: Row;
|
|
1639
|
+
readonly previous: Row | undefined;
|
|
1640
|
+
readonly terminalEvent?: Row;
|
|
1641
|
+
}>;
|
|
1642
|
+
|
|
1083
1643
|
/**
|
|
1084
1644
|
* Read the state and decide — the ONE composition both callers use.
|
|
1085
1645
|
*
|
|
@@ -1102,6 +1662,42 @@ declare interface EvaluateInput {
|
|
|
1102
1662
|
|
|
1103
1663
|
export declare const EVENTS_TABLE = "_voltro_workflow_events";
|
|
1104
1664
|
|
|
1665
|
+
/** Submit under an identity the durable owner already chose and persisted.
|
|
1666
|
+
* Does not derive the key again, reserve capacity, or persist caller context.
|
|
1667
|
+
* Call only AFTER those responsibilities have committed, outside their
|
|
1668
|
+
* transaction. Reusing an ID requires the same immutable encoded input.
|
|
1669
|
+
* By default returns the accepted execution ID. With discard:false, waits for
|
|
1670
|
+
* the typed body result under that same ID and preserves its failure channel.
|
|
1671
|
+
* Record acceptance before joining; body completion is a separate event.
|
|
1672
|
+
* Ordinary starts do not opt into this capability automatically. */
|
|
1673
|
+
export declare const executePreparedWorkflow: <Payload extends Schema.Schema.Any, Success extends Schema.Schema.Any, Error extends Schema.Schema.All, Discard extends boolean = true>(definition: {
|
|
1674
|
+
readonly payloadSchema: Payload;
|
|
1675
|
+
readonly successSchema: Success;
|
|
1676
|
+
readonly errorSchema: Error;
|
|
1677
|
+
}, payload: Payload["Type"], executionId: string, options?: {
|
|
1678
|
+
readonly discard: Discard;
|
|
1679
|
+
}) => Effect.Effect<Discard extends true ? string : Success["Type"], Error["Type"], WorkflowEngine.WorkflowEngine | Payload["Context"] | Success["Context"] | Error["Context"]>;
|
|
1680
|
+
|
|
1681
|
+
declare const FailureRecordSchema: Schema.Struct<{
|
|
1682
|
+
id: typeof Schema.String;
|
|
1683
|
+
workflowName: typeof Schema.String;
|
|
1684
|
+
tenantId: Schema.NullOr<typeof Schema.String>;
|
|
1685
|
+
sourceId: typeof Schema.String;
|
|
1686
|
+
sourceKind: Schema.Literal<["submission", "intent", "run"]>;
|
|
1687
|
+
handler: Schema.NullOr<typeof Schema.String>;
|
|
1688
|
+
callerContext: typeof Schema.Unknown;
|
|
1689
|
+
report: Schema.Struct<{
|
|
1690
|
+
workflow: typeof Schema.String;
|
|
1691
|
+
payload: typeof Schema.Unknown;
|
|
1692
|
+
errorTag: Schema.NullOr<typeof Schema.String>;
|
|
1693
|
+
errorMessage: Schema.NullOr<typeof Schema.String>;
|
|
1694
|
+
runId: Schema.NullOr<typeof Schema.String>;
|
|
1695
|
+
executionId: Schema.NullOr<typeof Schema.String>;
|
|
1696
|
+
reason: typeof Schema.String;
|
|
1697
|
+
failedAt: typeof Schema.Number;
|
|
1698
|
+
}>;
|
|
1699
|
+
}>;
|
|
1700
|
+
|
|
1105
1701
|
/** Raised when a user-supplied key function throws. Named separately because
|
|
1106
1702
|
* the alternative — letting it escape — surfaces as an opaque failure inside
|
|
1107
1703
|
* `start()` with no hint that the app's own lambda produced it. */
|
|
@@ -1135,6 +1731,12 @@ export declare const getWorkflowSchedule: (value: unknown) => ResolvedWorkflowSc
|
|
|
1135
1731
|
|
|
1136
1732
|
export declare const getWorkflowVersionMetadata: (value: unknown) => WorkflowVersionMetadata;
|
|
1137
1733
|
|
|
1734
|
+
/** Transfer a stored incident to the existing durable arrival queue. Must share
|
|
1735
|
+
* the resident admission transaction with its source transition when creating
|
|
1736
|
+
* a report. No engine I/O; a queued receipt is not handler acceptance.
|
|
1737
|
+
* The handler's declared controls apply when the arrival is drained. */
|
|
1738
|
+
export declare const handoffWorkflowFailureInTransaction: (tx: AdmissionDataStore, reportId: string, now: number) => Promise<WorkflowFailureHandoff>;
|
|
1739
|
+
|
|
1138
1740
|
/** `true` when this workflow declares at least one `cancelOn` entry — i.e. when
|
|
1139
1741
|
* the cancellation sweep has anything to do for it. */
|
|
1140
1742
|
export declare const hasCancelOn: (control: ResolvedFlowControl | undefined) => boolean;
|
|
@@ -1340,6 +1942,13 @@ declare type NormaliseWorkflowMessages<M extends WorkflowMessageSchemas | undefi
|
|
|
1340
1942
|
* `patch()` then reports the PRE-patch branch. */
|
|
1341
1943
|
export declare const normaliseWorkflowPatches: (value: unknown) => ReadonlyArray<string> | undefined;
|
|
1342
1944
|
|
|
1945
|
+
/** Record a failed submit/ack attempt on its durable owner, not a consumed
|
|
1946
|
+
* pending row. Missing acknowledgement does NOT prove that the engine rejected
|
|
1947
|
+
* the call; this record deliberately makes no terminal-execution claim.
|
|
1948
|
+
* Call inside the owning admission transaction. A reached attempt limit stops
|
|
1949
|
+
* automatic retry but retains the lease and receipt for reconciliation. */
|
|
1950
|
+
export declare const noteAdmissionSubmissionFailure: (tx: Pick<DataStore, "query" | "update">, id: string, error: string, now: number, maxAttempts?: number | false) => Promise<AdmissionSubmission>;
|
|
1951
|
+
|
|
1343
1952
|
export declare const noteIntentAttempt: (store: AdmissionDataStore, intent: PendingIntent, error: string, now: number) => Promise<void>;
|
|
1344
1953
|
|
|
1345
1954
|
/**
|
|
@@ -1369,8 +1978,8 @@ export declare interface ParkDelayedStartInput {
|
|
|
1369
1978
|
readonly tenantId: string | null;
|
|
1370
1979
|
readonly queuedAppVersion?: string | null;
|
|
1371
1980
|
readonly queuedSchemaFingerprint?: string | null;
|
|
1372
|
-
/** Epoch ms the start becomes an ARRIVAL.
|
|
1373
|
-
*
|
|
1981
|
+
/** Epoch ms the start becomes an ARRIVAL. A transaction may enqueue for now;
|
|
1982
|
+
* the row is invisible to other connections until the business commit. */
|
|
1374
1983
|
readonly at: number;
|
|
1375
1984
|
readonly now: number;
|
|
1376
1985
|
}
|
|
@@ -1436,6 +2045,10 @@ declare type PayloadSchemaOf<P> = P extends Schema.Struct.Fields ? Schema.Struct
|
|
|
1436
2045
|
|
|
1437
2046
|
export declare const PENDING_TABLE = "_voltro_workflow_pending";
|
|
1438
2047
|
|
|
2048
|
+
/** Bounded recovery window. Only completed queue transfers may be dispatched;
|
|
2049
|
+
* a bare reservation does not prove that its selected rows were consumed. */
|
|
2050
|
+
export declare const pendingAdmissionSubmissions: (store: Pick<DataStore, "query">, limit: number, afterId?: string) => Promise<ReadonlyArray<AdmissionSubmission>>;
|
|
2051
|
+
|
|
1439
2052
|
/** Every hold currently parked — the operator's view, and the poller's input. */
|
|
1440
2053
|
export declare const pendingBudgetHolds: (store: DataStore, options?: {
|
|
1441
2054
|
readonly budget?: string;
|
|
@@ -1492,6 +2105,17 @@ export declare interface PendingIntent {
|
|
|
1492
2105
|
*/
|
|
1493
2106
|
export declare const pendingSlotId: (workflowName: string, mode: string, controlKey: string) => string;
|
|
1494
2107
|
|
|
2108
|
+
export declare interface PendingSubmissionInput {
|
|
2109
|
+
readonly id: string;
|
|
2110
|
+
readonly workflowName: string;
|
|
2111
|
+
readonly tenantId: string | null;
|
|
2112
|
+
readonly intentIds: ReadonlyArray<string>;
|
|
2113
|
+
readonly now: number;
|
|
2114
|
+
/** Pure schema/control preparation from the rows read INSIDE the transaction.
|
|
2115
|
+
* May run again after a database conflict. No engine or provider I/O. */
|
|
2116
|
+
readonly prepare: (intents: ReadonlyArray<PendingIntent>) => Omit<ReserveAdmissionSubmissionInput, 'id' | 'tenantId' | 'intentIds' | 'now'>;
|
|
2117
|
+
}
|
|
2118
|
+
|
|
1495
2119
|
/**
|
|
1496
2120
|
* The same read, plus the answer to "when is the next one due".
|
|
1497
2121
|
*
|
|
@@ -1533,6 +2157,10 @@ declare interface PersistDeferInput {
|
|
|
1533
2157
|
readonly existingId?: string;
|
|
1534
2158
|
}
|
|
1535
2159
|
|
|
2160
|
+
/** Internal database-only constructor for an admission already recorded in the
|
|
2161
|
+
* same transaction. Never re-evaluate capacity against that admission's lease. */
|
|
2162
|
+
declare const persistReservedSubmission: (tx: Pick<DataStore, "insert">, input: Pick<AdmissionSubmission, "id" | "workflowName" | "tenantId" | "ledgerId" | "payload" | "callerContext" | "intentIds" | "eviction">) => Promise<AdmissionSubmission>;
|
|
2163
|
+
|
|
1536
2164
|
/**
|
|
1537
2165
|
* Which runs and intents a batch of events cancels.
|
|
1538
2166
|
*
|
|
@@ -1546,16 +2174,20 @@ export declare const planCancellations: (input: CancelOnPlanInput) => CancelOnPl
|
|
|
1546
2174
|
/**
|
|
1547
2175
|
* The stored spelling of a concurrency key, pool-aware.
|
|
1548
2176
|
*
|
|
1549
|
-
*
|
|
1550
|
-
*
|
|
1551
|
-
*
|
|
1552
|
-
*
|
|
1553
|
-
* on purpose is sabotage, not a typo. Kept human-readable (not hashed) so a
|
|
1554
|
-
* ledger row's key still SAYS which pool it held — "why was this dropped" must
|
|
1555
|
-
* stay answerable by looking.
|
|
2177
|
+
* JSON tuples escape control characters (PostgreSQL text rejects NUL) and
|
|
2178
|
+
* preserve component boundaries. Encode unpooled keys too: a raw application
|
|
2179
|
+
* key must never impersonate a pooled tuple. Null identifies an unpooled key,
|
|
2180
|
+
* independently of every possible string-valued pool name.
|
|
1556
2181
|
*/
|
|
1557
2182
|
export declare const pooledConcurrencyKey: (pool: string | undefined, rawKey: string) => string;
|
|
1558
2183
|
|
|
2184
|
+
/** Bind the proposed application-derived execution identity before any engine
|
|
2185
|
+
* call. Compute the proposal outside this database-only transaction; after a
|
|
2186
|
+
* conflict, the first committed identity wins, never the retry's new proposal.
|
|
2187
|
+
* A previous unbound dispatch is uncertain and cannot safely acquire a new ID.
|
|
2188
|
+
* This records intent, not engine acceptance, and does not release capacity. */
|
|
2189
|
+
export declare const prepareAdmissionSubmissionExecutionInTransaction: (tx: Pick<DataStore, "query" | "update">, id: string, proposedExecutionId: string) => Promise<AdmissionSubmission>;
|
|
2190
|
+
|
|
1559
2191
|
/** Enqueue work and await the durable queue worker's result. */
|
|
1560
2192
|
export declare const processQueue: typeof durableQueueModule.process;
|
|
1561
2193
|
|
|
@@ -1570,6 +2202,10 @@ export declare const processQueue: typeof durableQueueModule.process;
|
|
|
1570
2202
|
*/
|
|
1571
2203
|
export declare const pruneAdmissions: (store: AdmissionDataStore, olderThan: Date, limit?: number) => Promise<number>;
|
|
1572
2204
|
|
|
2205
|
+
/** Resident entry consumes these requests. Public acceptance and recovery are
|
|
2206
|
+
* not wired yet. A persisted submission target is intent, not cancellation. */
|
|
2207
|
+
export declare const queuedCancellationRequestsTable: SchemaTable;
|
|
2208
|
+
|
|
1573
2209
|
/** Start a durable queue worker layer with bounded concurrency.
|
|
1574
2210
|
*
|
|
1575
2211
|
* `DurableQueue.worker` is itself generic (`<Payload, Success, Error, R>`), so
|
|
@@ -1592,6 +2228,8 @@ export declare const rateLimit: typeof durableRateLimiterModule.rateLimit;
|
|
|
1592
2228
|
*/
|
|
1593
2229
|
export declare const readAdmissionState: (input: ReadStateInput) => Promise<AdmissionState>;
|
|
1594
2230
|
|
|
2231
|
+
export declare const readAdmissionSubmission: (tx: Pick<DataStore, "query">, id: string) => Promise<AdmissionSubmission | undefined>;
|
|
2232
|
+
|
|
1595
2233
|
/**
|
|
1596
2234
|
* Every workflow name currently paused.
|
|
1597
2235
|
*
|
|
@@ -1607,6 +2245,10 @@ export declare const readAdmissionState: (input: ReadStateInput) => Promise<Admi
|
|
|
1607
2245
|
*/
|
|
1608
2246
|
export declare const readPausedWorkflows: (store: AdmissionDataStore) => Promise<ReadonlySet<string>>;
|
|
1609
2247
|
|
|
2248
|
+
/** Observe the original request without accepting, dispatching or repairing it.
|
|
2249
|
+
* It remains readable after the source receipt has been removed. */
|
|
2250
|
+
export declare const readQueuedWorkflowCancellationInTransaction: (tx: Pick<AdmissionDataStore, "query">, input: ResidentQueuedCancellationTarget) => Promise<WorkflowQueuedCancellationResult>;
|
|
2251
|
+
|
|
1610
2252
|
declare interface ReadStateInput {
|
|
1611
2253
|
readonly store: AdmissionDataStore;
|
|
1612
2254
|
readonly control: ResolvedFlowControl;
|
|
@@ -1618,6 +2260,48 @@ declare interface ReadStateInput {
|
|
|
1618
2260
|
/** Read the stored position for a sweep consumer. */
|
|
1619
2261
|
export declare const readWatermark: (store: CancelOnDataStore, name: string) => Promise<Date | undefined>;
|
|
1620
2262
|
|
|
2263
|
+
export declare const readWorkflowControlInTransaction: (tx: Pick<Store, "query">, id: string) => Promise<WorkflowControlRequest | undefined>;
|
|
2264
|
+
|
|
2265
|
+
/** Strict read: a damaged record is not an absent report. */
|
|
2266
|
+
export declare const readWorkflowFailureRecord: (tx: Pick<DataStore, "query">, id: string) => Promise<WorkflowFailureRecord | undefined>;
|
|
2267
|
+
|
|
2268
|
+
/** Strict lookup shared by receipt owners; a malformed receipt is not absent. */
|
|
2269
|
+
export declare const readWorkflowStartReceipt: (store: Pick<DataStore, "query">, id: string) => Promise<WorkflowStartReceipt | undefined>;
|
|
2270
|
+
|
|
2271
|
+
declare const ReceiptSchema: Schema.filter<Schema.Struct<{
|
|
2272
|
+
id: typeof Schema.String;
|
|
2273
|
+
workflowName: typeof Schema.String;
|
|
2274
|
+
tenantId: Schema.NullOr<typeof Schema.String>;
|
|
2275
|
+
pendingId: typeof Schema.String;
|
|
2276
|
+
submissionId: Schema.NullOr<typeof Schema.String>;
|
|
2277
|
+
terminal: Schema.NullOr<Schema.Union<[Schema.Struct<{
|
|
2278
|
+
kind: Schema.Literal<["dropped"]>;
|
|
2279
|
+
at: typeof Schema.Number;
|
|
2280
|
+
retryAfterMs: typeof Schema.Number;
|
|
2281
|
+
}>, Schema.Struct<{
|
|
2282
|
+
kind: Schema.Literal<["skipped"]>;
|
|
2283
|
+
at: typeof Schema.Number;
|
|
2284
|
+
executionId: typeof Schema.String;
|
|
2285
|
+
runId: typeof Schema.String;
|
|
2286
|
+
}>, Schema.Struct<{
|
|
2287
|
+
kind: Schema.Literal<["superseded"]>;
|
|
2288
|
+
at: typeof Schema.Number;
|
|
2289
|
+
}>, Schema.Struct<{
|
|
2290
|
+
kind: Schema.Literal<["cancelled"]>;
|
|
2291
|
+
at: typeof Schema.Number;
|
|
2292
|
+
}>, Schema.Struct<{
|
|
2293
|
+
kind: Schema.Literal<["abandoned"]>;
|
|
2294
|
+
at: typeof Schema.Number;
|
|
2295
|
+
failureId: typeof Schema.NonEmptyString;
|
|
2296
|
+
}>]>>;
|
|
2297
|
+
}>>;
|
|
2298
|
+
|
|
2299
|
+
/** Reconcile under the resident admission lock. Only a terminal pre-admission
|
|
2300
|
+
* drop/skip/supersession or proven pre-engine rejection permits a new arrival. Preserve every previous receipt and
|
|
2301
|
+
* the immutable report. Unknown or stopped engine acceptance never creates a
|
|
2302
|
+
* second submission. This is acceptance, not completion or provider delivery. */
|
|
2303
|
+
export declare const reconcileWorkflowFailureInTransaction: (tx: AdmissionDataStore, reportId: string, now: number) => Promise<WorkflowFailureDelivery>;
|
|
2304
|
+
|
|
1621
2305
|
/**
|
|
1622
2306
|
* Append one ledger row. Also the lease, when the outcome is `admitted`.
|
|
1623
2307
|
*
|
|
@@ -1683,6 +2367,27 @@ export declare interface RecordedStepShape {
|
|
|
1683
2367
|
readonly stepName: string;
|
|
1684
2368
|
}
|
|
1685
2369
|
|
|
2370
|
+
/** Database-only: call inside the resident admission transaction, together
|
|
2371
|
+
* with the source's terminal transition. Never notify the handler from here.
|
|
2372
|
+
* Replaying an identity keeps the first report AND recipient, even after a
|
|
2373
|
+
* deployment changes the handler or a new attempt supplies a later timestamp. */
|
|
2374
|
+
export declare const recordWorkflowFailureInTransaction: (tx: Pick<DataStore, "query" | "insert">, input: WorkflowFailureRecord) => Promise<WorkflowFailureRecord>;
|
|
2375
|
+
|
|
2376
|
+
/** Call inside the transaction that persists the pending start. The caller
|
|
2377
|
+
* allocates id once, before any retryable callback. pendingId is a reusable
|
|
2378
|
+
* queue slot; id is this caller's durable receipt and must not be that slot. */
|
|
2379
|
+
export declare const recordWorkflowStartReceipt: (tx: Pick<DataStore, "insertIgnoreWithOutcome">, input: Omit<WorkflowStartReceipt, "submissionId" | "terminal">) => Promise<WorkflowStartReceipt>;
|
|
2380
|
+
|
|
2381
|
+
/** Record proven pre-engine rejection together with its source and lease.
|
|
2382
|
+
* Attempt 0 means local validation before any engine call. Attempt 1 means the
|
|
2383
|
+
* first call returned a failure the host guarantees occurs before engine I/O.
|
|
2384
|
+
* A prior or competing attempt makes acceptance unknown, not rejected. */
|
|
2385
|
+
export declare const rejectAdmissionSubmissionInTransaction: (tx: AdmissionDataStore, id: string, attempt: number, failure: {
|
|
2386
|
+
readonly handler: string | null;
|
|
2387
|
+
readonly errorMessage: string;
|
|
2388
|
+
readonly now: number;
|
|
2389
|
+
}) => Promise<WorkflowFailureRecord | undefined>;
|
|
2390
|
+
|
|
1686
2391
|
/**
|
|
1687
2392
|
* Resume every run parked on `budget`.
|
|
1688
2393
|
*
|
|
@@ -1753,9 +2458,83 @@ export declare interface ReplayShapeTracker {
|
|
|
1753
2458
|
*/
|
|
1754
2459
|
export declare const reportNondeterminism: (findings: ReadonlyArray<NondeterminismFinding>) => Effect.Effect<void>;
|
|
1755
2460
|
|
|
2461
|
+
declare const RequestSchema: Schema.Struct<{
|
|
2462
|
+
id: Schema.filter<typeof Schema.String>;
|
|
2463
|
+
runId: Schema.filter<typeof Schema.String>;
|
|
2464
|
+
workflowName: Schema.filter<typeof Schema.String>;
|
|
2465
|
+
executionId: Schema.filter<typeof Schema.String>;
|
|
2466
|
+
generation: Schema.filter<typeof Schema.String>;
|
|
2467
|
+
operation: Schema.Literal<["cancel", "terminate", "resume"]>;
|
|
2468
|
+
requestedAt: Schema.filter<typeof Schema.Number>;
|
|
2469
|
+
/** Null means no proven owner, not a null-tenant owner. */
|
|
2470
|
+
owner: Schema.NullOr<Schema.Struct<{
|
|
2471
|
+
tenantId: Schema.NullOr<typeof Schema.String>;
|
|
2472
|
+
}>>;
|
|
2473
|
+
cause: Schema.optional<Schema.NullOr<Schema.Struct<{
|
|
2474
|
+
reason: typeof Schema.NonEmptyString;
|
|
2475
|
+
detail: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
|
|
2476
|
+
}>>>;
|
|
2477
|
+
dispatchAttempts: Schema.filter<Schema.filter<typeof Schema.Number>>;
|
|
2478
|
+
resumeJournal: Schema.NullOr<Schema.Struct<{
|
|
2479
|
+
requestId: Schema.filter<typeof Schema.String>;
|
|
2480
|
+
replyId: Schema.filter<typeof Schema.String>;
|
|
2481
|
+
restartToken: Schema.NullOr<typeof Schema.NonEmptyString>;
|
|
2482
|
+
}>>;
|
|
2483
|
+
result: Schema.NullOr<Schema.Union<[Schema.Struct<{
|
|
2484
|
+
kind: Schema.Literal<["confirmed", "already-terminal"]>;
|
|
2485
|
+
status: Schema.Literal<["succeeded", "failed", "cancelled"]>;
|
|
2486
|
+
completedAt: Schema.filter<typeof Schema.Number>;
|
|
2487
|
+
output: typeof Schema.Unknown;
|
|
2488
|
+
errorTag: Schema.NullOr<typeof Schema.String>;
|
|
2489
|
+
errorMessage: Schema.NullOr<typeof Schema.String>;
|
|
2490
|
+
}>, Schema.Struct<{
|
|
2491
|
+
kind: Schema.Literal<["confirmed"]>;
|
|
2492
|
+
status: Schema.Literal<["running"]>;
|
|
2493
|
+
enteredAt: Schema.filter<typeof Schema.Number>;
|
|
2494
|
+
generation: Schema.filter<typeof Schema.String>;
|
|
2495
|
+
}>]>>;
|
|
2496
|
+
}>;
|
|
2497
|
+
|
|
2498
|
+
/** Reserve once, before engine I/O. The identity lookup precedes admission:
|
|
2499
|
+
* otherwise a retry would wait forever for the slot its own submission holds.
|
|
2500
|
+
* This primitive only persists a reservation; queue consumption and durable
|
|
2501
|
+
* engine acknowledgement belong to the submission dispatcher. */
|
|
2502
|
+
export declare const reserveAdmissionSubmission: (store: Pick<DataStore, "insertIgnoreWithOutcome" | "transactional">, input: ReserveAdmissionSubmissionInput) => Promise<ReserveAdmissionSubmissionResult>;
|
|
2503
|
+
|
|
2504
|
+
export declare interface ReserveAdmissionSubmissionInput {
|
|
2505
|
+
/** Stable identity of this submission, independent of the process attempting it. */
|
|
2506
|
+
readonly id: string;
|
|
2507
|
+
readonly control: ResolvedFlowControl;
|
|
2508
|
+
/** Decoded input used only to resolve the flow-control keys. */
|
|
2509
|
+
readonly keyPayload: unknown;
|
|
2510
|
+
/** Schema-encoded complete engine input, including the selected batch items. */
|
|
2511
|
+
readonly encodedPayload: unknown;
|
|
2512
|
+
readonly callerContext: unknown;
|
|
2513
|
+
readonly intentIds: ReadonlyArray<string>;
|
|
2514
|
+
readonly tenantId: string | null;
|
|
2515
|
+
readonly paused: boolean;
|
|
2516
|
+
readonly now: number;
|
|
2517
|
+
readonly firstSeenAt: number;
|
|
2518
|
+
readonly collapsed: number;
|
|
2519
|
+
readonly mode: string | null;
|
|
2520
|
+
}
|
|
2521
|
+
|
|
2522
|
+
export declare type ReserveAdmissionSubmissionResult = {
|
|
2523
|
+
readonly kind: 'reserved';
|
|
2524
|
+
readonly submission: AdmissionSubmission;
|
|
2525
|
+
readonly reused: boolean;
|
|
2526
|
+
} | {
|
|
2527
|
+
readonly kind: 'not-admitted';
|
|
2528
|
+
readonly decision: Exclude<AdmissionDecision, {
|
|
2529
|
+
kind: 'admit';
|
|
2530
|
+
}>;
|
|
2531
|
+
};
|
|
2532
|
+
|
|
1756
2533
|
/** Test seam: forget which (workflow, signal) pairs have been hinted. */
|
|
1757
2534
|
export declare const resetSuspendHintsForTest: () => void;
|
|
1758
2535
|
|
|
2536
|
+
export declare type ResidentQueuedCancellationTarget = typeof Target.Type;
|
|
2537
|
+
|
|
1759
2538
|
/** Resolve every declared key against one payload. Pure; throws only
|
|
1760
2539
|
* {@link FlowControlKeyError}. */
|
|
1761
2540
|
export declare const resolveAdmissionKeys: (control: ResolvedFlowControl, payload: unknown) => AdmissionKeys;
|
|
@@ -1859,6 +2638,15 @@ export declare const resolveSuspendHintMs: () => number;
|
|
|
1859
2638
|
|
|
1860
2639
|
export declare const resolveWorkflowMessageRun: (store: WorkflowMessageStore, target: WorkflowMessageTarget) => Promise<WorkflowResolvedRun>;
|
|
1861
2640
|
|
|
2641
|
+
/** Read inside the resident admission transaction. A prepared identity is not
|
|
2642
|
+
* an acceptance acknowledgement; an absent or contradictory owner is not a
|
|
2643
|
+
* pending start. Tenant authority is supplied by the caller, never the receipt. */
|
|
2644
|
+
export declare const resolveWorkflowStartReceipt: (tx: Pick<DataStore, "query">, input: {
|
|
2645
|
+
readonly receiptId: string;
|
|
2646
|
+
readonly workflowName: string;
|
|
2647
|
+
readonly tenantId: string | null;
|
|
2648
|
+
}) => Promise<WorkflowStartResolution>;
|
|
2649
|
+
|
|
1862
2650
|
export declare const resumeWorkflow: (store: AdmissionDataStore, workflowName: string) => Promise<boolean>;
|
|
1863
2651
|
|
|
1864
2652
|
/** Re-arm one dead-lettered intent after an operator has deployed a schema or
|
|
@@ -1902,7 +2690,14 @@ export declare interface ShardLockHolder {
|
|
|
1902
2690
|
/** Who holds it: `pid <n> from <client>` for a postgres advisory lock, the
|
|
1903
2691
|
* runner address for a row lease. */
|
|
1904
2692
|
readonly holder: string;
|
|
1905
|
-
/**
|
|
2693
|
+
/**
|
|
2694
|
+
* `true` when THIS runner holds the shard — the engine's own answer
|
|
2695
|
+
* (`Sharding.hasShardId`), never a guess from a connection. The first
|
|
2696
|
+
* version compared the holder's pid with `pg_backend_pid()` of the query
|
|
2697
|
+
* that asked, and the pool hands every query a different backend than the
|
|
2698
|
+
* lock session, so a runner's own 300 locks read as a stranger's — and the
|
|
2699
|
+
* report's lever, ending the holder's session, would have ended the runner.
|
|
2700
|
+
*/
|
|
1906
2701
|
readonly own: boolean;
|
|
1907
2702
|
readonly since: Date | null;
|
|
1908
2703
|
readonly detail?: Record<string, unknown>;
|
|
@@ -1948,11 +2743,27 @@ export declare const sleepUntil: (options: {
|
|
|
1948
2743
|
readonly until: Date | number;
|
|
1949
2744
|
}) => Effect.Effect<void, never, never>;
|
|
1950
2745
|
|
|
2746
|
+
/** Database-only recovery step. The saved cursor and child control requests
|
|
2747
|
+
* commit together. A receipt belongs to the first observed child generation;
|
|
2748
|
+
* replay must never retarget it from a replacement row. Only a complete scan
|
|
2749
|
+
* observing no open bound children completes the closure. Entry checks remain
|
|
2750
|
+
* active after completion, so late children cannot escape this scan. */
|
|
2751
|
+
export declare const stageWorkflowParentClosureInTransaction: (tx: AdmissionDataStore, closureId: string, now?: number) => Promise<{
|
|
2752
|
+
readonly scanned: number;
|
|
2753
|
+
readonly controls: number;
|
|
2754
|
+
readonly wrapped: boolean;
|
|
2755
|
+
}>;
|
|
2756
|
+
|
|
1951
2757
|
/** The narrow store slice this needs. Structural, like `CancelOnDataStore`. */
|
|
1952
2758
|
export declare interface StalenessDataStore {
|
|
1953
2759
|
query(descriptor: QueryDescriptor): Promise<ReadonlyArray<Row>>;
|
|
1954
2760
|
}
|
|
1955
2761
|
|
|
2762
|
+
export declare interface StalenessRunCursor {
|
|
2763
|
+
readonly startedAt: Date;
|
|
2764
|
+
readonly runId: string;
|
|
2765
|
+
}
|
|
2766
|
+
|
|
1956
2767
|
export declare interface StalenessSweepDeps {
|
|
1957
2768
|
readonly store: StalenessDataStore;
|
|
1958
2769
|
/**
|
|
@@ -1988,6 +2799,9 @@ export declare interface StalenessSweepOptions {
|
|
|
1988
2799
|
readonly stallAfterMs?: number;
|
|
1989
2800
|
readonly runPage?: number;
|
|
1990
2801
|
readonly eventLookback?: number;
|
|
2802
|
+
/** Continue one physical store's oldest-first census. Omit after exhaustion
|
|
2803
|
+
* to revisit runs which have since made progress or become stale again. */
|
|
2804
|
+
readonly afterRun?: StalenessRunCursor;
|
|
1991
2805
|
}
|
|
1992
2806
|
|
|
1993
2807
|
export declare interface StalenessSweepResult {
|
|
@@ -2001,14 +2815,16 @@ export declare interface StalenessSweepResult {
|
|
|
2001
2815
|
readonly alreadyReported: number;
|
|
2002
2816
|
/** Excluded because they are inside a durable timer that has not come due. */
|
|
2003
2817
|
readonly waitingOnTimer: number;
|
|
2004
|
-
/** The candidate page filled up:
|
|
2005
|
-
*
|
|
2006
|
-
* distinguish it from "nothing else was old". */
|
|
2818
|
+
/** The candidate page filled up: another page must be checked before the
|
|
2819
|
+
* census can claim exhaustion. That next page may be empty. */
|
|
2007
2820
|
readonly sawFullRunPage: boolean;
|
|
2008
2821
|
readonly failures: ReadonlyArray<{
|
|
2009
2822
|
readonly subject: string;
|
|
2010
2823
|
readonly detail: string;
|
|
2011
2824
|
}>;
|
|
2825
|
+
/** Present when the candidate page filled. Keep per physical store, not per
|
|
2826
|
+
* replica or workflow. A failed candidate read does not advance the cursor. */
|
|
2827
|
+
readonly nextRun?: StalenessRunCursor;
|
|
2012
2828
|
}
|
|
2013
2829
|
|
|
2014
2830
|
export declare interface StalledRun {
|
|
@@ -2149,6 +2965,34 @@ export declare interface StepRetryPolicy {
|
|
|
2149
2965
|
readonly note?: string;
|
|
2150
2966
|
}
|
|
2151
2967
|
|
|
2968
|
+
declare type Store = Pick<DataStore, 'query' | 'insert' | 'update'>;
|
|
2969
|
+
|
|
2970
|
+
declare const SubmissionSchema: Schema.Struct<{
|
|
2971
|
+
id: typeof Schema.String;
|
|
2972
|
+
workflowName: typeof Schema.String;
|
|
2973
|
+
tenantId: Schema.NullOr<typeof Schema.String>;
|
|
2974
|
+
ledgerId: typeof Schema.String;
|
|
2975
|
+
preparedExecutionId: Schema.NullOr<typeof Schema.String>;
|
|
2976
|
+
executionId: Schema.NullOr<typeof Schema.String>;
|
|
2977
|
+
runId: Schema.NullOr<typeof Schema.String>;
|
|
2978
|
+
receiptsBound: typeof Schema.Boolean;
|
|
2979
|
+
dispatchAttempts: Schema.refine<number, typeof Schema.NonNegative>;
|
|
2980
|
+
failureId: Schema.NullOr<typeof Schema.String>;
|
|
2981
|
+
retry: Schema.Struct<{
|
|
2982
|
+
attempts: typeof Schema.Int;
|
|
2983
|
+
after: typeof Schema.Number;
|
|
2984
|
+
lastError: Schema.NullOr<typeof Schema.String>;
|
|
2985
|
+
stoppedAt: Schema.NullOr<typeof Schema.Number>;
|
|
2986
|
+
}>;
|
|
2987
|
+
payload: typeof Schema.Unknown;
|
|
2988
|
+
callerContext: typeof Schema.Unknown;
|
|
2989
|
+
intentIds: Schema.Array$<typeof Schema.String>;
|
|
2990
|
+
eviction: Schema.NullOr<Schema.Struct<{
|
|
2991
|
+
executionId: typeof Schema.String;
|
|
2992
|
+
runId: typeof Schema.String;
|
|
2993
|
+
}>>;
|
|
2994
|
+
}>;
|
|
2995
|
+
|
|
2152
2996
|
/**
|
|
2153
2997
|
* Park the run until the budget has headroom.
|
|
2154
2998
|
*
|
|
@@ -2243,6 +3087,50 @@ export declare const sweepCancelOn: (deps: CancelOnSweepDeps, options: CancelOnS
|
|
|
2243
3087
|
*/
|
|
2244
3088
|
export declare const sweepStalledRuns: (deps: StalenessSweepDeps, options?: StalenessSweepOptions) => Promise<StalenessSweepResult>;
|
|
2245
3089
|
|
|
3090
|
+
/** Transfer an arrival already admitted under THIS transaction. Unlike a due
|
|
3091
|
+
* queue drain, a size-closing batch may consume inputs before their timeout.
|
|
3092
|
+
* The caller supplies the encoded payload derived under this same lock. */
|
|
3093
|
+
export declare const takeAdmittedSubmissionInTransaction: (tx: AdmissionDataStore, input: Parameters<typeof persistReservedSubmission>[1]) => Promise<{
|
|
3094
|
+
readonly id: string;
|
|
3095
|
+
readonly tenantId: string | null;
|
|
3096
|
+
readonly retry: {
|
|
3097
|
+
readonly lastError: string | null;
|
|
3098
|
+
readonly attempts: number;
|
|
3099
|
+
readonly after: number;
|
|
3100
|
+
readonly stoppedAt: number | null;
|
|
3101
|
+
};
|
|
3102
|
+
readonly payload: unknown;
|
|
3103
|
+
readonly executionId: string | null;
|
|
3104
|
+
readonly runId: string | null;
|
|
3105
|
+
readonly failureId: string | null;
|
|
3106
|
+
readonly workflowName: string;
|
|
3107
|
+
readonly dispatchAttempts: number;
|
|
3108
|
+
readonly callerContext: unknown;
|
|
3109
|
+
readonly intentIds: readonly string[];
|
|
3110
|
+
readonly ledgerId: string;
|
|
3111
|
+
readonly receiptsBound: boolean;
|
|
3112
|
+
readonly preparedExecutionId: string | null;
|
|
3113
|
+
readonly eviction: {
|
|
3114
|
+
readonly executionId: string;
|
|
3115
|
+
readonly runId: string;
|
|
3116
|
+
} | null;
|
|
3117
|
+
}>;
|
|
3118
|
+
|
|
3119
|
+
/** Resident queue takeover. A competing transfer that already consumed any
|
|
3120
|
+
* selected row invalidates the selection, rather than silently starting a
|
|
3121
|
+
* smaller batch. Existing submission identity wins before looking at reusable
|
|
3122
|
+
* queue slots; a retry cannot consume a later debounce burst. */
|
|
3123
|
+
export declare const takePendingAdmissionSubmission: (store: Pick<DataStore, "insertIgnoreWithOutcome" | "transactional">, input: PendingSubmissionInput) => Promise<ReserveAdmissionSubmissionResult | {
|
|
3124
|
+
readonly kind: "selection-unavailable";
|
|
3125
|
+
}>;
|
|
3126
|
+
|
|
3127
|
+
declare const Target: Schema.Struct<{
|
|
3128
|
+
requestId: typeof Schema.NonEmptyString;
|
|
3129
|
+
receiptId: typeof Schema.NonEmptyString;
|
|
3130
|
+
workflowName: typeof Schema.NonEmptyString;
|
|
3131
|
+
tenantId: Schema.NullOr<typeof Schema.String>;
|
|
3132
|
+
}>;
|
|
3133
|
+
|
|
2246
3134
|
export declare const truncateWorkflowValue: (value: unknown, bytes?: number) => unknown;
|
|
2247
3135
|
|
|
2248
3136
|
export declare interface UnreadMessage extends ClusterMessageState {
|
|
@@ -2283,6 +3171,10 @@ export declare const validateWorkflowSchedule: (workflowName: string, declaratio
|
|
|
2283
3171
|
*/
|
|
2284
3172
|
export declare const _voltroBudgetHoldsTable: TableLike;
|
|
2285
3173
|
|
|
3174
|
+
/** One coordination row per physical admission ledger, not per tenant/pool.
|
|
3175
|
+
* Contains no payload or caller identity. Held only during database decisions. */
|
|
3176
|
+
export declare const _voltroWorkflowAdmissionLocksTable: SchemaTable;
|
|
3177
|
+
|
|
2286
3178
|
/**
|
|
2287
3179
|
* `_voltro_workflow_admissions` — append-only ledger, and the lease register.
|
|
2288
3180
|
*
|
|
@@ -2292,6 +3184,19 @@ export declare const _voltroBudgetHoldsTable: TableLike;
|
|
|
2292
3184
|
*/
|
|
2293
3185
|
export declare const _voltroWorkflowAdmissionsTable: SchemaTable;
|
|
2294
3186
|
|
|
3187
|
+
/** Resident control identity and attempted delivery, distinct from the run's
|
|
3188
|
+
* outcome. An attempted interrupt is not a confirmed cancellation. */
|
|
3189
|
+
export declare const _voltroWorkflowControlRequestsTable: SchemaTable;
|
|
3190
|
+
|
|
3191
|
+
/** Resident, immutable incidents. Persistence is not handler delivery; the
|
|
3192
|
+
* delivery lifecycle must not overwrite the report or its original recipient. */
|
|
3193
|
+
export declare const _voltroWorkflowFailureReportsTable: SchemaTable;
|
|
3194
|
+
|
|
3195
|
+
/** Durable child-close work, committed with its parent generation's terminal
|
|
3196
|
+
* outcome. Also prevents body re-entry after run-history retention. No payload
|
|
3197
|
+
* or caller credentials; never cascade from runs or expire completed scans. */
|
|
3198
|
+
export declare const _voltroWorkflowParentClosuresTable: SchemaTable;
|
|
3199
|
+
|
|
2295
3200
|
/**
|
|
2296
3201
|
* `_voltro_workflow_pauses` — one row per PAUSED workflow. Absent ⇒ running.
|
|
2297
3202
|
*
|
|
@@ -2324,10 +3229,24 @@ export declare const _voltroWorkflowRunStepsTable: SchemaTable;
|
|
|
2324
3229
|
|
|
2325
3230
|
export declare const _voltroWorkflowStartContextsTable: TableLike;
|
|
2326
3231
|
|
|
3232
|
+
/** A caller's identity survives removal and later reuse of a debounce slot. */
|
|
3233
|
+
export declare const _voltroWorkflowStartReceiptsTable: SchemaTable;
|
|
3234
|
+
|
|
3235
|
+
/** Immutable engine submissions live in the same physical store as their queue
|
|
3236
|
+
* payloads. A reservation retry reads this row instead of taking another lease. */
|
|
3237
|
+
export declare const _voltroWorkflowSubmissionsTable: SchemaTable;
|
|
3238
|
+
|
|
2327
3239
|
export declare const _voltroWorkflowWatermarksTable: SchemaTable;
|
|
2328
3240
|
|
|
2329
3241
|
export declare const WATERMARKS_TABLE = "_voltro_workflow_watermarks";
|
|
2330
3242
|
|
|
3243
|
+
/** Serialize database-only admission decisions. Never call the engine or a
|
|
3244
|
+
* provider from work: the store can replay it after a transaction conflict.
|
|
3245
|
+
* Bootstrap is outside the transaction so a MySQL consistent read performed
|
|
3246
|
+
* by insertIgnore cannot establish a stale snapshot before the locking read.
|
|
3247
|
+
* The nonce write also makes optimistic memory transactions conflict. */
|
|
3248
|
+
export declare const withAdmissionTransaction: <A>(store: Pick<DataStore, "insertIgnoreWithOutcome" | "transactional">, work: (tx: DataStore) => Promise<A>) => Promise<A>;
|
|
3249
|
+
|
|
2331
3250
|
/**
|
|
2332
3251
|
* Add compensating (rollback) logic to a top-level effect in a workflow
|
|
2333
3252
|
* body. The finalizer runs if the WHOLE workflow later fails — use it for
|
|
@@ -2538,6 +3457,8 @@ export declare interface WorkflowConcurrency<Payload> {
|
|
|
2538
3457
|
readonly pool?: string;
|
|
2539
3458
|
}
|
|
2540
3459
|
|
|
3460
|
+
export declare type WorkflowControlRequest = typeof RequestSchema.Type;
|
|
3461
|
+
|
|
2541
3462
|
/**
|
|
2542
3463
|
* Collapse a burst of starts into ONE run, `period` after the last one.
|
|
2543
3464
|
*
|
|
@@ -2570,6 +3491,21 @@ export declare interface WorkflowDebounce<Payload> {
|
|
|
2570
3491
|
}
|
|
2571
3492
|
|
|
2572
3493
|
export declare interface WorkflowExecuteRecordingOptions extends WorkflowRunRecorderOptions {
|
|
3494
|
+
readonly store: WorkflowRecordingStore & Required<Pick<WorkflowRecordingStore, 'query'>>;
|
|
3495
|
+
/** Encode the full decoded workflow input before storing its durable run
|
|
3496
|
+
* payload. Hosts omitting this callback accept JSON-only inputs. Never use
|
|
3497
|
+
* the batch-item schema here: the body receives the complete batch. */
|
|
3498
|
+
readonly encodePayload?: (payload: unknown) => unknown;
|
|
3499
|
+
/** Same resident store as `store`, under the shared admission lock. The
|
|
3500
|
+
* database-only callback may replay; never run application code inside it. */
|
|
3501
|
+
readonly transaction: <T>(work: (tx: AdmissionDataStore) => Promise<T>) => Promise<T>;
|
|
3502
|
+
/** Bound identity for durable failure delivery. Omitted by standalone hosts
|
|
3503
|
+
* without a failure handler; framework boot paths provide the resolved caller. */
|
|
3504
|
+
readonly failureContext?: {
|
|
3505
|
+
readonly handler: string | null;
|
|
3506
|
+
readonly callerContext: unknown;
|
|
3507
|
+
readonly tenantId: string | null;
|
|
3508
|
+
};
|
|
2573
3509
|
readonly name: string;
|
|
2574
3510
|
readonly subject?: unknown;
|
|
2575
3511
|
readonly source?: string | null;
|
|
@@ -2578,6 +3514,7 @@ export declare interface WorkflowExecuteRecordingOptions extends WorkflowRunReco
|
|
|
2578
3514
|
readonly workflowCompatibleVersions?: ReadonlyArray<string> | null;
|
|
2579
3515
|
readonly workflowPatches?: ReadonlyArray<string> | null;
|
|
2580
3516
|
readonly parentExecutionId?: string | null;
|
|
3517
|
+
readonly parentGeneration?: string | null;
|
|
2581
3518
|
readonly parentClosePolicy?: WorkflowParentClosePolicy | null;
|
|
2582
3519
|
readonly onParentClose?: (input: {
|
|
2583
3520
|
readonly workflowName: string;
|
|
@@ -2587,30 +3524,15 @@ export declare interface WorkflowExecuteRecordingOptions extends WorkflowRunReco
|
|
|
2587
3524
|
}) => Promise<void>;
|
|
2588
3525
|
readonly recorder?: WorkflowRunRecorderService;
|
|
2589
3526
|
readonly pluginWorkflowStepLayer?: Layer.Layer<any, never, never>;
|
|
2590
|
-
/**
|
|
2591
|
-
*
|
|
2592
|
-
*
|
|
2593
|
-
*
|
|
2594
|
-
* It exists to free the run's admission lease. That lease is what a
|
|
2595
|
-
* `concurrency` limit counts, so a terminal transition that does not release
|
|
2596
|
-
* it does not error, log, or fail a test — the limit simply admits one fewer
|
|
2597
|
-
* run, permanently, and then one fewer again. A deployment that slowly stops
|
|
2598
|
-
* doing work with nothing pointing at why.
|
|
2599
|
-
*
|
|
2600
|
-
* Called on success AND on failure, and DELIBERATELY not on suspend: a
|
|
2601
|
-
* suspended run is still holding the resource it was admitted for.
|
|
2602
|
-
*
|
|
2603
|
-
* On a failure it also carries the payload and the error, so the caller
|
|
2604
|
-
* can raise the workflow's `onFailure` — the one route into that signal
|
|
2605
|
-
* that produces a `failed` row, and the one that was not wired: the
|
|
2606
|
-
* flow-control paths (an expired start, a finish timeout, a dead-lettered
|
|
2607
|
-
* intent) notified, and a body that failed did not.
|
|
2608
|
-
*/
|
|
3527
|
+
/** Observation after a committed terminal transition, never an admission or
|
|
3528
|
+
* failure-delivery writer. The resident transaction already records the
|
|
3529
|
+
* failure arrival and releases capacity. Not called for superseded results
|
|
3530
|
+
* or failed commits; callback failure cannot undo a committed outcome. */
|
|
2609
3531
|
readonly onTerminal?: (input: {
|
|
2610
3532
|
readonly workflowName: string;
|
|
2611
3533
|
readonly executionId: string;
|
|
2612
3534
|
readonly runId?: string;
|
|
2613
|
-
readonly status: 'succeeded' | 'failed';
|
|
3535
|
+
readonly status: 'succeeded' | 'failed' | 'cancelled';
|
|
2614
3536
|
/** The run's payload — present on `failed`, for the failure report. */
|
|
2615
3537
|
readonly payload?: unknown;
|
|
2616
3538
|
readonly errorTag?: string | null;
|
|
@@ -2649,6 +3571,28 @@ export declare interface WorkflowExecuteRecordingOptions extends WorkflowRunReco
|
|
|
2649
3571
|
readonly replayShapeLimit?: number;
|
|
2650
3572
|
}
|
|
2651
3573
|
|
|
3574
|
+
export declare type WorkflowFailureDelivery = WorkflowFailureHandoff | {
|
|
3575
|
+
readonly kind: 'accepted';
|
|
3576
|
+
readonly executionId: string;
|
|
3577
|
+
} | {
|
|
3578
|
+
readonly kind: 'cancelled';
|
|
3579
|
+
readonly receiptId: string;
|
|
3580
|
+
};
|
|
3581
|
+
|
|
3582
|
+
export declare type WorkflowFailureHandoff = {
|
|
3583
|
+
readonly kind: 'unconfigured';
|
|
3584
|
+
} | {
|
|
3585
|
+
readonly kind: 'queued';
|
|
3586
|
+
readonly receiptId: string;
|
|
3587
|
+
readonly intentId: string;
|
|
3588
|
+
};
|
|
3589
|
+
|
|
3590
|
+
/** Low-level persistence foundation. A record proves the failure was recorded,
|
|
3591
|
+
* not that its handler accepted or completed it. Payload must be schema-encoded.
|
|
3592
|
+
* The source's owner allocates one identity before entering a retryable
|
|
3593
|
+
* transaction; reusable debounce slots are not permanent incident identities. */
|
|
3594
|
+
export declare type WorkflowFailureRecord = typeof FailureRecordSchema.Type;
|
|
3595
|
+
|
|
2652
3596
|
/**
|
|
2653
3597
|
* What an `onFailure` workflow receives. Declare it as that workflow's
|
|
2654
3598
|
* `payload` schema — the framework validates against it like any other start,
|
|
@@ -2852,33 +3796,8 @@ export declare interface WorkflowMessageTarget {
|
|
|
2852
3796
|
|
|
2853
3797
|
export { workflowModule }
|
|
2854
3798
|
|
|
2855
|
-
export declare interface WorkflowParentCloseDecision {
|
|
2856
|
-
readonly runId: string;
|
|
2857
|
-
readonly workflowName: string;
|
|
2858
|
-
readonly executionId: string;
|
|
2859
|
-
readonly policy: WorkflowParentClosePolicy | null;
|
|
2860
|
-
readonly action: 'cancelled' | 'abandoned' | 'skipped' | 'failed';
|
|
2861
|
-
readonly reason?: string;
|
|
2862
|
-
}
|
|
2863
|
-
|
|
2864
|
-
export declare interface WorkflowParentCloseEmitter {
|
|
2865
|
-
emit(channel: 'workflowRuns' | 'workflowSteps' | 'workflowEvents', event: {
|
|
2866
|
-
readonly op: 'insert' | 'update';
|
|
2867
|
-
readonly row: Record<string, unknown>;
|
|
2868
|
-
}): void;
|
|
2869
|
-
}
|
|
2870
|
-
|
|
2871
|
-
export declare interface WorkflowParentCloseLogger {
|
|
2872
|
-
warn(message: string, fields?: Record<string, unknown>): void;
|
|
2873
|
-
}
|
|
2874
|
-
|
|
2875
3799
|
export declare type WorkflowParentCloseStatus = 'succeeded' | 'failed' | 'cancelled';
|
|
2876
3800
|
|
|
2877
|
-
export declare interface WorkflowParentCloseStore {
|
|
2878
|
-
query(descriptor: QueryDescriptor): Promise<ReadonlyArray<unknown>>;
|
|
2879
|
-
update(table: string, id: string, patch: unknown): Promise<unknown | null>;
|
|
2880
|
-
}
|
|
2881
|
-
|
|
2882
3801
|
/** Everything `Workflow.make` accepts for `payload`: a struct Schema, or bare
|
|
2883
3802
|
* `Fields`. Both stay supported — a key lambda must not silently degrade to
|
|
2884
3803
|
* `any` because the workflow spelled its payload the shorter way. */
|
|
@@ -2925,6 +3844,28 @@ export declare interface WorkflowResolvedRun {
|
|
|
2925
3844
|
readonly tag?: string;
|
|
2926
3845
|
}
|
|
2927
3846
|
|
|
3847
|
+
export declare interface WorkflowRunCompletion {
|
|
3848
|
+
readonly owner: WorkflowRunGeneration;
|
|
3849
|
+
readonly now: number;
|
|
3850
|
+
readonly durationMs: number;
|
|
3851
|
+
readonly outcome: {
|
|
3852
|
+
readonly status: 'succeeded';
|
|
3853
|
+
readonly output: unknown;
|
|
3854
|
+
}
|
|
3855
|
+
/** Only a confirmed exit of this body generation. A void interrupt reply
|
|
3856
|
+
* is not confirmation and must never be passed as this outcome. */
|
|
3857
|
+
| {
|
|
3858
|
+
readonly status: 'cancelled';
|
|
3859
|
+
} | {
|
|
3860
|
+
readonly status: 'failed';
|
|
3861
|
+
readonly errorTag: string | null;
|
|
3862
|
+
readonly errorMessage: string | null;
|
|
3863
|
+
readonly handler: string | null;
|
|
3864
|
+
readonly callerContext: unknown;
|
|
3865
|
+
readonly tenantId: string | null;
|
|
3866
|
+
};
|
|
3867
|
+
}
|
|
3868
|
+
|
|
2928
3869
|
/**
|
|
2929
3870
|
* Closed enumeration of event types the framework knows how to emit.
|
|
2930
3871
|
* Kept here (not in `runEventsTable.ts`) so callers in the recorder
|
|
@@ -2938,7 +3879,10 @@ export declare type WorkflowRunEventType = 'run-started' | 'run-suspended' | 'ru
|
|
|
2938
3879
|
* `payload` carries `{ reason, activitiesReset }` — how many failed step
|
|
2939
3880
|
* attempts were reset so they re-execute (completed steps replay). Distinct
|
|
2940
3881
|
* from `run-resumed`, which continues a *suspended* run. */
|
|
2941
|
-
| 'run-redriven' | 'run-cancelled'
|
|
3882
|
+
| 'run-redriven' | 'run-cancelled'
|
|
3883
|
+
/** Durable receipt settlement, including the original control cause. This
|
|
3884
|
+
* is not a second run transition or proof that a late request caused it. */
|
|
3885
|
+
| 'control-settled' | 'run-succeeded' | 'run-failed'
|
|
2942
3886
|
/** Emitted when `sleep({ name, duration })` enters the wait — `payload`
|
|
2943
3887
|
* carries `{ name, durationMs, scheduledWakeAt }`. The dashboard
|
|
2944
3888
|
* Gantt renders these as a hatched bar in the timeline so a
|
|
@@ -2998,13 +3942,22 @@ export declare type WorkflowRunEventType = 'run-started' | 'run-suspended' | 'ru
|
|
|
2998
3942
|
* lastProgressAt, reason }`. Diagnostic only — the run is untouched. */
|
|
2999
3943
|
| 'run-stalled';
|
|
3000
3944
|
|
|
3945
|
+
export declare interface WorkflowRunGeneration {
|
|
3946
|
+
readonly runId: string;
|
|
3947
|
+
readonly workflowName: string;
|
|
3948
|
+
readonly executionId: string;
|
|
3949
|
+
/** Allocate once before entering the replayable transaction. Not a timestamp
|
|
3950
|
+
* or a reclaim counter: both may repeat across distinct body entries. */
|
|
3951
|
+
readonly generation: string;
|
|
3952
|
+
}
|
|
3953
|
+
|
|
3001
3954
|
/** A workflow run's TERMINAL outcome, handed to the metrics hook. Kept local to
|
|
3002
3955
|
* this package (structurally matching `@voltro/runtime`'s `WorkflowRunRecord`) so
|
|
3003
3956
|
* the workflow package stays free of a `@voltro/runtime` dependency — the CLI
|
|
3004
3957
|
* wiring supplies a `recordRun` that forwards to `recordWorkflowRun`. */
|
|
3005
3958
|
declare interface WorkflowRunOutcome {
|
|
3006
3959
|
readonly name: string;
|
|
3007
|
-
readonly status: 'succeeded' | 'failed';
|
|
3960
|
+
readonly status: 'succeeded' | 'failed' | 'cancelled';
|
|
3008
3961
|
readonly durationMs: number;
|
|
3009
3962
|
/** UNIX seconds — set only on success (drives the last-success gauge). */
|
|
3010
3963
|
readonly completedAtSec?: number;
|
|
@@ -3223,6 +4176,21 @@ export declare interface WorkflowSingleton<Payload> {
|
|
|
3223
4176
|
readonly mode: 'skip' | 'cancel';
|
|
3224
4177
|
}
|
|
3225
4178
|
|
|
4179
|
+
export declare type WorkflowStartReceipt = typeof ReceiptSchema.Type;
|
|
4180
|
+
|
|
4181
|
+
export declare type WorkflowStartResolution = {
|
|
4182
|
+
readonly kind: 'pending';
|
|
4183
|
+
} | {
|
|
4184
|
+
readonly kind: 'accepted';
|
|
4185
|
+
readonly executionId: string;
|
|
4186
|
+
} | {
|
|
4187
|
+
readonly kind: 'terminal';
|
|
4188
|
+
readonly outcome: NonNullable<WorkflowStartReceipt['terminal']>;
|
|
4189
|
+
} | {
|
|
4190
|
+
readonly kind: 'rejected';
|
|
4191
|
+
readonly failureId: string;
|
|
4192
|
+
};
|
|
4193
|
+
|
|
3226
4194
|
/**
|
|
3227
4195
|
* Per-step plugin interceptor. Plugins can wrap every `step()`
|
|
3228
4196
|
* (== `Activity.make`) invocation with observability, suppress /
|
|
@@ -3378,7 +4346,7 @@ export declare interface WorkflowWorkerLayerBrand {
|
|
|
3378
4346
|
|
|
3379
4347
|
export declare const WorkflowWorkerLayerTypeId: unique symbol;
|
|
3380
4348
|
|
|
3381
|
-
export declare const wrapWorkflowExecuteWithRunRecording: (options: WorkflowExecuteRecordingOptions, userExecute: (payload: unknown, executionId: string) => Effect.Effect<unknown, unknown, never>) => (payload: unknown, executionId: string) => Effect.Effect<unknown, unknown, never>;
|
|
4349
|
+
export declare const wrapWorkflowExecuteWithRunRecording: (options: WorkflowExecuteRecordingOptions, userExecute: (payload: unknown, executionId: string, generation: string) => Effect.Effect<unknown, unknown, never>) => (payload: unknown, executionId: string) => Effect.Effect<unknown, unknown, never>;
|
|
3382
4350
|
|
|
3383
4351
|
/**
|
|
3384
4352
|
* Advance the stored position.
|