@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.
Files changed (152) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +685 -2
  3. package/cordis.patch.yml +11 -0
  4. package/lib/acceptance-binding.d.ts +86 -0
  5. package/lib/acceptance-binding.d.ts.map +1 -0
  6. package/lib/acceptance-binding.js +250 -0
  7. package/lib/acceptance-binding.js.map +1 -0
  8. package/lib/admission.d.ts +95 -0
  9. package/lib/admission.d.ts.map +1 -0
  10. package/lib/admission.js +642 -0
  11. package/lib/admission.js.map +1 -0
  12. package/lib/authority.d.ts +99 -0
  13. package/lib/authority.d.ts.map +1 -0
  14. package/lib/authority.js +233 -0
  15. package/lib/authority.js.map +1 -0
  16. package/lib/config.d.ts +365 -0
  17. package/lib/config.d.ts.map +1 -0
  18. package/lib/config.js +672 -0
  19. package/lib/config.js.map +1 -0
  20. package/lib/continuation-contract.d.ts +126 -0
  21. package/lib/continuation-contract.d.ts.map +1 -0
  22. package/lib/continuation-contract.js +109 -0
  23. package/lib/continuation-contract.js.map +1 -0
  24. package/lib/continuation-record.d.ts +32 -0
  25. package/lib/continuation-record.d.ts.map +1 -0
  26. package/lib/continuation-record.js +57 -0
  27. package/lib/continuation-record.js.map +1 -0
  28. package/lib/continuation.d.ts +89 -0
  29. package/lib/continuation.d.ts.map +1 -0
  30. package/lib/continuation.js +607 -0
  31. package/lib/continuation.js.map +1 -0
  32. package/lib/diagnosis-contract.d.ts +95 -0
  33. package/lib/diagnosis-contract.d.ts.map +1 -0
  34. package/lib/diagnosis-contract.js +167 -0
  35. package/lib/diagnosis-contract.js.map +1 -0
  36. package/lib/diagnosis.d.ts +70 -0
  37. package/lib/diagnosis.d.ts.map +1 -0
  38. package/lib/diagnosis.js +466 -0
  39. package/lib/diagnosis.js.map +1 -0
  40. package/lib/dispatch.d.ts +100 -0
  41. package/lib/dispatch.d.ts.map +1 -0
  42. package/lib/dispatch.js +317 -0
  43. package/lib/dispatch.js.map +1 -0
  44. package/lib/engineering-context.d.ts +86 -0
  45. package/lib/engineering-context.d.ts.map +1 -0
  46. package/lib/engineering-context.js +263 -0
  47. package/lib/engineering-context.js.map +1 -0
  48. package/lib/evaluation.d.ts +125 -0
  49. package/lib/evaluation.d.ts.map +1 -0
  50. package/lib/evaluation.js +295 -0
  51. package/lib/evaluation.js.map +1 -0
  52. package/lib/event-follow.d.ts +93 -0
  53. package/lib/event-follow.d.ts.map +1 -0
  54. package/lib/event-follow.js +150 -0
  55. package/lib/event-follow.js.map +1 -0
  56. package/lib/feedback-targets.d.ts +91 -0
  57. package/lib/feedback-targets.d.ts.map +1 -0
  58. package/lib/feedback-targets.js +362 -0
  59. package/lib/feedback-targets.js.map +1 -0
  60. package/lib/index.d.ts +27 -0
  61. package/lib/index.d.ts.map +1 -0
  62. package/lib/index.js +25 -0
  63. package/lib/index.js.map +1 -0
  64. package/lib/intake-admission.d.ts +49 -0
  65. package/lib/intake-admission.d.ts.map +1 -0
  66. package/lib/intake-admission.js +100 -0
  67. package/lib/intake-admission.js.map +1 -0
  68. package/lib/intake-evaluation-runtime.d.ts +74 -0
  69. package/lib/intake-evaluation-runtime.d.ts.map +1 -0
  70. package/lib/intake-evaluation-runtime.js +343 -0
  71. package/lib/intake-evaluation-runtime.js.map +1 -0
  72. package/lib/intake-evaluation.d.ts +180 -0
  73. package/lib/intake-evaluation.d.ts.map +1 -0
  74. package/lib/intake-evaluation.js +440 -0
  75. package/lib/intake-evaluation.js.map +1 -0
  76. package/lib/intake.d.ts +118 -0
  77. package/lib/intake.d.ts.map +1 -0
  78. package/lib/intake.js +137 -0
  79. package/lib/intake.js.map +1 -0
  80. package/lib/ledger.d.ts +86 -0
  81. package/lib/ledger.d.ts.map +1 -0
  82. package/lib/ledger.js +145 -0
  83. package/lib/ledger.js.map +1 -0
  84. package/lib/mandate.d.ts +45 -0
  85. package/lib/mandate.d.ts.map +1 -0
  86. package/lib/mandate.js +168 -0
  87. package/lib/mandate.js.map +1 -0
  88. package/lib/outcome.d.ts +137 -0
  89. package/lib/outcome.d.ts.map +1 -0
  90. package/lib/outcome.js +303 -0
  91. package/lib/outcome.js.map +1 -0
  92. package/lib/owner-access.d.ts +35 -0
  93. package/lib/owner-access.d.ts.map +1 -0
  94. package/lib/owner-access.js +152 -0
  95. package/lib/owner-access.js.map +1 -0
  96. package/lib/owner-continuation.d.ts +27 -0
  97. package/lib/owner-continuation.d.ts.map +1 -0
  98. package/lib/owner-continuation.js +131 -0
  99. package/lib/owner-continuation.js.map +1 -0
  100. package/lib/owner-recall.d.ts +85 -0
  101. package/lib/owner-recall.d.ts.map +1 -0
  102. package/lib/owner-recall.js +134 -0
  103. package/lib/owner-recall.js.map +1 -0
  104. package/lib/owner-replies.d.ts +44 -0
  105. package/lib/owner-replies.d.ts.map +1 -0
  106. package/lib/owner-replies.js +268 -0
  107. package/lib/owner-replies.js.map +1 -0
  108. package/lib/peers.d.ts +624 -0
  109. package/lib/peers.d.ts.map +1 -0
  110. package/lib/peers.js +10 -0
  111. package/lib/peers.js.map +1 -0
  112. package/lib/policy-notice.d.ts +31 -0
  113. package/lib/policy-notice.d.ts.map +1 -0
  114. package/lib/policy-notice.js +137 -0
  115. package/lib/policy-notice.js.map +1 -0
  116. package/lib/reply-contract.d.ts +67 -0
  117. package/lib/reply-contract.d.ts.map +1 -0
  118. package/lib/reply-contract.js +58 -0
  119. package/lib/reply-contract.js.map +1 -0
  120. package/lib/service.d.ts +632 -0
  121. package/lib/service.d.ts.map +1 -0
  122. package/lib/service.js +2447 -0
  123. package/lib/service.js.map +1 -0
  124. package/lib/settlement.d.ts +74 -0
  125. package/lib/settlement.d.ts.map +1 -0
  126. package/lib/settlement.js +233 -0
  127. package/lib/settlement.js.map +1 -0
  128. package/lib/signals.d.ts +176 -0
  129. package/lib/signals.d.ts.map +1 -0
  130. package/lib/signals.js +497 -0
  131. package/lib/signals.js.map +1 -0
  132. package/lib/store.d.ts +791 -0
  133. package/lib/store.d.ts.map +1 -0
  134. package/lib/store.js +3266 -0
  135. package/lib/store.js.map +1 -0
  136. package/lib/tools.d.ts +7 -0
  137. package/lib/tools.d.ts.map +1 -0
  138. package/lib/tools.js +443 -0
  139. package/lib/tools.js.map +1 -0
  140. package/lib/types.d.ts +831 -0
  141. package/lib/types.d.ts.map +1 -0
  142. package/lib/types.js +29 -0
  143. package/lib/types.js.map +1 -0
  144. package/lib/version.d.ts +2 -0
  145. package/lib/version.d.ts.map +1 -0
  146. package/lib/version.js +2 -0
  147. package/lib/version.js.map +1 -0
  148. package/lib/workspace.d.ts +43 -0
  149. package/lib/workspace.d.ts.map +1 -0
  150. package/lib/workspace.js +137 -0
  151. package/lib/workspace.js.map +1 -0
  152. package/package.json +101 -3
package/lib/types.d.ts ADDED
@@ -0,0 +1,831 @@
1
+ /**
2
+ * Shared value shapes for the assistant work-item ledger.
3
+ *
4
+ * The ledger is the only durable authority for external work: every admitted
5
+ * signal becomes one row, and every state transition is either a
6
+ * compare-and-swap claim or an append-only report. No timer, outbox or session
7
+ * store is introduced here; wake-up, execution and delivery stay owned by
8
+ * `assistant-automations`, the native DSH agent run and `assistant-delivery`.
9
+ */
10
+ /** Terminal or in-flight lifecycle states of one durable work item. */
11
+ export type WorkItemState = 'queued' | 'claimed' | 'working' | 'waiting' | 'ready' | 'blocked' | 'failed' | 'dropped';
12
+ /** Lifecycle states that count against `maxOpenItems`. */
13
+ export declare const OPEN_STATES: readonly WorkItemState[];
14
+ /** States in which the model may claim the item. */
15
+ export declare const CLAIMABLE_STATES: readonly WorkItemState[];
16
+ /** States after which no further claim is possible without a new admission. */
17
+ export declare const TERMINAL_STATES: readonly WorkItemState[];
18
+ /** Status a worker may report. `progress` keeps the item open and renews the lease. */
19
+ export type WorkItemReportStatus = 'progress' | 'waiting' | 'ready' | 'blocked' | 'failed';
20
+ /** Report statuses that end the worker's ownership of the item. */
21
+ export declare const TERMINAL_REPORT_STATUSES: readonly WorkItemReportStatus[];
22
+ /** Delivery escalation state recorded next to a notified report. */
23
+ export type WorkItemDeliveryState = 'pending' | 'sent' | 'failed' | 'unknown';
24
+ /** Progress of the single automation wake-up that owes the item a run. */
25
+ export type WorkItemDispatchState = 'pending' | 'dispatched' | 'failed';
26
+ /** Lifecycle of one compare-and-swap claim row. */
27
+ export type WorkItemClaimState = 'active' | 'completed' | 'released' | 'expired';
28
+ /** Stable, closed error vocabulary. Callers branch on `code`, never on text. */
29
+ export type WorkItemErrorCode = 'disabled' | 'observe-mode' | 'invalid-input' | 'source-rejected' | 'kind-rejected' | 'cooldown' | 'rate-limited' | 'capacity' | 'owner-route-invalid' | 'owner-route-expired' | 'owner-route-unavailable' | 'authority-revoked' | 'authority-unavailable' | 'missing-dependency' | 'not-found' | 'invalid-state' | 'claim-conflict' | 'claim-expired' | 'retry-exhausted' | 'report-limit' | 'report-too-large' | 'dispatch-failed' | 'identity-mismatch' | 'storage';
30
+ /** Typed failure raised by admission, the ledger and the tools. */
31
+ export declare class WorkItemError extends Error {
32
+ readonly code: WorkItemErrorCode;
33
+ readonly detail: string | undefined;
34
+ constructor(code: WorkItemErrorCode, message: string, detail?: string);
35
+ }
36
+ /** Owner route re-anchored from `assistant-delivery` before every admission. */
37
+ export interface WorkItemScope {
38
+ readonly workspace: string;
39
+ readonly preset: string;
40
+ readonly principalId: string;
41
+ readonly ownerRouteId: string;
42
+ readonly expiresAt: number;
43
+ }
44
+ /** Receipt-shaped owner evidence captured for one item at admission time. */
45
+ export interface WorkItemOwnerEvidence {
46
+ readonly principalRecordId: string;
47
+ readonly principalVersion: number;
48
+ readonly workspace: string;
49
+ readonly agentPreset: string;
50
+ readonly bindingVersion: number;
51
+ readonly generation: number;
52
+ }
53
+ /**
54
+ * The admission decision an item was admitted under, persisted as audit-only.
55
+ *
56
+ * The fields are frozen at admission and never recomputed from the current
57
+ * configuration; revalidation replays the *identical* request and idempotency
58
+ * key against `assistant-policy`, which stays the only authority. This record
59
+ * grants nothing by itself.
60
+ */
61
+ export interface WorkItemAuthorityBasis {
62
+ /** Literal protocol marker; a different value is treated as malformed. */
63
+ readonly protocol: 'work-items/authority/v1';
64
+ readonly action: 'admit';
65
+ readonly subjectKind: 'background';
66
+ /** Intake source id at admission; the dedup identity can shift later. */
67
+ readonly sourceId: string;
68
+ readonly automationId: string;
69
+ readonly workspace: string;
70
+ readonly principal: string;
71
+ readonly resourceKind: 'automation';
72
+ readonly effect: 'allow';
73
+ readonly reasonCode: string;
74
+ readonly ruleId?: string;
75
+ readonly idempotencyKey: string;
76
+ readonly checkedAt: number;
77
+ /**
78
+ * Present only on items admitted through `admitDecision(...)`. Frozen with
79
+ * the basis in the same JSON column; grants nothing on its own.
80
+ */
81
+ readonly mandate?: WorkItemMandateBasis;
82
+ }
83
+ /** Where an execute decision came from. */
84
+ export type WorkItemDecisionOrigin = 'explicit' | 'inferred';
85
+ /** Mode the deciding intake ran in when it produced the decision. */
86
+ export type WorkItemDecisionMode = 'observe' | 'auto';
87
+ /**
88
+ * Narrow, producer-agnostic execute decision handed to `admitDecision(...)`.
89
+ *
90
+ * Deliberately independent of any intake ledger shape: the producer maps its
91
+ * own decision into this record. `decisionId` is the replay identity; the same
92
+ * id always resolves to the same work item.
93
+ */
94
+ export interface WorkItemExecuteDecision {
95
+ readonly protocol: 'work-items/execute-decision/v1';
96
+ readonly decisionId: string;
97
+ readonly verdict: 'execute';
98
+ readonly origin: WorkItemDecisionOrigin;
99
+ readonly mode: WorkItemDecisionMode;
100
+ /** Policy rule the decision claims to rely on; required for `inferred`. */
101
+ readonly policyRuleId?: string;
102
+ /** Remaining budget units the producer reported at decision time. */
103
+ readonly budgetRemaining: number;
104
+ /** The admitted scope of work. Frozen into the item; nothing outside it is admitted. */
105
+ readonly mandate: Readonly<{
106
+ kind: string;
107
+ title: string;
108
+ brief: string;
109
+ originBindingId: string;
110
+ /** TaskAcceptanceContract reference the work is accepted against. */
111
+ acceptanceRef: string;
112
+ }>;
113
+ /**
114
+ * Optional handle of an already-prepared TaskAcceptanceContract (WP21 slice 4).
115
+ *
116
+ * Only the handle crosses: admission re-reads the contract from the
117
+ * independent verifier itself and never trusts a caller-supplied body or
118
+ * verdict. When present, the item's completion is judged by that verifier.
119
+ */
120
+ readonly acceptance?: WorkItemAcceptanceHandle;
121
+ }
122
+ /** Handle naming one verifier-held TaskAcceptanceContract. */
123
+ export interface WorkItemAcceptanceHandle {
124
+ readonly contractId: string;
125
+ readonly contractDigest: string;
126
+ }
127
+ /** Host producer that froze a TaskAcceptanceContract, derived from its task kind. */
128
+ export type WorkItemAcceptanceAuthor = 'assistant-automations' | 'assistant-delivery' | 'assistant-goals';
129
+ /**
130
+ * Frozen summary of the TaskAcceptanceContract an item is accepted against.
131
+ *
132
+ * Read from the verifier at admission and stored inside the mandate, so the
133
+ * item's acceptance terms cannot drift after admission. The author (the Host
134
+ * producer that froze the contract), the verifier and the executor
135
+ * (`assistant-work-items`' worker) are three distinct identities.
136
+ */
137
+ export interface WorkItemAcceptanceBinding {
138
+ readonly protocol: 'work-items/acceptance-binding/v1';
139
+ readonly verifier: 'assistant-verifier';
140
+ readonly author: WorkItemAcceptanceAuthor;
141
+ readonly contractId: string;
142
+ readonly contractDigest: string;
143
+ readonly taskKind: string;
144
+ /** acceptanceDigest of the contract's task identity. */
145
+ readonly taskDigest: string;
146
+ /** acceptanceDigest of the contract's objective text. */
147
+ readonly objectiveDigest: string;
148
+ readonly profileDigest: string;
149
+ readonly criteria: number;
150
+ readonly expiresAt: number;
151
+ }
152
+ /** Frozen record of the decision an item was admitted for. */
153
+ export interface WorkItemMandateBasis {
154
+ readonly protocol: 'work-items/mandate/v1';
155
+ readonly decisionId: string;
156
+ readonly origin: WorkItemDecisionOrigin;
157
+ readonly mode: WorkItemDecisionMode;
158
+ readonly ruleId?: string;
159
+ readonly budgetRemaining: number;
160
+ /** sha256 over the decision identity (id, origin, rule, mandate fields); excludes mode and budget. */
161
+ readonly digest: string;
162
+ /** Independent acceptance binding; absent for decisions admitted without one. */
163
+ readonly acceptance?: WorkItemAcceptanceBinding;
164
+ }
165
+ /** Deterministic reasons an execute decision is refused before any durable write. */
166
+ export type WorkItemDecisionRefusal = 'inferred-requires-auto' | 'inferred-requires-rule' | 'budget-exhausted' | 'policy-rule-mismatch'
167
+ /** No verifier peer, or it holds no contract under the handle. */
168
+ | 'acceptance-unavailable'
169
+ /** The verifier's contract is invalid or differs from the handle or the item's owner scope. */
170
+ | 'acceptance-mismatch' | 'acceptance-expired'
171
+ /** The contract was already verified (or needs attention) before this work began. */
172
+ | 'acceptance-already-settled'
173
+ /** Author, verifier and executor are not three distinct identities. */
174
+ | 'acceptance-not-independent' | 'acceptance-not-awaiting' | 'acceptance-contract-bound';
175
+ /**
176
+ * Verdict read back from the independent verifier for one bound item.
177
+ *
178
+ * `objectiveStatus` is derived by `validateTaskVerificationReceipt` from the
179
+ * receipt's criterion results; no caller or worker input reaches it.
180
+ */
181
+ export interface WorkItemAcceptanceVerdict {
182
+ readonly itemId: string;
183
+ readonly verifier: 'assistant-verifier';
184
+ readonly contractId: string;
185
+ readonly contractDigest: string;
186
+ readonly receiptId: string;
187
+ readonly receiptDigest: string;
188
+ readonly objectiveStatus: 'achieved' | 'not-achieved' | 'unknown';
189
+ readonly completedAt: number;
190
+ /**
191
+ * The executed generation the verdict was settled for (attempt and
192
+ * occurrence at settle time). Absent on verdicts recorded before slice 7;
193
+ * `acceptance.verdictGate` never moves an item on such a verdict.
194
+ */
195
+ readonly attempt?: number;
196
+ readonly occurrenceId?: string | null;
197
+ readonly recordedAt: number;
198
+ }
199
+ /**
200
+ * WP21 slice 6: a worker run's own acceptance contract bound after wake as an
201
+ * append-only event, outside the mandate digest. The latest row is current;
202
+ * it only settles while `occurrenceId` is still the item's occurrence.
203
+ */
204
+ export interface WorkItemLateAcceptanceBinding {
205
+ readonly itemId: string;
206
+ readonly occurrenceId: string;
207
+ readonly binding: WorkItemAcceptanceBinding;
208
+ readonly recordedAt: number;
209
+ }
210
+ /** `blocked` reasons `acceptance.verdictGate` writes; the state itself is the existing `blocked`. */
211
+ export type WorkItemAcceptanceBlockReason = 'acceptance-not-achieved' | 'acceptance-unknown' | 'acceptance-needs-attention';
212
+ /** The executed generation a verdict gate may move: compare-and-swap inputs. */
213
+ export type WorkItemAcceptanceGateExpectation = Readonly<{
214
+ attempt: number;
215
+ occurrenceId: string | null;
216
+ }>;
217
+ export type WorkItemAcceptanceSettleResult =
218
+ /** The verifier peer is missing or could not answer; nothing was written. */
219
+ Readonly<{
220
+ outcome: 'unavailable';
221
+ detail: string;
222
+ }>
223
+ /** The verifier no longer holds the frozen contract, or its receipt does not validate; nothing was written. */
224
+ | Readonly<{
225
+ outcome: 'drift';
226
+ detail: string;
227
+ }> | Readonly<{
228
+ outcome: 'pending';
229
+ state: 'awaiting-execution' | 'pending' | 'verifying';
230
+ }>
231
+ /** `blockedReason` is present only when `acceptance.verdictGate` moved the item to `blocked` on this call. */
232
+ | Readonly<{
233
+ outcome: 'needs-attention';
234
+ reason: string | null;
235
+ blockedReason?: WorkItemAcceptanceBlockReason;
236
+ }> | Readonly<{
237
+ outcome: 'verified' | 'already-verified';
238
+ verdict: WorkItemAcceptanceVerdict;
239
+ blockedReason?: WorkItemAcceptanceBlockReason;
240
+ }>
241
+ /** A different receipt already settled this item (first receipt wins); nothing was written. */
242
+ | Readonly<{
243
+ outcome: 'identity-mismatch';
244
+ verdict: WorkItemAcceptanceVerdict;
245
+ receiptDigest: string;
246
+ }>;
247
+ export type WorkItemDecisionAdmitResult = Readonly<{
248
+ outcome: 'admitted';
249
+ item: WorkItemRecord;
250
+ dispatch: WorkItemDispatchRecord;
251
+ mandate: WorkItemMandateBasis;
252
+ }>
253
+ /** The decision id already owns an item (any state); no second item is opened. */
254
+ | Readonly<{
255
+ outcome: 'replayed';
256
+ item: WorkItemRecord;
257
+ dispatch: WorkItemDispatchRecord;
258
+ mandate: WorkItemMandateBasis;
259
+ }> | Readonly<{
260
+ outcome: 'refused';
261
+ reasonCode: WorkItemDecisionRefusal;
262
+ }>;
263
+ /**
264
+ * Host-supplied notice that the Policy peer now runs under a new version.
265
+ *
266
+ * `policyVersion` is opaque to this plugin (a config digest, a revision
267
+ * counter); it only names the change so each affected item is notified once.
268
+ */
269
+ export interface WorkItemPolicyChange {
270
+ readonly protocol: 'work-items/policy-change/v1';
271
+ readonly policyVersion: string;
272
+ /** Continue a pass that returned `next`; omitted to start from the oldest live item. */
273
+ readonly after?: WorkItemPolicyNoticeCursor;
274
+ }
275
+ /** Position of the last live item one notice pass assessed (admission order). */
276
+ export interface WorkItemPolicyNoticeCursor {
277
+ readonly createdAt: number;
278
+ readonly id: string;
279
+ }
280
+ /** Durable per-item notice that a Policy change affects its frozen basis. Never cancels. */
281
+ export interface WorkItemPolicyNotice {
282
+ readonly itemId: string;
283
+ readonly policyVersion: string;
284
+ /** `mandate-rule-changed`, `malformed-basis`, or the Policy deny reason. */
285
+ readonly reasonCode: string;
286
+ /** Rule the item's mandate (or basis) was admitted under; `null` when none was named. */
287
+ readonly frozenRuleId: string | null;
288
+ /** Rule the current Policy decided by; `null` on deny or an unnamed allow. */
289
+ readonly currentRuleId: string | null;
290
+ readonly decisionId: string | null;
291
+ readonly recordedAt: number;
292
+ }
293
+ export type WorkItemPolicyChangeResult = Readonly<{
294
+ outcome: 'noticed';
295
+ policyVersion: string;
296
+ /** Notices written by this call. */
297
+ notified: readonly WorkItemPolicyNotice[];
298
+ /** Items already notified for this version (restart / replay). */
299
+ alreadyNotified: readonly string[];
300
+ /** Live items whose basis still holds under the new Policy. */
301
+ unaffected: number;
302
+ /** Live pre-v7 items without a basis; nothing to compare against. */
303
+ legacy: number;
304
+ /** Items Policy could not answer for now; a later call with the same version retries them. */
305
+ unavailable: readonly string[];
306
+ /** Live items after this page; pass `next` as `after` to assess them. `null` when the pass is complete. */
307
+ next: WorkItemPolicyNoticeCursor | null;
308
+ remaining: number;
309
+ }>
310
+ /** The Policy peer is missing or cannot evaluate side-effect free; nothing was written. */
311
+ | Readonly<{
312
+ outcome: 'unavailable';
313
+ detail: string;
314
+ }>;
315
+ /**
316
+ * One human follow-up message on an item's work thread, handed over by the
317
+ * host that observed it. The message text stays with its producer; the item
318
+ * owns only its identity.
319
+ */
320
+ export interface WorkItemFollowUpInput {
321
+ readonly protocol: 'work-items/follow-up/v1';
322
+ readonly itemId: string;
323
+ /** Work thread binding; must equal the item's `originBindingId`. */
324
+ readonly bindingId: string;
325
+ readonly messageId: string;
326
+ /** Producer digest of the message; part of the follow-up identity. */
327
+ readonly sourceDigest: string;
328
+ }
329
+ /** `owned` while the item is live; `processed` by the item; `released` back to judgment after the item ended. */
330
+ export type WorkItemFollowUpState = 'owned' | 'processed' | 'released';
331
+ export interface WorkItemFollowUpRecord {
332
+ readonly itemId: string;
333
+ readonly messageId: string;
334
+ readonly bindingId: string;
335
+ readonly sourceDigest: string;
336
+ readonly state: WorkItemFollowUpState;
337
+ readonly ownedAt: number;
338
+ /** When it was processed or released; `null` while owned. */
339
+ readonly settledAt: number | null;
340
+ /** Terminal item state a released follow-up was released from. */
341
+ readonly releasedFrom: WorkItemState | null;
342
+ }
343
+ export type WorkItemFollowUpOwnResult = Readonly<{
344
+ outcome: 'owned' | 'already-owned';
345
+ followUp: WorkItemFollowUpRecord;
346
+ }>
347
+ /** The item already ended: nothing is written and the message stays with judgment. */
348
+ | Readonly<{
349
+ outcome: 'item-ended';
350
+ itemId: string;
351
+ state: WorkItemState;
352
+ }>;
353
+ /** One durable work item. */
354
+ export interface WorkItemRecord {
355
+ readonly id: string;
356
+ readonly dedupKey: string;
357
+ readonly dedupBucket: number;
358
+ readonly sourceId: string;
359
+ readonly kind: string;
360
+ readonly externalId: string;
361
+ readonly title: string;
362
+ readonly brief: string;
363
+ readonly briefTruncated: boolean;
364
+ readonly originBindingId: string;
365
+ readonly acceptanceRef: string | null;
366
+ readonly scope: WorkItemScope;
367
+ readonly owner: WorkItemOwnerEvidence;
368
+ readonly workerAutomationId: string;
369
+ /** Audit-only revalidation basis; `null` means a pre-v7 (legacy) item. */
370
+ readonly authority: WorkItemAuthorityBasis | null;
371
+ readonly state: WorkItemState;
372
+ readonly stateReason: string | null;
373
+ readonly attempt: number;
374
+ readonly maxAttempts: number;
375
+ readonly leaseUntil: number | null;
376
+ readonly leaseRunId: string | null;
377
+ readonly occurrenceId: string | null;
378
+ readonly workDir: string;
379
+ readonly lastReportStatus: WorkItemReportStatus | null;
380
+ readonly observed: boolean;
381
+ readonly createdAt: number;
382
+ readonly updatedAt: number;
383
+ }
384
+ /** Append-only lifecycle event; never rewritten. */
385
+ export interface WorkItemEventRecord {
386
+ readonly itemId: string;
387
+ readonly sequence: number;
388
+ readonly kind: string;
389
+ readonly actor: string;
390
+ readonly detail: string | null;
391
+ readonly recordedAt: number;
392
+ }
393
+ /** One compare-and-swap claim; a run may own several across lease renewals. */
394
+ export interface WorkItemClaimRecord {
395
+ readonly claimId: number;
396
+ readonly itemId: string;
397
+ readonly runId: string;
398
+ readonly occurrenceId: string;
399
+ readonly state: WorkItemClaimState;
400
+ readonly leasedUntil: number;
401
+ readonly createdAt: number;
402
+ readonly updatedAt: number;
403
+ }
404
+ /** One append-only worker report revision. */
405
+ export interface WorkItemReportRecord {
406
+ readonly itemId: string;
407
+ readonly revision: number;
408
+ readonly status: WorkItemReportStatus;
409
+ readonly summary: string;
410
+ readonly truncated: boolean;
411
+ readonly artifactPaths: readonly string[];
412
+ readonly idempotencyKey: string;
413
+ readonly deliveryKey: string;
414
+ readonly deliveryState: WorkItemDeliveryState | null;
415
+ readonly deliveryId: string | null;
416
+ readonly recordedAt: number;
417
+ }
418
+ /** One attempt end as reconstructed from the append-only event ledger. */
419
+ export interface WorkItemResumeAttempt {
420
+ readonly attempt: number;
421
+ readonly runId: string | null;
422
+ readonly startedAt: number;
423
+ readonly ended: 'expired' | 'reclaimed' | 'attempt-exhausted' | 'reported' | 'settled' | null;
424
+ readonly terminalStatus: WorkItemReportStatus | null;
425
+ }
426
+ /** One prior worker report summary, bounded for the resume brief. */
427
+ export interface WorkItemResumeReport {
428
+ readonly revision: number;
429
+ readonly status: WorkItemReportStatus;
430
+ readonly summary: string;
431
+ readonly summaryTruncated: boolean;
432
+ readonly recordedAt: number;
433
+ }
434
+ /** Compact latest settled outcome; evidence, baseline, inbox and authority stay out. */
435
+ export interface WorkItemResumeOutcome {
436
+ readonly revision: number;
437
+ readonly settledBy: WorkItemOutcomeSettledBy;
438
+ readonly executionStatus: WorkItemExecutionStatus;
439
+ readonly objectiveStatus: WorkItemObjectiveStatus;
440
+ readonly evidenceState: WorkItemOutcomeEvidenceState;
441
+ readonly evidenceReason: WorkItemOutcomeEvidenceReason | null;
442
+ readonly settledAt: number;
443
+ }
444
+ /**
445
+ * Bounded, read-only brief for a fresh occurrence continuing an item.
446
+ *
447
+ * Everything here is derived from the local append-only ledger at claim time;
448
+ * it never carries model memory or peer calls, and `truncated` advertises that
449
+ * older attempts or report revisions were cut by the fixed caps.
450
+ */
451
+ export interface WorkItemResumeContext {
452
+ readonly resumed: boolean;
453
+ readonly priorAttempts: number;
454
+ readonly attempts: readonly WorkItemResumeAttempt[];
455
+ readonly reports: readonly WorkItemResumeReport[];
456
+ readonly reportsTotal: number;
457
+ readonly latestOutcome: WorkItemResumeOutcome | null;
458
+ readonly truncated: boolean;
459
+ }
460
+ /**
461
+ * The single wake-up owed for one admitted item.
462
+ *
463
+ * `generation` scopes the external event identity to one delivery attempt of
464
+ * the item. Generation 0 is admission and keeps the historical identity
465
+ * (`eventId === itemId`, `occurredAt === item.createdAt`); every re-arm
466
+ * increments it and derives a fresh deterministic `eventId`, because the
467
+ * automation intake dedupes occurrences by `(automationId, eventId,
468
+ * occurredAt)` and would otherwise replay the *completed* occurrence instead of
469
+ * starting a new run.
470
+ *
471
+ * `wakeAttempts` counts ambiguous wake failures inside the current generation.
472
+ * It bounds recovery to exactly one re-wake: the row is retryable while the
473
+ * value is 1, and a second ambiguous failure leaves the row failed so the gap
474
+ * stays visible instead of looping forever.
475
+ */
476
+ export interface WorkItemDispatchRecord {
477
+ readonly itemId: string;
478
+ readonly automationId: string;
479
+ readonly eventId: string;
480
+ readonly occurredAt: number;
481
+ readonly generation: number;
482
+ readonly wakeAttempts: number;
483
+ readonly state: WorkItemDispatchState;
484
+ readonly occurrenceId: string | null;
485
+ readonly reason: string | null;
486
+ readonly createdAt: number;
487
+ readonly updatedAt: number;
488
+ }
489
+ /**
490
+ * Provenance of an automatically derived signal.
491
+ *
492
+ * The digest is the source's own canonical revision identity; it is never a
493
+ * hash of the owner-facing text, so a reworded but unchanged signal keeps its
494
+ * identity while a genuinely new revision changes it.
495
+ */
496
+ export interface WorkItemProvenance {
497
+ readonly source: string;
498
+ readonly sourceVersion: string;
499
+ readonly signalDigest: string;
500
+ readonly observedAt: number;
501
+ readonly evidence?: Readonly<Record<string, string | number | boolean>>;
502
+ }
503
+ /**
504
+ * One external thread this item follows for settlement.
505
+ *
506
+ * `kind` is the registered thread source (lower-kebab), `ref` is that source's
507
+ * own host identifier. Nothing here is authenticated by this plugin; resolution
508
+ * is the registered source's synchronous, read-only answer.
509
+ */
510
+ export interface WorkItemThreadRef {
511
+ readonly kind: string;
512
+ readonly ref: string;
513
+ }
514
+ /** Whether a followed thread has finished. */
515
+ export type WorkItemThreadClosureState = 'open' | 'closed';
516
+ /** How a closed thread ended, as its own source reports it. */
517
+ export type WorkItemThreadOutcome = 'succeeded' | 'failed' | 'cancelled' | 'unknown';
518
+ /** One synchronous, read-only observation of a followed thread. */
519
+ export interface WorkItemThreadClosure {
520
+ readonly state: WorkItemThreadClosureState;
521
+ readonly outcome: WorkItemThreadOutcome;
522
+ /** The source's own canonical revision identity for this observation. */
523
+ readonly digest: string;
524
+ readonly observedAt?: number;
525
+ }
526
+ /**
527
+ * Host-only registration of one thread source.
528
+ *
529
+ * `resolve` must be synchronous and read-only: it observes, it never mutates
530
+ * the host or the ledger. `undefined` means "this source cannot answer right
531
+ * now", which keeps the follow open rather than guessing a closure.
532
+ */
533
+ export interface WorkItemThreadSourceRegistration {
534
+ /** Stable lower-kebab id; also the `kind` an admission follows. */
535
+ readonly source: string;
536
+ /** Registration generation; a follow records it and a stale one cannot close. */
537
+ readonly generation: string;
538
+ resolve(ref: string): WorkItemThreadClosure | undefined;
539
+ /**
540
+ * Optional admission-time ref check. Synchronous and read-only; returning
541
+ * false (or throwing) rejects the admission with `invalid-input` before any
542
+ * write, so a source can refuse a ref that would close on stale evidence.
543
+ */
544
+ validate?(ref: string): boolean;
545
+ /**
546
+ * Optional admission-time ref rewrite, run before `validate` for a new item.
547
+ * Synchronous and read-only; returns the canonical ref to validate and store,
548
+ * or undefined (or throws) to reject with `invalid-input`. Only the returned
549
+ * form is ever persisted, so an alias the source accepts never leaks out.
550
+ */
551
+ canonicalize?(ref: string): string | undefined;
552
+ }
553
+ /** Persisted lifecycle of one followed thread. */
554
+ export type WorkItemFollowState = 'open' | 'closed';
555
+ /** Why an open follow currently cannot be resolved; never a silent loss. */
556
+ export type WorkItemFollowDegradedReason = 'source-missing' | 'resolver-failed' | 'generation-mismatch';
557
+ /** One persisted follow of an item's settlement on an external thread. */
558
+ export interface WorkItemFollowRecord {
559
+ readonly itemId: string;
560
+ readonly position: number;
561
+ readonly kind: string;
562
+ readonly ref: string;
563
+ readonly state: WorkItemFollowState;
564
+ /** Only a closed follow carries an outcome (and its source digest). */
565
+ readonly outcome: WorkItemThreadOutcome | null;
566
+ readonly digest: string | null;
567
+ /** Registered source at admission; persisted for audit and fencing. */
568
+ readonly source: string;
569
+ /** Source generation at admission; a newer registration cannot close this follow. */
570
+ readonly sourceGeneration: string;
571
+ readonly openedAt: number;
572
+ readonly closedAt: number | null;
573
+ }
574
+ /** Bounded follow health projection; counts only, never refs or digests. */
575
+ export interface WorkItemFollowHealth {
576
+ readonly open: number;
577
+ readonly closed: number;
578
+ /**
579
+ * Open follows this host currently cannot resolve: the source is no longer
580
+ * registered, its generation moved, or its resolver failed. Such an item
581
+ * stays `waiting` and is never guessed closed.
582
+ */
583
+ readonly unresolved: number;
584
+ readonly degraded: WorkItemFollowDegradedReason | null;
585
+ }
586
+ /** Input accepted by `assistantWorkItems.admit()`. */
587
+ export interface WorkItemAdmitInput {
588
+ readonly kind: string;
589
+ readonly externalId: string;
590
+ readonly title: string;
591
+ readonly brief: string;
592
+ readonly originBindingId: string;
593
+ readonly acceptanceRef?: string;
594
+ readonly provenance?: WorkItemProvenance;
595
+ /**
596
+ * Threads whose eventual closure bounds this item's settlement wait.
597
+ *
598
+ * A follow is not authority: it can only end the bounded wait early and park
599
+ * the item in `waiting` while the thread is open. It never asserts that the
600
+ * objective was achieved, and it cannot observe delivery evidence.
601
+ */
602
+ readonly follows?: readonly WorkItemThreadRef[];
603
+ }
604
+ /** Why an admission did not create a new item. */
605
+ export type WorkItemAdmitReason = 'duplicate' | 'fenced';
606
+ /** What a withdrawal did to the item the canonical signal already produced. */
607
+ export type WorkItemWithdrawOutcome =
608
+ /** An open item was moved to `dropped` and its pending dispatch failed. */
609
+ 'withdrawn'
610
+ /** The item was already terminal; nothing changed (idempotent no-op). */
611
+ | 'settled'
612
+ /** No item was ever admitted for this canonical signal. */
613
+ | 'absent';
614
+ /** Result of one withdrawal attempt. */
615
+ export interface WorkItemWithdrawResult {
616
+ readonly outcome: WorkItemWithdrawOutcome;
617
+ /**
618
+ * Items actually retired for `withdrawn` (there can be more than one when an
619
+ * older, still-open row lived in a previous dedup window), the newest item for
620
+ * `settled`, and empty for `absent`.
621
+ */
622
+ readonly items: readonly WorkItemRecord[];
623
+ }
624
+ /** Result of one admission attempt. */
625
+ export interface WorkItemAdmitResult {
626
+ readonly item: WorkItemRecord;
627
+ readonly created: boolean;
628
+ /** Present only when `created` is `false`. */
629
+ readonly reason?: WorkItemAdmitReason;
630
+ readonly dispatch: WorkItemDispatchRecord;
631
+ }
632
+ /** Notification intent derived from a terminal report. */
633
+ export interface WorkItemNotification {
634
+ readonly item: WorkItemRecord;
635
+ readonly report: WorkItemReportRecord;
636
+ readonly text: string;
637
+ readonly idempotencyKey: string;
638
+ readonly format: 'markdown';
639
+ }
640
+ /** Admission-authority revalidation projection for one health read. */
641
+ export interface WorkItemAuthorityHealth {
642
+ /** Open items admitted before the basis was persisted; they gate nothing. */
643
+ readonly legacy: number;
644
+ /** Open items currently parked by a failed revalidation. */
645
+ readonly parked: number;
646
+ readonly lastDeniedAt: number | null;
647
+ readonly lastDeniedReason: string | null;
648
+ }
649
+ /** Bounded runtime health projection; never exposes paths or briefs. */
650
+ export interface WorkItemHealth {
651
+ readonly enabled: boolean;
652
+ readonly mode: 'observe' | 'active';
653
+ readonly openItems: number;
654
+ readonly lastAdmitAt: number | null;
655
+ readonly lastDispatchAt: number | null;
656
+ /**
657
+ * Dispatch rows failed with `unknown_after_send`: the peer may or may not
658
+ * have committed the occurrence. Non-zero means the database really holds
659
+ * such a gap; recovery retries each row once and then leaves it visible.
660
+ */
661
+ readonly dispatchUnknown: number;
662
+ readonly workerConnected: boolean;
663
+ readonly ownerRouteValid: boolean;
664
+ readonly settlement: WorkItemSettlementHealth;
665
+ readonly evaluation: WorkItemEvaluationHealth;
666
+ readonly follows: WorkItemFollowHealth;
667
+ readonly authority: WorkItemAuthorityHealth;
668
+ }
669
+ /**
670
+ * How the guarded execution ended, as independently recorded by
671
+ * `assistant-delivery`.
672
+ *
673
+ * `unknown` is the honest default: the absence of evidence is not evidence of
674
+ * success, and a worker claiming success is not an execution outcome.
675
+ */
676
+ export type WorkItemExecutionStatus = 'succeeded' | 'failed' | 'timed-out' | 'cancelled' | 'unknown';
677
+ /**
678
+ * Objective outcome of the admitted work.
679
+ *
680
+ * Only an independent verifier may ever assert `achieved` or `partial`; this
681
+ * plugin derives nothing into those values from a worker self-report, and no
682
+ * automatic path sets them at all.
683
+ */
684
+ export type WorkItemObjectiveStatus = 'achieved' | 'partial' | 'not-achieved' | 'unknown';
685
+ /** Who produced the execution/objective claim recorded on one outcome. */
686
+ export type WorkItemOutcomeTrust = 'agent-self-report' | 'external-receipt' | 'deterministic-check';
687
+ /** Independent evidence state of one outcome revision. */
688
+ export type WorkItemOutcomeEvidenceState = 'pending' | 'observed' | 'unverified' | 'not-applicable';
689
+ /** Why an outcome revision carries no usable independent evidence. */
690
+ export type WorkItemOutcomeEvidenceReason =
691
+ /** The item's signal has no independent execution channel to observe. */
692
+ 'no-independent-source'
693
+ /** The observed receipt exceeded the evidence byte budget; it is dropped, never truncated. */
694
+ | 'evidence-too-large'
695
+ /** The bounded settlement window closed with no matching execution. */
696
+ | 'window-expired'
697
+ /** The window closed while the evidence channel was unavailable. */
698
+ | 'channel-unavailable'
699
+ /**
700
+ * A followed thread closed and ended the bounded wait. Thread closure is not
701
+ * independent delivery evidence, so the revision stays `unverified`.
702
+ */
703
+ | 'closed-by-thread';
704
+ /** Which durable transition appended this outcome revision. */
705
+ export type WorkItemOutcomeSettledBy = 'report-ready' | 'report-blocked' | 'report-failed' | 'withdrawn' | 'retry-exhausted' | 'observed-evidence' | 'window-expired'
706
+ /** Every followed thread closed; the deferred terminal report settled the item. */
707
+ | 'closed-by-thread';
708
+ /**
709
+ * Allowlisted evidence captured from the delivery channel.
710
+ *
711
+ * These keys are all authenticated, delivery-owned identities; owner-facing
712
+ * text is deliberately excluded so an outcome never carries owner content.
713
+ */
714
+ export interface WorkItemOutcomeEvidence {
715
+ readonly inboxId?: string;
716
+ readonly completionSequence?: number;
717
+ readonly completedAt?: number;
718
+ readonly executionStatus?: string;
719
+ readonly sourceDigest?: string;
720
+ readonly bindingVersion?: number;
721
+ readonly bindingGeneration?: number;
722
+ readonly scope?: string;
723
+ }
724
+ /**
725
+ * One append-only outcome revision.
726
+ *
727
+ * A terminal lifecycle state (`ready`, `blocked`, …) is a *report*, not proof:
728
+ * it says the worker stopped owning the item. This record is the separate,
729
+ * independently sourced evidence trail, and it only ever moves forward by
730
+ * appending a new revision for the same item.
731
+ */
732
+ export interface WorkItemOutcomeRecord {
733
+ readonly itemId: string;
734
+ readonly revision: number;
735
+ readonly settledBy: WorkItemOutcomeSettledBy;
736
+ readonly executionStatus: WorkItemExecutionStatus;
737
+ readonly objectiveStatus: WorkItemObjectiveStatus;
738
+ readonly trust: WorkItemOutcomeTrust;
739
+ readonly evidenceState: WorkItemOutcomeEvidenceState;
740
+ readonly evidenceReason: WorkItemOutcomeEvidenceReason | null;
741
+ readonly evidence: WorkItemOutcomeEvidence | null;
742
+ /** The admitted execution's completion sequence this outcome is fenced above. */
743
+ readonly baselineSequence: number | null;
744
+ readonly inboxId: string | null;
745
+ /** Authority hash admitted with this execution; the fence a receipt must match. */
746
+ readonly authorityHash: string | null;
747
+ /** Deadline of the bounded settlement window; only pending outcomes have one. */
748
+ readonly deadlineAt: number | null;
749
+ readonly settledAt: number;
750
+ readonly recordedAt: number;
751
+ /**
752
+ * Whether this revision has been handed to the trusted Evaluation producer
753
+ * seam. Only the newest revision of an item is ever exportable, and only once
754
+ * its evidence state is no longer `pending`.
755
+ */
756
+ readonly evaluationState: WorkItemEvaluationState;
757
+ /** Digest of the exact claims exported, so a replay is provably identical. */
758
+ readonly evaluationDigest: string | null;
759
+ readonly evaluationRecordedAt: number | null;
760
+ /** Bounded export attempts; a stuck row stays visible instead of looping. */
761
+ readonly evaluationAttempts: number;
762
+ }
763
+ /** Trusted Evaluation export state of one settled outcome revision. */
764
+ export type WorkItemEvaluationState = 'pending' | 'exported' | 'skipped';
765
+ /** One outcome revision joined with the report/delivery coordinates it refers to. */
766
+ export interface WorkItemOutcomeView {
767
+ readonly outcome: WorkItemOutcomeRecord;
768
+ readonly deliveryState: WorkItemDeliveryState | null;
769
+ readonly reportRevision: number | null;
770
+ }
771
+ /** Result of one bounded settlement pass. Host-only; never admits or wakes. */
772
+ export interface WorkItemSettlementReport {
773
+ readonly skipped: 'disabled' | 'not-due' | 'no-pending' | null;
774
+ readonly degraded: 'missing-dependency' | 'owner-route-unavailable' | null;
775
+ /** True only when the evidence channel was reached but failed. */
776
+ readonly failed: boolean;
777
+ readonly scanned: number;
778
+ readonly settled: number;
779
+ readonly expired: number;
780
+ /**
781
+ * Items still parked in `waiting` because at least one followed thread stayed
782
+ * open (or was unresolvable) this pass.
783
+ */
784
+ readonly deferred: number;
785
+ /** Items whose deferred terminal report settled because all follows closed. */
786
+ readonly closedByThread: number;
787
+ /** Resolution degradation observed this pass; `null` when every source spoke. */
788
+ readonly followDegraded: WorkItemFollowDegradedReason | null;
789
+ /** Item ids whose pending window resolved to an observed receipt this pass. */
790
+ readonly observedItemIds: readonly string[];
791
+ }
792
+ /** Bounded settlement health projection. */
793
+ export interface WorkItemSettlementHealth {
794
+ readonly enabled: boolean;
795
+ readonly pending: number;
796
+ readonly observed: number;
797
+ readonly unverified: number;
798
+ readonly degraded: string | null;
799
+ }
800
+ /** Bounded trusted-Evaluation export health projection; never exposes claims. */
801
+ export interface WorkItemEvaluationHealth {
802
+ /** True only in `active` mode, where settlement can actually export. */
803
+ readonly enabled: boolean;
804
+ /** The trusted Evaluation producer discovered a sink on the host, if any. */
805
+ readonly connected: boolean;
806
+ /** Settled revisions not yet exported; non-zero with no sink is a visible gap. */
807
+ readonly pending: number;
808
+ readonly exported: number;
809
+ readonly skipped: number;
810
+ /** Set when the last export attempt failed and the row stays retryable. */
811
+ readonly degraded: string | null;
812
+ }
813
+ /** Read-only WP20 intake judgment behind one admitted work item (`inspectIntakeProvenance`). */
814
+ export interface WorkItemIntakeProvenance {
815
+ readonly protocol: 'work-items/intake-provenance/v1';
816
+ readonly itemId: string;
817
+ /** The item's owner scope; a consumer must not attribute it to another scope. */
818
+ readonly scope: Readonly<{
819
+ workspace: string;
820
+ preset: string;
821
+ }>;
822
+ readonly source: string;
823
+ readonly sourceEventId: string;
824
+ readonly ruleId: string;
825
+ readonly policyVersion: string;
826
+ readonly mode: 'observe' | 'auto';
827
+ readonly level: 'ignore' | 'digest' | 'notify' | 'accept';
828
+ readonly wouldAccept: boolean;
829
+ readonly admittedAt: number;
830
+ }
831
+ //# sourceMappingURL=types.d.ts.map