@dsh-enhanced/assistant-work-items 0.0.0-stage → 0.1.67
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/LICENSE +21 -0
- package/README.md +685 -2
- package/cordis.patch.yml +11 -0
- package/lib/acceptance-binding.d.ts +86 -0
- package/lib/acceptance-binding.d.ts.map +1 -0
- package/lib/acceptance-binding.js +250 -0
- package/lib/acceptance-binding.js.map +1 -0
- package/lib/admission.d.ts +95 -0
- package/lib/admission.d.ts.map +1 -0
- package/lib/admission.js +642 -0
- package/lib/admission.js.map +1 -0
- package/lib/authority.d.ts +99 -0
- package/lib/authority.d.ts.map +1 -0
- package/lib/authority.js +233 -0
- package/lib/authority.js.map +1 -0
- package/lib/config.d.ts +365 -0
- package/lib/config.d.ts.map +1 -0
- package/lib/config.js +672 -0
- package/lib/config.js.map +1 -0
- package/lib/continuation-contract.d.ts +126 -0
- package/lib/continuation-contract.d.ts.map +1 -0
- package/lib/continuation-contract.js +109 -0
- package/lib/continuation-contract.js.map +1 -0
- package/lib/continuation-record.d.ts +32 -0
- package/lib/continuation-record.d.ts.map +1 -0
- package/lib/continuation-record.js +57 -0
- package/lib/continuation-record.js.map +1 -0
- package/lib/continuation.d.ts +89 -0
- package/lib/continuation.d.ts.map +1 -0
- package/lib/continuation.js +607 -0
- package/lib/continuation.js.map +1 -0
- package/lib/diagnosis-contract.d.ts +95 -0
- package/lib/diagnosis-contract.d.ts.map +1 -0
- package/lib/diagnosis-contract.js +167 -0
- package/lib/diagnosis-contract.js.map +1 -0
- package/lib/diagnosis.d.ts +70 -0
- package/lib/diagnosis.d.ts.map +1 -0
- package/lib/diagnosis.js +466 -0
- package/lib/diagnosis.js.map +1 -0
- package/lib/dispatch.d.ts +100 -0
- package/lib/dispatch.d.ts.map +1 -0
- package/lib/dispatch.js +317 -0
- package/lib/dispatch.js.map +1 -0
- package/lib/engineering-context.d.ts +86 -0
- package/lib/engineering-context.d.ts.map +1 -0
- package/lib/engineering-context.js +263 -0
- package/lib/engineering-context.js.map +1 -0
- package/lib/evaluation.d.ts +125 -0
- package/lib/evaluation.d.ts.map +1 -0
- package/lib/evaluation.js +295 -0
- package/lib/evaluation.js.map +1 -0
- package/lib/event-follow.d.ts +93 -0
- package/lib/event-follow.d.ts.map +1 -0
- package/lib/event-follow.js +150 -0
- package/lib/event-follow.js.map +1 -0
- package/lib/feedback-targets.d.ts +91 -0
- package/lib/feedback-targets.d.ts.map +1 -0
- package/lib/feedback-targets.js +362 -0
- package/lib/feedback-targets.js.map +1 -0
- package/lib/index.d.ts +27 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +25 -0
- package/lib/index.js.map +1 -0
- package/lib/intake-admission.d.ts +49 -0
- package/lib/intake-admission.d.ts.map +1 -0
- package/lib/intake-admission.js +100 -0
- package/lib/intake-admission.js.map +1 -0
- package/lib/intake-evaluation-runtime.d.ts +74 -0
- package/lib/intake-evaluation-runtime.d.ts.map +1 -0
- package/lib/intake-evaluation-runtime.js +343 -0
- package/lib/intake-evaluation-runtime.js.map +1 -0
- package/lib/intake-evaluation.d.ts +180 -0
- package/lib/intake-evaluation.d.ts.map +1 -0
- package/lib/intake-evaluation.js +440 -0
- package/lib/intake-evaluation.js.map +1 -0
- package/lib/intake.d.ts +118 -0
- package/lib/intake.d.ts.map +1 -0
- package/lib/intake.js +137 -0
- package/lib/intake.js.map +1 -0
- package/lib/ledger.d.ts +86 -0
- package/lib/ledger.d.ts.map +1 -0
- package/lib/ledger.js +145 -0
- package/lib/ledger.js.map +1 -0
- package/lib/mandate.d.ts +45 -0
- package/lib/mandate.d.ts.map +1 -0
- package/lib/mandate.js +168 -0
- package/lib/mandate.js.map +1 -0
- package/lib/outcome.d.ts +137 -0
- package/lib/outcome.d.ts.map +1 -0
- package/lib/outcome.js +303 -0
- package/lib/outcome.js.map +1 -0
- package/lib/owner-access.d.ts +35 -0
- package/lib/owner-access.d.ts.map +1 -0
- package/lib/owner-access.js +152 -0
- package/lib/owner-access.js.map +1 -0
- package/lib/owner-continuation.d.ts +27 -0
- package/lib/owner-continuation.d.ts.map +1 -0
- package/lib/owner-continuation.js +131 -0
- package/lib/owner-continuation.js.map +1 -0
- package/lib/owner-recall.d.ts +85 -0
- package/lib/owner-recall.d.ts.map +1 -0
- package/lib/owner-recall.js +134 -0
- package/lib/owner-recall.js.map +1 -0
- package/lib/owner-replies.d.ts +44 -0
- package/lib/owner-replies.d.ts.map +1 -0
- package/lib/owner-replies.js +268 -0
- package/lib/owner-replies.js.map +1 -0
- package/lib/peers.d.ts +624 -0
- package/lib/peers.d.ts.map +1 -0
- package/lib/peers.js +10 -0
- package/lib/peers.js.map +1 -0
- package/lib/policy-notice.d.ts +31 -0
- package/lib/policy-notice.d.ts.map +1 -0
- package/lib/policy-notice.js +137 -0
- package/lib/policy-notice.js.map +1 -0
- package/lib/reply-contract.d.ts +67 -0
- package/lib/reply-contract.d.ts.map +1 -0
- package/lib/reply-contract.js +58 -0
- package/lib/reply-contract.js.map +1 -0
- package/lib/service.d.ts +632 -0
- package/lib/service.d.ts.map +1 -0
- package/lib/service.js +2447 -0
- package/lib/service.js.map +1 -0
- package/lib/settlement.d.ts +74 -0
- package/lib/settlement.d.ts.map +1 -0
- package/lib/settlement.js +233 -0
- package/lib/settlement.js.map +1 -0
- package/lib/signals.d.ts +176 -0
- package/lib/signals.d.ts.map +1 -0
- package/lib/signals.js +497 -0
- package/lib/signals.js.map +1 -0
- package/lib/store.d.ts +791 -0
- package/lib/store.d.ts.map +1 -0
- package/lib/store.js +3266 -0
- package/lib/store.js.map +1 -0
- package/lib/tools.d.ts +7 -0
- package/lib/tools.d.ts.map +1 -0
- package/lib/tools.js +443 -0
- package/lib/tools.js.map +1 -0
- package/lib/types.d.ts +831 -0
- package/lib/types.d.ts.map +1 -0
- package/lib/types.js +29 -0
- package/lib/types.js.map +1 -0
- package/lib/version.d.ts +2 -0
- package/lib/version.d.ts.map +1 -0
- package/lib/version.js +2 -0
- package/lib/version.js.map +1 -0
- package/lib/workspace.d.ts +43 -0
- package/lib/workspace.d.ts.map +1 -0
- package/lib/workspace.js +137 -0
- package/lib/workspace.js.map +1 -0
- package/package.json +101 -3
package/lib/store.d.ts
ADDED
|
@@ -0,0 +1,791 @@
|
|
|
1
|
+
import { type WorkItemContinuationInput, type WorkItemContinuationRecord } from './continuation-record.js';
|
|
2
|
+
import { type WorkItemDiagnosisPlan } from './diagnosis-contract.js';
|
|
3
|
+
import type { WorkItemClaimRecord, WorkItemClaimState, WorkItemDeliveryState, WorkItemDispatchRecord, WorkItemEventRecord, WorkItemFollowRecord, WorkItemFollowUpOwnResult, WorkItemFollowUpRecord, WorkItemPolicyNotice, WorkItemAcceptanceBinding, WorkItemAcceptanceVerdict, WorkItemAcceptanceBlockReason, WorkItemAcceptanceGateExpectation, WorkItemLateAcceptanceBinding, WorkItemOutcomeEvidence, WorkItemOutcomeEvidenceReason, WorkItemOutcomeEvidenceState, WorkItemOutcomeRecord, WorkItemOutcomeView, WorkItemRecord, WorkItemReportRecord, WorkItemReportStatus, WorkItemResumeContext, WorkItemState, WorkItemThreadClosure } from './types.ts';
|
|
4
|
+
import type { WorkItemIntakeCandidate, WorkItemIntakeRecord, WorkItemIntakeResult } from './intake.ts';
|
|
5
|
+
import type { WorkItemIntakeEvaluationRecord } from './intake-evaluation.ts';
|
|
6
|
+
import type { WorkItemIntakeAdmissionRecord } from './intake-admission.ts';
|
|
7
|
+
/** Waiting reasons that mean an admission mandate failed revalidation. */
|
|
8
|
+
declare const AUTHORITY_REVOKED = "authority-revoked";
|
|
9
|
+
declare const AUTHORITY_UNAVAILABLE = "authority-unavailable";
|
|
10
|
+
/** One validated follow, already resolved to its registered source at admission. */
|
|
11
|
+
/** Append-only event kinds for WP21 notices and follow-up ownership (no schema change). */
|
|
12
|
+
export declare const POLICY_NOTICE_EVENT = "policy-change-noticed";
|
|
13
|
+
export declare const FOLLOW_UP_OWNED_EVENT = "follow-up-owned";
|
|
14
|
+
export declare const FOLLOW_UP_PROCESSED_EVENT = "follow-up-processed";
|
|
15
|
+
export declare const FOLLOW_UP_RELEASED_EVENT = "follow-up-released";
|
|
16
|
+
/** WP21 slice 4: the independent verifier's verdict, read back once per bound item. */
|
|
17
|
+
export declare const ACCEPTANCE_VERIFIED_EVENT = "acceptance-verified";
|
|
18
|
+
/** WP21 slice 6: a worker run's contract bound after wake; the latest row is current. */
|
|
19
|
+
export declare const ACCEPTANCE_BOUND_EVENT = "acceptance-bound";
|
|
20
|
+
/** Message of the fail-closed storage error for a malformed latest `acceptance-bound` row. */
|
|
21
|
+
export declare const MALFORMED_ACCEPTANCE_BINDING = "recorded acceptance binding is malformed";
|
|
22
|
+
/** One dispatched, unbound item whose current worker run may be late-bound. */
|
|
23
|
+
export interface WorkItemLateAcceptanceCandidate {
|
|
24
|
+
readonly item: WorkItemRecord;
|
|
25
|
+
readonly automationId: string;
|
|
26
|
+
readonly occurrenceId: string;
|
|
27
|
+
/** Earliest time this generation's run can have started: max(item createdAt, dispatch occurredAt). */
|
|
28
|
+
readonly notBefore: number;
|
|
29
|
+
}
|
|
30
|
+
/** Position of one released follow-up in release order. */
|
|
31
|
+
export interface WorkItemFollowUpCursor {
|
|
32
|
+
readonly recordedAt: number;
|
|
33
|
+
readonly itemId: string;
|
|
34
|
+
readonly sequence: number;
|
|
35
|
+
}
|
|
36
|
+
export interface WorkItemFollowInput {
|
|
37
|
+
readonly kind: string;
|
|
38
|
+
readonly ref: string;
|
|
39
|
+
/** Registered source key; equals `kind` and is persisted for audit. */
|
|
40
|
+
readonly source: string;
|
|
41
|
+
/** Registration generation at admission; a newer one cannot close this row. */
|
|
42
|
+
readonly sourceGeneration: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Deterministic external event identity for one dispatch generation.
|
|
46
|
+
*
|
|
47
|
+
* Generation 0 is the admission identity and equals the item id, so existing
|
|
48
|
+
* rows keep their exact `(event_id, occurred_at)` pair. Later generations append
|
|
49
|
+
* a suffix, because the automation intake dedupes occurrences by
|
|
50
|
+
* `(automationId, eventId, occurredAt)` and would replay a completed occurrence
|
|
51
|
+
* instead of starting a new run.
|
|
52
|
+
*/
|
|
53
|
+
export declare function dispatchEventId(itemId: string, generation: number): string;
|
|
54
|
+
/** Create a mode-0700 directory and prove it is not a link or group-writable. */
|
|
55
|
+
export declare function preparePrivateDirectory(path: string): void;
|
|
56
|
+
/** Create the SQLite file with mode 0600 before SQLite opens it. */
|
|
57
|
+
export declare function prepareDatabaseFile(path: string): void;
|
|
58
|
+
export interface ClaimResult {
|
|
59
|
+
readonly item: WorkItemRecord;
|
|
60
|
+
readonly claim: WorkItemClaimRecord;
|
|
61
|
+
readonly replayed: boolean;
|
|
62
|
+
}
|
|
63
|
+
export interface ReportResult {
|
|
64
|
+
readonly item: WorkItemRecord;
|
|
65
|
+
readonly report: WorkItemReportRecord;
|
|
66
|
+
readonly replayed: boolean;
|
|
67
|
+
}
|
|
68
|
+
export interface ReclaimResult {
|
|
69
|
+
readonly requeued: readonly string[];
|
|
70
|
+
readonly blocked: readonly string[];
|
|
71
|
+
}
|
|
72
|
+
/** Which signal drove a withdrawal; recorded on every retired item's event. */
|
|
73
|
+
export interface WithdrawAttribution {
|
|
74
|
+
readonly sourceId: string;
|
|
75
|
+
readonly externalId: string;
|
|
76
|
+
readonly observedAt: number;
|
|
77
|
+
}
|
|
78
|
+
/** Result of retiring every open item of one canonical dedup key. */
|
|
79
|
+
export interface WithdrawDedupResult {
|
|
80
|
+
readonly outcome: 'withdrawn' | 'settled' | 'absent';
|
|
81
|
+
/** Items actually retired (`withdrawn`), the newest item (`settled`), or none. */
|
|
82
|
+
readonly items: readonly WorkItemRecord[];
|
|
83
|
+
}
|
|
84
|
+
export interface WorkItemStoreStats {
|
|
85
|
+
readonly schemaVersion: number;
|
|
86
|
+
readonly items: number;
|
|
87
|
+
readonly openItems: number;
|
|
88
|
+
readonly reports: number;
|
|
89
|
+
readonly dispatches: number;
|
|
90
|
+
readonly outcomes: number;
|
|
91
|
+
readonly pendingOutcomes: number;
|
|
92
|
+
readonly unverifiedOutcomes: number;
|
|
93
|
+
/** Latest settled revisions still waiting for one trusted Evaluation append. */
|
|
94
|
+
readonly evaluationPending: number;
|
|
95
|
+
readonly evaluationExported: number;
|
|
96
|
+
readonly evaluationSkipped: number;
|
|
97
|
+
/** Persisted followed-thread rows (open and closed). */
|
|
98
|
+
readonly follows: number;
|
|
99
|
+
/** Open items admitted before the revalidation basis existed (schema < v7). */
|
|
100
|
+
readonly authorityLegacy: number;
|
|
101
|
+
/** Open items parked because their admission mandate failed revalidation. */
|
|
102
|
+
readonly authorityParked: number;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Durable execution facts one work item can contribute to an Evaluation claim.
|
|
106
|
+
*
|
|
107
|
+
* Only counts the ledger already records are exposed. No provider token/cost
|
|
108
|
+
* usage is read here: this ledger owns no run-usage contract, while the
|
|
109
|
+
* automation side records those figures for the same run scope, so copying them
|
|
110
|
+
* would double-count cost. Zero counts are omitted so a quiet item stays compact.
|
|
111
|
+
*/
|
|
112
|
+
export interface WorkItemExecutionMetrics {
|
|
113
|
+
readonly latencyMs: number;
|
|
114
|
+
readonly retries?: number;
|
|
115
|
+
readonly claims?: number;
|
|
116
|
+
readonly reports?: number;
|
|
117
|
+
readonly waitingReports?: number;
|
|
118
|
+
readonly unknownDispatches?: number;
|
|
119
|
+
readonly claimExpiries?: number;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Single-writer SQLite ledger.
|
|
123
|
+
*
|
|
124
|
+
* Every mutation runs inside `BEGIN IMMEDIATE`; the database file is created
|
|
125
|
+
* 0600 next to a 0700 directory, WAL keeps readers unblocked, and schema
|
|
126
|
+
* upgrades are bounded to the single-writer upgrade boundary at open time.
|
|
127
|
+
*/
|
|
128
|
+
export declare class WorkItemStore {
|
|
129
|
+
#private;
|
|
130
|
+
constructor(path: string, options?: {
|
|
131
|
+
now?: () => number;
|
|
132
|
+
settleWindowMs?: number;
|
|
133
|
+
});
|
|
134
|
+
/** Keep report/plan sources writer-fenced through a synchronous Host commit.
|
|
135
|
+
* Delivery and Evaluation own their outer locks; this method never acquires
|
|
136
|
+
* either peer or starts any execution. */
|
|
137
|
+
withFeedbackSourceFence<T>(work: () => T): T;
|
|
138
|
+
close(): void;
|
|
139
|
+
get closed(): boolean;
|
|
140
|
+
stats(): WorkItemStoreStats;
|
|
141
|
+
/**
|
|
142
|
+
* Record one classified intake candidate exactly once.
|
|
143
|
+
*
|
|
144
|
+
* A replay of the same `(source, sourceEventId)` returns the original row
|
|
145
|
+
* unchanged, with no second write. A new event whose content digest matches
|
|
146
|
+
* an earlier `stored` row of the same source and at least the same strength
|
|
147
|
+
* is recorded as `duplicate`; a stronger repeat (for example the same text
|
|
148
|
+
* re-posted with a mention) is never suppressed by a weaker original.
|
|
149
|
+
* This method writes only the intake table; it admits and dispatches nothing.
|
|
150
|
+
*/
|
|
151
|
+
recordIntake(candidate: WorkItemIntakeCandidate): WorkItemIntakeResult;
|
|
152
|
+
getIntake(source: string, sourceEventId: string): WorkItemIntakeRecord | undefined;
|
|
153
|
+
/**
|
|
154
|
+
* Append one evaluation result exactly once per `(row, rule, Policy version)`.
|
|
155
|
+
* The intake row must be a `stored` `inferred` row whose content digest is the
|
|
156
|
+
* evaluated source digest. A replay returns the original row unchanged.
|
|
157
|
+
*/
|
|
158
|
+
recordIntakeEvaluation(record: Omit<WorkItemIntakeEvaluationRecord, 'recordedAt'>): {
|
|
159
|
+
readonly record: WorkItemIntakeEvaluationRecord;
|
|
160
|
+
readonly replayed: boolean;
|
|
161
|
+
};
|
|
162
|
+
getIntakeEvaluation(source: string, sourceEventId: string, ruleId: string, policyVersion: string): WorkItemIntakeEvaluationRecord | undefined;
|
|
163
|
+
/** Every persisted evaluation of one intake row, oldest first; read-only. */
|
|
164
|
+
listIntakeEvaluations(source: string, sourceEventId: string): readonly WorkItemIntakeEvaluationRecord[];
|
|
165
|
+
/** Status counts over the evaluation table; read-only. */
|
|
166
|
+
countIntakeEvaluations(): Readonly<Record<WorkItemIntakeEvaluationRecord['status'], number>>;
|
|
167
|
+
/**
|
|
168
|
+
* Append one admission outcome exactly once per evaluation row. The
|
|
169
|
+
* evaluation must exist and would accept. A replay returns the first row
|
|
170
|
+
* unchanged, so a later outcome never rewrites an earlier one.
|
|
171
|
+
*/
|
|
172
|
+
recordIntakeAdmission(record: Omit<WorkItemIntakeAdmissionRecord, 'recordedAt'>): WorkItemIntakeAdmissionRecord;
|
|
173
|
+
getIntakeAdmission(source: string, sourceEventId: string, ruleId: string, policyVersion: string): WorkItemIntakeAdmissionRecord | undefined;
|
|
174
|
+
/** Every admission outcome of one intake row, oldest first; read-only. */
|
|
175
|
+
listIntakeAdmissions(source: string, sourceEventId: string): readonly WorkItemIntakeAdmissionRecord[];
|
|
176
|
+
/** Oldest accepting evaluations without an admission row, at most `limit`; read-only. */
|
|
177
|
+
pendingIntakeAdmissions(limit: number): readonly WorkItemIntakeEvaluationRecord[];
|
|
178
|
+
/**
|
|
179
|
+
* The intake decision that admitted one item, if any: its first
|
|
180
|
+
* `admitted` (or crash-recovered `replayed`) admission row joined with the
|
|
181
|
+
* evaluation it acted on.
|
|
182
|
+
* Read-only. Served by the partial `item_id` index (schema 13).
|
|
183
|
+
*/
|
|
184
|
+
intakeProvenance(itemId: string): Readonly<{
|
|
185
|
+
admission: WorkItemIntakeAdmissionRecord;
|
|
186
|
+
evaluation: WorkItemIntakeEvaluationRecord;
|
|
187
|
+
}> | undefined;
|
|
188
|
+
/** Items admitted from intake at or after `since`; the hourly intake budget. */
|
|
189
|
+
countIntakeAdmitted(since: number): number;
|
|
190
|
+
/** Outcome counts over the admission table; read-only. */
|
|
191
|
+
countIntakeAdmissions(): Readonly<Record<WorkItemIntakeAdmissionRecord['outcome'], number>>;
|
|
192
|
+
/** Decision counts over the intake table; read-only. */
|
|
193
|
+
countIntake(): Readonly<Record<WorkItemIntakeRecord['decision'], number>>;
|
|
194
|
+
/** SQL owner filtering precedes keyset pagination; no recovery or writes. */
|
|
195
|
+
listOwnerItems(owner: Readonly<{
|
|
196
|
+
principalId: string;
|
|
197
|
+
principalRecordId: string;
|
|
198
|
+
principalVersion: number;
|
|
199
|
+
workspace: string;
|
|
200
|
+
preset: string;
|
|
201
|
+
ownerRouteId: string;
|
|
202
|
+
workerAutomationId: string;
|
|
203
|
+
continuationAutomationId?: string;
|
|
204
|
+
generation: number;
|
|
205
|
+
bindingVersion: number;
|
|
206
|
+
}>, after: Readonly<{
|
|
207
|
+
createdAt: number;
|
|
208
|
+
id: string;
|
|
209
|
+
}> | undefined, limit: number, itemId?: string): readonly WorkItemRecord[];
|
|
210
|
+
/** Exact UTF-8 body bytes after the caller has selected an owner-filtered item. */
|
|
211
|
+
ownerRecallText(itemId: string, revision?: number): string;
|
|
212
|
+
findItemById(itemId: string): WorkItemRecord | undefined;
|
|
213
|
+
findItemByDedup(dedupKey: string, dedupBucket: number): WorkItemRecord | undefined;
|
|
214
|
+
/**
|
|
215
|
+
* Latest item admitted for one canonical dedup key, across all windows.
|
|
216
|
+
*
|
|
217
|
+
* The dedup window forgets history when a bucket rolls over; this lookup is
|
|
218
|
+
* what lets a correction or withdrawal of an already-settled signal stay
|
|
219
|
+
* settled instead of reviving a completed item.
|
|
220
|
+
*/
|
|
221
|
+
findLatestItemByDedupKey(dedupKey: string): WorkItemRecord | undefined;
|
|
222
|
+
/**
|
|
223
|
+
* The item whose frozen mandate already binds `contractId`, if any. One
|
|
224
|
+
* acceptance contract settles exactly one item. A full scan over the stored
|
|
225
|
+
* basis JSON (no index, no schema change); unreadable bases never match.
|
|
226
|
+
*/
|
|
227
|
+
findItemByAcceptanceContract(contractId: string): WorkItemRecord | undefined;
|
|
228
|
+
/**
|
|
229
|
+
* WP21 slice 6 candidates: items whose worker dispatch is `dispatched` to
|
|
230
|
+
* `workerAutomationId` under their current occurrence, whose mandate binds
|
|
231
|
+
* no contract, that have no verdict yet and no `acceptance-bound` row for
|
|
232
|
+
* that occurrence. Never-run, withdrawn, failed and dropped items are out.
|
|
233
|
+
* (created_at, id) order strictly after `after`; bounded scan, no schema change.
|
|
234
|
+
*/
|
|
235
|
+
listLateAcceptanceCandidates(workerAutomationId: string, after: Readonly<{
|
|
236
|
+
createdAt: number;
|
|
237
|
+
id: string;
|
|
238
|
+
}> | null, limit: number): readonly WorkItemLateAcceptanceCandidate[];
|
|
239
|
+
/** The current (latest) late acceptance binding of one item, if any; malformed rows fail closed. */
|
|
240
|
+
lateAcceptanceBinding(itemId: string): WorkItemLateAcceptanceBinding | undefined;
|
|
241
|
+
/**
|
|
242
|
+
* Append one late acceptance binding for the item's current occurrence.
|
|
243
|
+
* Refused for a mandate-bound or already-verified item, for a stale
|
|
244
|
+
* occurrence, and for a contract another item already binds. The same
|
|
245
|
+
* occurrence and contract again is idempotent; a later occurrence's row
|
|
246
|
+
* supersedes earlier ones. State, lease and mandate are untouched.
|
|
247
|
+
*/
|
|
248
|
+
recordLateAcceptanceBinding(input: Readonly<{
|
|
249
|
+
itemId: string;
|
|
250
|
+
occurrenceId: string;
|
|
251
|
+
binding: WorkItemAcceptanceBinding;
|
|
252
|
+
}>): Readonly<{
|
|
253
|
+
binding: WorkItemLateAcceptanceBinding;
|
|
254
|
+
created: boolean;
|
|
255
|
+
}>;
|
|
256
|
+
/**
|
|
257
|
+
* Executed (`ready`, attempt ≥ 1) items whose frozen mandate binds an
|
|
258
|
+
* acceptance contract, or whose latest late binding is for the item's
|
|
259
|
+
* current occurrence, and that have no recorded verdict yet, in
|
|
260
|
+
* (created_at, id) order strictly after `after`. A bounded full scan over
|
|
261
|
+
* the stored basis JSON, like `findItemByAcceptanceContract` (no schema change).
|
|
262
|
+
*/
|
|
263
|
+
listUnsettledAcceptanceItems(after: Readonly<{
|
|
264
|
+
createdAt: number;
|
|
265
|
+
id: string;
|
|
266
|
+
}> | null, limit: number): readonly WorkItemRecord[];
|
|
267
|
+
/**
|
|
268
|
+
* WP21 slice 8 (`acceptance.holdReport`): executed items whose latest report
|
|
269
|
+
* is a terminal `ready` self-report that has not been handed to Delivery and
|
|
270
|
+
* that is either still waiting for the verifier (`ready`) or was moved to
|
|
271
|
+
* `blocked` by the verdict gate (`acceptance-*`). One row per item, oldest
|
|
272
|
+
* report first. `after` is the `(recordedAt, itemId)` keyset position of the
|
|
273
|
+
* previous page, so a full page advances the caller's in-memory round-robin
|
|
274
|
+
* position instead of rescanning rows that are still waiting. Read-only and
|
|
275
|
+
* bounded; no schema change.
|
|
276
|
+
*/
|
|
277
|
+
listHeldAcceptanceReports(limit: number, after?: Readonly<{
|
|
278
|
+
recordedAt: number;
|
|
279
|
+
itemId: string;
|
|
280
|
+
}>): readonly Readonly<{
|
|
281
|
+
item: WorkItemRecord;
|
|
282
|
+
report: WorkItemReportRecord;
|
|
283
|
+
}>[];
|
|
284
|
+
/** Read one durable key/value row from the schema-meta table. */
|
|
285
|
+
meta(key: string): string | null;
|
|
286
|
+
/** Persist one durable key/value row; no schema change is required for it. */
|
|
287
|
+
setMeta(key: string, value: string): void;
|
|
288
|
+
/** Full SQLite bytes; TEXT projection is insufficient for authority-bearing JSON. */
|
|
289
|
+
readCanonicalMeta(key: string): unknown;
|
|
290
|
+
/** Only the exact first admitted event may confer a diagnostic plan. Never scan later events for one. */
|
|
291
|
+
readDiagnosisPlan(itemId: string): Readonly<WorkItemDiagnosisPlan> | undefined;
|
|
292
|
+
diagnosisInterventionPending(itemId: string): boolean;
|
|
293
|
+
diagnosisInterventionItems(limit?: number): readonly WorkItemRecord[];
|
|
294
|
+
diagnosisExplicitlyDisposed(itemId: string): boolean;
|
|
295
|
+
clearDiagnosisIntervention(itemId: string): void;
|
|
296
|
+
/** Locate a real report, then prove its released/completed claim using complete NUL-delimited bytes. */
|
|
297
|
+
diagnosisReportOccurrence(itemId: string, revision: number): Readonly<{
|
|
298
|
+
itemId: string;
|
|
299
|
+
revision: number;
|
|
300
|
+
status: string;
|
|
301
|
+
occurrenceId: string;
|
|
302
|
+
}>;
|
|
303
|
+
/** Row order is database-owned; wall-clock jumps cannot choose a different last report. */
|
|
304
|
+
latestWorkerDiagnosisReport(workerId?: string): Readonly<{
|
|
305
|
+
itemId: string;
|
|
306
|
+
revision: number;
|
|
307
|
+
status: string;
|
|
308
|
+
occurrenceId: string;
|
|
309
|
+
}> | undefined;
|
|
310
|
+
/** Drop one durable key/value row when its cursor no longer applies. */
|
|
311
|
+
deleteMeta(key: string): void;
|
|
312
|
+
/** Count latest outcome revisions in one evidence state. */
|
|
313
|
+
countLatestOutcomes(evidenceState: WorkItemOutcomeEvidenceState): number;
|
|
314
|
+
findItemByOccurrence(occurrenceId: string): WorkItemRecord | undefined;
|
|
315
|
+
listItems(options?: {
|
|
316
|
+
states?: readonly WorkItemState[];
|
|
317
|
+
includeObserved?: boolean;
|
|
318
|
+
limit?: number;
|
|
319
|
+
}): readonly WorkItemRecord[];
|
|
320
|
+
lastAdmitAt(kind?: string): number | null;
|
|
321
|
+
/** Latest successful dispatch timestamp, for bounded health reporting. */
|
|
322
|
+
lastDispatchedAt(): number | null;
|
|
323
|
+
countItemsSince(createdAt: number): number;
|
|
324
|
+
countOpenItems(): number;
|
|
325
|
+
/** Open items admitted before schema v7, i.e. with no persisted mandate. */
|
|
326
|
+
countAuthorityLegacy(): number;
|
|
327
|
+
/** Open items parked because their admission mandate failed revalidation. */
|
|
328
|
+
countAuthorityParked(): number;
|
|
329
|
+
/** Follows of one item, in admission order (their stable position). */
|
|
330
|
+
follows(itemId: string): readonly WorkItemFollowRecord[];
|
|
331
|
+
countOpenFollows(itemId: string): number;
|
|
332
|
+
/** Global follow counts for health reporting (open rows of live items only). */
|
|
333
|
+
countFollows(): {
|
|
334
|
+
open: number;
|
|
335
|
+
closed: number;
|
|
336
|
+
};
|
|
337
|
+
/**
|
|
338
|
+
* Identity of every open follow on a live item, for health projections.
|
|
339
|
+
*
|
|
340
|
+
* A follow row outlives the item it parked when that item is withdrawn or
|
|
341
|
+
* otherwise settled by another path (no resolver ever observed those threads).
|
|
342
|
+
* Reporting those rows as gaps would make health permanently degraded over
|
|
343
|
+
* dead items, so only follows of still-open items count.
|
|
344
|
+
*/
|
|
345
|
+
openFollowIdentities(): readonly {
|
|
346
|
+
readonly source: string;
|
|
347
|
+
readonly sourceGeneration: string;
|
|
348
|
+
}[];
|
|
349
|
+
/** Open follows across live items, oldest first, bounded for diagnostics. */
|
|
350
|
+
listOpenFollows(limit: number): readonly WorkItemFollowRecord[];
|
|
351
|
+
/**
|
|
352
|
+
* Close one open follow exactly once.
|
|
353
|
+
*
|
|
354
|
+
* The CAS on `state = 'open'` is what makes duplicate and out-of-order
|
|
355
|
+
* closures harmless: a second observation of the same closure changes no row
|
|
356
|
+
* and reports `undefined`, so no settlement signal can be produced twice.
|
|
357
|
+
*/
|
|
358
|
+
closeFollow(itemId: string, position: number, closure: WorkItemThreadClosure, now?: number): WorkItemFollowRecord | undefined;
|
|
359
|
+
/**
|
|
360
|
+
* Waiting items that owe a thread-closure settlement.
|
|
361
|
+
*
|
|
362
|
+
* `waiting` with a terminal `last_report_status` is produced only by the
|
|
363
|
+
* deferred report branch, so this is exactly the deferred set. Selecting on
|
|
364
|
+
* the report status rather than on open follow rows keeps the sweep
|
|
365
|
+
* crash-safe: a crash after closing the last follow but before appending the
|
|
366
|
+
* outcome still finds the item on the next pass. A live lease is excluded
|
|
367
|
+
* (additionally to the state check) so a re-claimed item is never settled
|
|
368
|
+
* underneath its new worker.
|
|
369
|
+
*/
|
|
370
|
+
itemsAwaitingThreadClosure(limit: number): readonly WorkItemRecord[];
|
|
371
|
+
/**
|
|
372
|
+
* Settle one deferred item because every followed thread is closed.
|
|
373
|
+
*
|
|
374
|
+
* This appends at most one outcome revision, and a second call is a no-op.
|
|
375
|
+
* The transition reuses the recorded terminal report status, so the item
|
|
376
|
+
* still ends in the state the worker reported; the closure itself is never
|
|
377
|
+
* treated as evidence of objective achievement.
|
|
378
|
+
*/
|
|
379
|
+
settleThreadClosure(itemId: string): WorkItemOutcomeRecord | undefined;
|
|
380
|
+
/**
|
|
381
|
+
* Ambiguous sends that still describe an actionable gap.
|
|
382
|
+
*
|
|
383
|
+
* A failed row is dead weight once its item is terminal or observed (for
|
|
384
|
+
* example a withdrawal after an ambiguous send): no retry is owed and the
|
|
385
|
+
* owner already settled the item, so counting it would report a permanent
|
|
386
|
+
* false gap. The gate mirrors `wakePending()`'s eligibility check.
|
|
387
|
+
*/
|
|
388
|
+
countDispatchUnknown(): number;
|
|
389
|
+
/**
|
|
390
|
+
* Park one item whose admission mandate failed revalidation.
|
|
391
|
+
*
|
|
392
|
+
* Parking is never terminal: the item stays `waiting` with a typed reason, its
|
|
393
|
+
* pending dispatch row is left intact, and it becomes claimable/wakeable again
|
|
394
|
+
* as soon as the identical mandate allows. Repeating the same park only
|
|
395
|
+
* refreshes the audit timestamp, so a sweep that observes the same denial on
|
|
396
|
+
* every tick does not flood the event log.
|
|
397
|
+
*/
|
|
398
|
+
parkAuthority(itemId: string, reason: typeof AUTHORITY_REVOKED | typeof AUTHORITY_UNAVAILABLE, detail: Readonly<Record<string, unknown>>, now: number): WorkItemRecord;
|
|
399
|
+
/**
|
|
400
|
+
* Record a successful revalidation of one item's mandate.
|
|
401
|
+
*
|
|
402
|
+
* Only a wait this gate itself created is lifted; a slice-9
|
|
403
|
+
* `following-thread` wait is a different concern and stays untouched.
|
|
404
|
+
*/
|
|
405
|
+
restoreAuthority(itemId: string, now: number): WorkItemRecord;
|
|
406
|
+
/** Latest authority denial for bounded health reporting. */
|
|
407
|
+
lastAuthorityDenial(): {
|
|
408
|
+
readonly at: number;
|
|
409
|
+
readonly reason: string;
|
|
410
|
+
} | null;
|
|
411
|
+
getContinuation(itemId: string): Readonly<WorkItemContinuationRecord> | undefined;
|
|
412
|
+
findContinuationBySourceKey(key: string): Readonly<WorkItemContinuationRecord> | undefined;
|
|
413
|
+
/** Most recently admitted dispatched child, by immutable dispatch rowid; no wall-clock ordering. */
|
|
414
|
+
latestContinuationDispatch(automationId: string): Readonly<{
|
|
415
|
+
item: WorkItemRecord;
|
|
416
|
+
dispatch: WorkItemDispatchRecord;
|
|
417
|
+
continuation: WorkItemContinuationRecord;
|
|
418
|
+
}> | undefined;
|
|
419
|
+
continuationDispatchUncertain(automationId: string): boolean;
|
|
420
|
+
listPendingContinuations(automationId: string, limit?: number, after?: Readonly<{
|
|
421
|
+
createdAt: number;
|
|
422
|
+
id: string;
|
|
423
|
+
}>): readonly Readonly<{
|
|
424
|
+
item: WorkItemRecord;
|
|
425
|
+
dispatch: WorkItemDispatchRecord;
|
|
426
|
+
continuation: WorkItemContinuationRecord;
|
|
427
|
+
}>[];
|
|
428
|
+
continuationParentBrief(itemId: string): string;
|
|
429
|
+
continuationParentReports(itemId: string, afterRevision?: number, limit?: number): readonly WorkItemReportRecord[];
|
|
430
|
+
continuationParentOutcomes(itemId: string, afterRevision?: number, limit?: number): readonly WorkItemOutcomeRecord[];
|
|
431
|
+
/**
|
|
432
|
+
* Insert one admitted item, its lifecycle event and its single dispatch row
|
|
433
|
+
* in one transaction. A crash between these writes is impossible.
|
|
434
|
+
*/
|
|
435
|
+
admitItem(record: WorkItemRecord, event: {
|
|
436
|
+
kind: string;
|
|
437
|
+
actor: string;
|
|
438
|
+
detail?: unknown;
|
|
439
|
+
}, dispatch: WorkItemDispatchRecord, follows?: readonly WorkItemFollowInput[], diagnosisPlan?: WorkItemDiagnosisPlan, continuation?: WorkItemContinuationInput): WorkItemRecord;
|
|
440
|
+
/**
|
|
441
|
+
* Retire every open item a canonical signal produced, because it was withdrawn.
|
|
442
|
+
*
|
|
443
|
+
* This is the only lifecycle transition driven by the read side of autonomy
|
|
444
|
+
* rather than by a worker report. It is deliberately narrow: the items stop
|
|
445
|
+
* being open, their active claim (if any) is released so the current run
|
|
446
|
+
* cannot keep reporting, and a still-pending wake-up is failed rather than
|
|
447
|
+
* re-armed. A wake-up already handed to the automation is left alone —
|
|
448
|
+
* delivery to a running occurrence cannot be recalled from here.
|
|
449
|
+
*
|
|
450
|
+
* Withdrawal targets the whole dedup key, not the newest row, because the
|
|
451
|
+
* dedup window is a freshness bound: once it rolls, a still-open item can be
|
|
452
|
+
* re-admitted under the same key with a different bucket. Retiring only the
|
|
453
|
+
* newest row would leave the older one winnable by `wakePending()` on the next
|
|
454
|
+
* host start, i.e. cancelled work could still be woken. All rows of the key
|
|
455
|
+
* therefore settle together in one transaction.
|
|
456
|
+
*
|
|
457
|
+
* Idempotent: an already-terminal key is returned unchanged (`settled`) with
|
|
458
|
+
* no new event, so a repeated withdrawn revision never rewrites history.
|
|
459
|
+
*/
|
|
460
|
+
withdrawByDedupKey(dedupKey: string, attribution?: WithdrawAttribution): WithdrawDedupResult;
|
|
461
|
+
latestOutcome(itemId: string): WorkItemOutcomeRecord | undefined;
|
|
462
|
+
/** Every outcome revision for one item, oldest first. */
|
|
463
|
+
outcomes(itemId: string): readonly WorkItemOutcomeRecord[];
|
|
464
|
+
/**
|
|
465
|
+
* Latest outcome plus the report delivery state it depends on.
|
|
466
|
+
*
|
|
467
|
+
* `reportRevision` is the terminal report that caused a report-derived
|
|
468
|
+
* transition; observation and expiry revisions keep pointing at it, while
|
|
469
|
+
* withdrawal and retry exhaustion never had a report.
|
|
470
|
+
*/
|
|
471
|
+
outcomeView(itemId: string): WorkItemOutcomeView | undefined;
|
|
472
|
+
/** Latest outcomes, newest first, optionally filtered by evidence state. */
|
|
473
|
+
listOutcomes(options?: {
|
|
474
|
+
limit?: number;
|
|
475
|
+
evidenceState?: WorkItemOutcomeEvidenceState;
|
|
476
|
+
}): readonly WorkItemOutcomeView[];
|
|
477
|
+
/**
|
|
478
|
+
* Latest outcome revisions still waiting for evidence, soonest deadline first.
|
|
479
|
+
*
|
|
480
|
+
* Only the newest revision per item is considered: an older revision that was
|
|
481
|
+
* superseded still says `pending` in the immutable row, but it is history, not
|
|
482
|
+
* an open window.
|
|
483
|
+
*/
|
|
484
|
+
pendingOutcomes(limit: number): readonly WorkItemOutcomeRecord[];
|
|
485
|
+
/**
|
|
486
|
+
* Append the settling revision for one pending outcome.
|
|
487
|
+
*
|
|
488
|
+
* Compare-and-swap on the revision number: a concurrent pass that already
|
|
489
|
+
* settled the item fails here instead of overwriting its history.
|
|
490
|
+
*
|
|
491
|
+
* This intentionally appends no `work_item_event`: the outcome ledger is its
|
|
492
|
+
* own append-only audit trail, and duplicating every revision into the event
|
|
493
|
+
* log would mix worker lifecycle with independently sourced evidence.
|
|
494
|
+
*/
|
|
495
|
+
settleOutcome(input: {
|
|
496
|
+
itemId: string;
|
|
497
|
+
revision: number;
|
|
498
|
+
evidence: WorkItemOutcomeEvidence | null;
|
|
499
|
+
reason: WorkItemOutcomeEvidenceReason | null;
|
|
500
|
+
degraded: boolean;
|
|
501
|
+
expired: boolean;
|
|
502
|
+
}): WorkItemOutcomeRecord;
|
|
503
|
+
/**
|
|
504
|
+
* Latest outcome revisions that still owe exactly one trusted Evaluation
|
|
505
|
+
* append.
|
|
506
|
+
*
|
|
507
|
+
* Only the newest revision per item is exportable, and only once it carries a
|
|
508
|
+
* settled evidence state: an unresolved `pending` window is still changing, so
|
|
509
|
+
* exporting it early would publish a claim that later revisions contradict.
|
|
510
|
+
*/
|
|
511
|
+
outcomesAwaitingEvaluation(limit: number, attemptBound?: number): readonly WorkItemOutcomeRecord[];
|
|
512
|
+
/** Count settled revisions that used up their bounded export attempts. */
|
|
513
|
+
countExhaustedEvaluations(attemptBound: number): number;
|
|
514
|
+
/** Count latest export-eligible revisions per Evaluation export state. */
|
|
515
|
+
countEvaluations(): {
|
|
516
|
+
pending: number;
|
|
517
|
+
exported: number;
|
|
518
|
+
skipped: number;
|
|
519
|
+
};
|
|
520
|
+
/**
|
|
521
|
+
* Bounded, read-only execution facts for one item at a settlement instant.
|
|
522
|
+
*
|
|
523
|
+
* Every counter is a COUNT over durable rows this ledger already keeps for
|
|
524
|
+
* the item; nothing is re-derived from live process state. `settledAt` bounds
|
|
525
|
+
* each read because rows recorded after the settled revision belong to a
|
|
526
|
+
* later observation and must not inflate an earlier claim. An absent item row
|
|
527
|
+
* returns `undefined` so the caller can keep the live-record fallback.
|
|
528
|
+
*
|
|
529
|
+
* Claims are counted from `claimed` ledger events rather than claim rows:
|
|
530
|
+
* each committed claim appends exactly one such event in the same transaction
|
|
531
|
+
* as the claim row and the `item.attempt` increment (the replay branch appends
|
|
532
|
+
* neither, retry-exhausted appends `blocked` only, and nothing deletes either
|
|
533
|
+
* record), while `work_item_claim` has no `item_id` index. `work_item_event`
|
|
534
|
+
* is `WITHOUT ROWID` keyed by `(item_id, sequence)`, so its count is an
|
|
535
|
+
* indexed prefix search instead of a scan of every claim ever recorded.
|
|
536
|
+
*/
|
|
537
|
+
workItemExecutionMetrics(itemId: string, settledAt: number): WorkItemExecutionMetrics | undefined;
|
|
538
|
+
/**
|
|
539
|
+
* Bounded, read-only resume brief for one item at a claim instant.
|
|
540
|
+
*
|
|
541
|
+
* Everything is derived from the item's own append-only ledger rows, so a
|
|
542
|
+
* fresh occurrence can continue without replaying a prior model's memory.
|
|
543
|
+
* Absent items return `undefined` (mirroring `workItemExecutionMetrics`) so
|
|
544
|
+
* the caller never invents an empty context for a row that vanished.
|
|
545
|
+
*
|
|
546
|
+
* The event read is a bounded newest-first scan of one item's primary-key
|
|
547
|
+
* prefix; it reconstructs prior attempts from the `claimed` event that
|
|
548
|
+
* records `{runId, attempt}` and the recovery/report events that end one.
|
|
549
|
+
* Malformed or absent detail JSON is skipped, never thrown. Reports are read
|
|
550
|
+
* newest-first through the same primary-key prefix and capped at five, with
|
|
551
|
+
* each summary cut to a safe UTF-8 byte boundary.
|
|
552
|
+
*/
|
|
553
|
+
workItemResumeContext(itemId: string, now?: number): WorkItemResumeContext | undefined;
|
|
554
|
+
/** Mark one settled revision exported; CAS on `pending` so a replay is refused. */
|
|
555
|
+
markOutcomeExported(itemId: string, revision: number, digest: string, recordedAt: number): WorkItemOutcomeRecord;
|
|
556
|
+
/** Mark one settled revision skipped; CAS on `pending`. */
|
|
557
|
+
markOutcomeSkipped(itemId: string, revision: number, recordedAt: number): WorkItemOutcomeRecord;
|
|
558
|
+
/** Count one failed export attempt, saturated at the caller's bound. */
|
|
559
|
+
recordOutcomeEvaluationAttempt(itemId: string, revision: number, maxAttempts: number): WorkItemOutcomeRecord;
|
|
560
|
+
appendEvent(itemId: string, kind: string, actor: string, detail?: unknown): void;
|
|
561
|
+
events(itemId: string): readonly WorkItemEventRecord[];
|
|
562
|
+
/**
|
|
563
|
+
* Record Policy-change notices for live items in one transaction, at most
|
|
564
|
+
* once per (item, policyVersion). A notice is an append-only event: it
|
|
565
|
+
* changes no state, lease or dispatch, so a Policy change never cancels
|
|
566
|
+
* work. All or nothing: a failure writes none of the batch, and a retry with
|
|
567
|
+
* the same version re-derives it. Each entry yields the written notice, or
|
|
568
|
+
* `undefined` when the item already had one for this version or is no
|
|
569
|
+
* longer live work.
|
|
570
|
+
*/
|
|
571
|
+
recordPolicyNotices(policyVersion: string, entries: ReadonlyArray<Readonly<{
|
|
572
|
+
itemId: string;
|
|
573
|
+
notice: Omit<WorkItemPolicyNotice, 'itemId' | 'recordedAt' | 'policyVersion'>;
|
|
574
|
+
}>>): ReadonlyArray<WorkItemPolicyNotice | undefined>;
|
|
575
|
+
/**
|
|
576
|
+
* Live (open, non-observed) items in admission order after `after`, for a
|
|
577
|
+
* bounded notice pass; also how many live items lie beyond the page.
|
|
578
|
+
*/
|
|
579
|
+
listLiveItemsPage(options: {
|
|
580
|
+
after?: Readonly<{
|
|
581
|
+
createdAt: number;
|
|
582
|
+
id: string;
|
|
583
|
+
}>;
|
|
584
|
+
limit: number;
|
|
585
|
+
}): Readonly<{
|
|
586
|
+
items: readonly WorkItemRecord[];
|
|
587
|
+
remaining: number;
|
|
588
|
+
}>;
|
|
589
|
+
/**
|
|
590
|
+
* The independent verifier's verdict recorded for one item, if any.
|
|
591
|
+
*
|
|
592
|
+
* Append-only event, at most one per item: a receipt is final for its
|
|
593
|
+
* contract, so the first validated read-back is the item's verdict.
|
|
594
|
+
*/
|
|
595
|
+
acceptanceVerdict(itemId: string): WorkItemAcceptanceVerdict | undefined;
|
|
596
|
+
/**
|
|
597
|
+
* Record the verifier's verdict for one item, at most once. The same
|
|
598
|
+
* receipt again is idempotent; a different receipt for an item that already
|
|
599
|
+
* has a verdict is an identity mismatch and writes nothing. The item's state,
|
|
600
|
+
* lease and outcome revisions are untouched.
|
|
601
|
+
*/
|
|
602
|
+
recordAcceptanceVerdict(verdict: Omit<WorkItemAcceptanceVerdict, 'recordedAt'>, gate?: WorkItemAcceptanceGateExpectation): Readonly<{
|
|
603
|
+
verdict: WorkItemAcceptanceVerdict;
|
|
604
|
+
created: boolean;
|
|
605
|
+
blockedReason?: WorkItemAcceptanceBlockReason;
|
|
606
|
+
}>;
|
|
607
|
+
/**
|
|
608
|
+
* WP21 slice 7 (`acceptance.verdictGate`): an independent verifier said the
|
|
609
|
+
* executed item's objective was not achieved, could not tell, or needs
|
|
610
|
+
* attention. Move it from `ready` to the existing `blocked` state with an
|
|
611
|
+
* `acceptance-*` reason and one `blocked` event. Compare-and-swap on the
|
|
612
|
+
* expected state, attempt and occurrence: an item that moved on (re-armed,
|
|
613
|
+
* withdrawn, already blocked) is left untouched and nothing is written. The
|
|
614
|
+
* outcome ledger is not rewritten; the self-reported `ready` revision stays
|
|
615
|
+
* history.
|
|
616
|
+
*/
|
|
617
|
+
blockForAcceptance(itemId: string, expect: WorkItemAcceptanceGateExpectation, reason: WorkItemAcceptanceBlockReason, detail: Readonly<{
|
|
618
|
+
contractId: string;
|
|
619
|
+
receiptDigest?: string;
|
|
620
|
+
verifierReason?: string | null;
|
|
621
|
+
}>): boolean;
|
|
622
|
+
/** Every Policy-change notice recorded for one item, oldest first. */
|
|
623
|
+
policyNotices(itemId: string): readonly WorkItemPolicyNotice[];
|
|
624
|
+
/**
|
|
625
|
+
* Hand one human follow-up on the item's work thread to that item.
|
|
626
|
+
*
|
|
627
|
+
* The message id is owned by at most one item for its whole life; the same
|
|
628
|
+
* (item, message, digest) is idempotent, anything else under the same id is
|
|
629
|
+
* an identity mismatch. An item that already ended takes nothing: the
|
|
630
|
+
* message stays with judgment and no row is written.
|
|
631
|
+
*/
|
|
632
|
+
ownFollowUp(input: {
|
|
633
|
+
itemId: string;
|
|
634
|
+
bindingId: string;
|
|
635
|
+
messageId: string;
|
|
636
|
+
sourceDigest: string;
|
|
637
|
+
}): WorkItemFollowUpOwnResult;
|
|
638
|
+
/**
|
|
639
|
+
* Mark one owned follow-up processed by its live item. Idempotent; once the
|
|
640
|
+
* item ended an unprocessed follow-up belongs to judgment and cannot be
|
|
641
|
+
* claimed as processed any more, whether or not the release sweep ran.
|
|
642
|
+
*/
|
|
643
|
+
markFollowUpProcessed(itemId: string, messageId: string, options?: {
|
|
644
|
+
readonly allowEnded?: boolean;
|
|
645
|
+
}): WorkItemFollowUpRecord;
|
|
646
|
+
/** Follow-ups owned by one item, in the order they were handed over. */
|
|
647
|
+
followUps(itemId: string): readonly WorkItemFollowUpRecord[];
|
|
648
|
+
/**
|
|
649
|
+
* Materialize the release of every unprocessed follow-up whose item ended.
|
|
650
|
+
*
|
|
651
|
+
* Derived from durable state only (terminal item, owned, neither processed
|
|
652
|
+
* nor released), so it is restart-safe and covers every terminal path
|
|
653
|
+
* without hooking each one; a second sweep releases nothing new.
|
|
654
|
+
*/
|
|
655
|
+
releaseEndedFollowUps(limit?: number): readonly WorkItemFollowUpRecord[];
|
|
656
|
+
/**
|
|
657
|
+
* Released follow-ups in release order, for judgment to (re)read after a
|
|
658
|
+
* restart. `after` is the cursor of the last record already seen.
|
|
659
|
+
*/
|
|
660
|
+
listReleasedFollowUps(options?: {
|
|
661
|
+
limit?: number;
|
|
662
|
+
after?: WorkItemFollowUpCursor;
|
|
663
|
+
}): Readonly<{
|
|
664
|
+
items: readonly WorkItemFollowUpRecord[];
|
|
665
|
+
next: WorkItemFollowUpCursor | null;
|
|
666
|
+
}>;
|
|
667
|
+
getDispatch(itemId: string): WorkItemDispatchRecord | undefined;
|
|
668
|
+
/** Final synchronous wake fence. This method calls no peer or user callback;
|
|
669
|
+
* full SQLite text equality also closes Node 24's hidden-NUL projection gap. */
|
|
670
|
+
isWakeSnapshotCurrent(item: WorkItemRecord, dispatch: WorkItemDispatchRecord): boolean;
|
|
671
|
+
/**
|
|
672
|
+
* Pending dispatches whose due time has arrived.
|
|
673
|
+
*
|
|
674
|
+
* `occurred_at` doubles as the due time: admission sets it to the admit
|
|
675
|
+
* instant, a lease reclaim re-arms it at the reclaim instant, and a `waiting`
|
|
676
|
+
* report re-arms it at `now + limits.waitingResumeMs`. Filtering here keeps
|
|
677
|
+
* recovery lazy and prevents an early wake of a deliberately delayed resume.
|
|
678
|
+
*/
|
|
679
|
+
listOpenDispatches(limit: number): readonly WorkItemDispatchRecord[];
|
|
680
|
+
/** At most ten due waiting resumes, with durable keyset round-robin fairness. */
|
|
681
|
+
listDueWaitingResumes(limit?: number): readonly WorkItemDispatchRecord[];
|
|
682
|
+
/** Advance even past denied/expired-owner rows so later items are not starved. */
|
|
683
|
+
advanceWaitingResumeCursor(dispatch: WorkItemDispatchRecord): void;
|
|
684
|
+
/**
|
|
685
|
+
* Failed dispatches whose wake outcome is unknown and that still own one
|
|
686
|
+
* bounded retry inside the same generation.
|
|
687
|
+
*/
|
|
688
|
+
listRetryableUnknownDispatches(limit: number): readonly WorkItemDispatchRecord[];
|
|
689
|
+
markDispatchDispatched(itemId: string, occurrenceId: string): void;
|
|
690
|
+
markDispatchFailed(itemId: string, reason: string): void;
|
|
691
|
+
/**
|
|
692
|
+
* Record an ambiguous wake failure: the peer may or may not have committed
|
|
693
|
+
* the occurrence, so the row is failed with `unknown_after_send` and the
|
|
694
|
+
* generation's retry budget is spent once.
|
|
695
|
+
*
|
|
696
|
+
* The identity is preserved, so a retry resolves the same occurrence instead
|
|
697
|
+
* of minting a second run.
|
|
698
|
+
*/
|
|
699
|
+
markDispatchUnknown(itemId: string): WorkItemDispatchRecord;
|
|
700
|
+
/**
|
|
701
|
+
* Re-arm one failed-with-unknown row inside the *same* generation.
|
|
702
|
+
*
|
|
703
|
+
* The persisted event id and occurred-at are reused verbatim, so the retry is
|
|
704
|
+
* idempotent against the automation intake: if the first attempt did commit,
|
|
705
|
+
* the retry resolves that occurrence; if it did not, the retry creates it.
|
|
706
|
+
*/
|
|
707
|
+
retryUnknownDispatch(itemId: string): WorkItemDispatchRecord;
|
|
708
|
+
/**
|
|
709
|
+
* Re-arm a fresh wake after a claim-time revalidation denial.
|
|
710
|
+
*
|
|
711
|
+
* At claim time the occurrence already exists, so parking alone would leave
|
|
712
|
+
* the item without any future wake. A new generation is minted because the
|
|
713
|
+
* denied run never claimed the item; once the mandate allows again, the
|
|
714
|
+
* ordinary wake path hands the same item to a fresh occurrence.
|
|
715
|
+
*/
|
|
716
|
+
rearmAuthority(itemId: string): void;
|
|
717
|
+
/**
|
|
718
|
+
* Reclaim every claim whose lease elapsed. Lazy by design: no timer owns
|
|
719
|
+
* recovery, so a host that was down simply reclaims on the next touch.
|
|
720
|
+
*
|
|
721
|
+
* The expired claim is retired explicitly, the item returns to `queued` and
|
|
722
|
+
* its dispatch row is re-armed so the normal wake path can hand the item to a
|
|
723
|
+
* fresh occurrence. A re-queued item that nobody wakes would otherwise stay
|
|
724
|
+
* queued forever, counted against `maxOpenItems`.
|
|
725
|
+
*/
|
|
726
|
+
reclaimExpired(): ReclaimResult;
|
|
727
|
+
/** Latest claim for one run; a re-claim after expiry appends a newer row. */
|
|
728
|
+
findClaimByRun(runId: string): WorkItemClaimRecord | undefined;
|
|
729
|
+
activeClaim(itemId: string): WorkItemClaimRecord | undefined;
|
|
730
|
+
/**
|
|
731
|
+
* Compare-and-swap claim.
|
|
732
|
+
*
|
|
733
|
+
* A repeated claim from the same run replays the existing claim only while
|
|
734
|
+
* that claim is still active, so a tool retry after transport loss is safe.
|
|
735
|
+
* Once the lease elapsed the claim is retired and the same run obtains a new
|
|
736
|
+
* claim row (and a new attempt), instead of replaying a dead lease forever.
|
|
737
|
+
* A competing run loses with `claim-conflict`.
|
|
738
|
+
*/
|
|
739
|
+
claim(input: {
|
|
740
|
+
itemId: string;
|
|
741
|
+
runId: string;
|
|
742
|
+
occurrenceId: string;
|
|
743
|
+
leaseMs: number;
|
|
744
|
+
reclaimExpired?: boolean;
|
|
745
|
+
}): ClaimResult;
|
|
746
|
+
reportCount(itemId: string): number;
|
|
747
|
+
lastReport(itemId: string): WorkItemReportRecord | undefined;
|
|
748
|
+
reports(itemId: string): readonly WorkItemReportRecord[];
|
|
749
|
+
/**
|
|
750
|
+
* Compare the existing scoped key and normalized persisted payload in SQLite.
|
|
751
|
+
* Node 24.7.0 TEXT projections truncate at NUL; bound SQL comparisons retain
|
|
752
|
+
* every byte. The existing key format alone also has delimiter collisions.
|
|
753
|
+
*/
|
|
754
|
+
reportReplayState(input: Pick<WorkItemReportRecord, 'itemId' | 'idempotencyKey' | 'status' | 'summary' | 'truncated' | 'artifactPaths'>): 'absent' | 'match' | 'conflict';
|
|
755
|
+
/** Exact report and adjacent references, using the existing item/revision key. */
|
|
756
|
+
reportByRevision(itemId: string, revision: number): Readonly<{
|
|
757
|
+
report: WorkItemReportRecord;
|
|
758
|
+
previousRevision: number | null;
|
|
759
|
+
nextRevision: number | null;
|
|
760
|
+
}> | undefined;
|
|
761
|
+
/** Feedback evidence keeps immutable report TEXT bytes intact on Node 24.
|
|
762
|
+
* This reads exactly the requested revision and performs no state changes. */
|
|
763
|
+
feedbackReportByRevision(itemId: string, revision: number): WorkItemReportRecord | undefined;
|
|
764
|
+
/**
|
|
765
|
+
* Append one report revision under the active claim, then apply the state
|
|
766
|
+
* transition for that status.
|
|
767
|
+
*
|
|
768
|
+
* The caller's idempotency key is scoped to the claim row, so identical text
|
|
769
|
+
* reported by different claims (or different items) is not mistaken for a
|
|
770
|
+
* replay, while a retried call on the same claim returns the stored revision.
|
|
771
|
+
*/
|
|
772
|
+
report(input: {
|
|
773
|
+
itemId: string;
|
|
774
|
+
runId: string;
|
|
775
|
+
status: WorkItemReportStatus;
|
|
776
|
+
summary: string;
|
|
777
|
+
truncated: boolean;
|
|
778
|
+
artifactPaths: readonly string[];
|
|
779
|
+
idempotencyKey: string;
|
|
780
|
+
maxReports: number;
|
|
781
|
+
leaseMs: number;
|
|
782
|
+
waitingResumeMs: number;
|
|
783
|
+
}): ReportResult;
|
|
784
|
+
setReportDelivery(itemId: string, revision: number, state: WorkItemDeliveryState, deliveryId: string | null): void;
|
|
785
|
+
/** Terminal item states map to terminal claim states. */
|
|
786
|
+
static claimStateFor(report: WorkItemReportStatus): WorkItemClaimState;
|
|
787
|
+
/** Open states are exposed for admission accounting and tests. */
|
|
788
|
+
static openStates(): readonly WorkItemState[];
|
|
789
|
+
}
|
|
790
|
+
export {};
|
|
791
|
+
//# sourceMappingURL=store.d.ts.map
|