specrails-core 6.0.1 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/README.md +1 -1
  2. package/dist/agent-runtime/capabilities.js +3 -1
  3. package/dist/agent-runtime/cli-executor.d.ts +3 -0
  4. package/dist/agent-runtime/cli-executor.js +50 -13
  5. package/dist/agent-runtime/cli-process.js +6 -2
  6. package/dist/agent-runtime/cli.d.ts +15 -0
  7. package/dist/agent-runtime/cli.js +43 -9
  8. package/dist/agent-runtime/compact/chat-client.js +2 -1
  9. package/dist/agent-runtime/config.d.ts +4 -1
  10. package/dist/agent-runtime/config.js +41 -3
  11. package/dist/agent-runtime/core-host.d.ts +9 -3
  12. package/dist/agent-runtime/core-host.js +21 -18
  13. package/dist/agent-runtime/efficiency-summary.d.ts +4 -1
  14. package/dist/agent-runtime/efficiency-summary.js +30 -27
  15. package/dist/agent-runtime/efficiency-types.d.ts +4 -4
  16. package/dist/agent-runtime/efficiency.d.ts +1 -1
  17. package/dist/agent-runtime/efficiency.js +7 -6
  18. package/dist/agent-runtime/engine/__fixtures__/implementation-component.json +90 -0
  19. package/dist/agent-runtime/engine/__fixtures__/implementation-fixture.d.ts +11 -0
  20. package/dist/agent-runtime/engine/__fixtures__/implementation-fixture.js +60 -0
  21. package/dist/agent-runtime/engine/__fixtures__/implementation.json +43 -0
  22. package/dist/agent-runtime/engine/budget.d.ts +9 -0
  23. package/dist/agent-runtime/engine/budget.js +33 -0
  24. package/dist/agent-runtime/engine/canonical-json.d.ts +9 -0
  25. package/dist/agent-runtime/engine/canonical-json.js +162 -0
  26. package/dist/agent-runtime/engine/checkpoint/database.d.ts +67 -0
  27. package/dist/agent-runtime/engine/checkpoint/database.js +304 -0
  28. package/dist/agent-runtime/engine/checkpoint/lease.d.ts +17 -0
  29. package/dist/agent-runtime/engine/checkpoint/lease.js +82 -0
  30. package/dist/agent-runtime/engine/checkpoint/ledger.d.ts +133 -0
  31. package/dist/agent-runtime/engine/checkpoint/ledger.js +510 -0
  32. package/dist/agent-runtime/engine/checkpoint/saver.d.ts +25 -0
  33. package/dist/agent-runtime/engine/checkpoint/saver.js +146 -0
  34. package/dist/agent-runtime/engine/cli.d.ts +10 -0
  35. package/dist/agent-runtime/engine/cli.js +172 -0
  36. package/dist/agent-runtime/engine/compiler.d.ts +23 -0
  37. package/dist/agent-runtime/engine/compiler.js +261 -0
  38. package/dist/agent-runtime/engine/composition.d.ts +16 -0
  39. package/dist/agent-runtime/engine/composition.js +28 -0
  40. package/dist/agent-runtime/engine/concurrency.d.ts +14 -0
  41. package/dist/agent-runtime/engine/concurrency.js +55 -0
  42. package/dist/agent-runtime/engine/contracts.d.ts +273 -0
  43. package/dist/agent-runtime/engine/contracts.js +11 -0
  44. package/dist/agent-runtime/engine/definition-schema.d.ts +250 -0
  45. package/dist/agent-runtime/engine/definition-schema.js +313 -0
  46. package/dist/agent-runtime/engine/definition-types.d.ts +84 -0
  47. package/dist/agent-runtime/engine/definition-types.js +3 -0
  48. package/dist/agent-runtime/engine/definition-validator.d.ts +7 -0
  49. package/dist/agent-runtime/engine/definition-validator.js +187 -0
  50. package/dist/agent-runtime/engine/efficiency-summary.d.ts +62 -0
  51. package/dist/agent-runtime/engine/efficiency-summary.js +31 -0
  52. package/dist/agent-runtime/engine/events.d.ts +19 -0
  53. package/dist/agent-runtime/engine/events.js +88 -0
  54. package/dist/agent-runtime/engine/execution.d.ts +29 -0
  55. package/dist/agent-runtime/engine/execution.js +121 -0
  56. package/dist/agent-runtime/engine/expressions.d.ts +11 -0
  57. package/dist/agent-runtime/engine/expressions.js +172 -0
  58. package/dist/agent-runtime/engine/fork.d.ts +28 -0
  59. package/dist/agent-runtime/engine/fork.js +211 -0
  60. package/dist/agent-runtime/engine/graph-description.d.ts +48 -0
  61. package/dist/agent-runtime/engine/graph-description.js +16 -0
  62. package/dist/agent-runtime/engine/implementation-compiler.d.ts +214 -0
  63. package/dist/agent-runtime/engine/implementation-compiler.js +91 -0
  64. package/dist/agent-runtime/engine/index.d.ts +14 -0
  65. package/dist/agent-runtime/engine/index.js +14 -0
  66. package/dist/agent-runtime/engine/invocation-context.d.ts +11 -0
  67. package/dist/agent-runtime/engine/invocation-context.js +128 -0
  68. package/dist/agent-runtime/engine/otel.d.ts +15 -0
  69. package/dist/agent-runtime/engine/otel.js +132 -0
  70. package/dist/agent-runtime/engine/output.d.ts +4 -0
  71. package/dist/agent-runtime/engine/output.js +73 -0
  72. package/dist/agent-runtime/engine/piece-dependencies.d.ts +50 -0
  73. package/dist/agent-runtime/engine/piece-dependencies.js +193 -0
  74. package/dist/agent-runtime/engine/piece-registry.d.ts +19 -0
  75. package/dist/agent-runtime/engine/piece-registry.js +62 -0
  76. package/dist/agent-runtime/engine/pieces/assign.d.ts +4 -0
  77. package/dist/agent-runtime/engine/pieces/assign.js +35 -0
  78. package/dist/agent-runtime/engine/pieces/control.d.ts +5 -0
  79. package/dist/agent-runtime/engine/pieces/control.js +49 -0
  80. package/dist/agent-runtime/engine/pieces/decider.d.ts +5 -0
  81. package/dist/agent-runtime/engine/pieces/decider.js +70 -0
  82. package/dist/agent-runtime/engine/pieces/implementation-binding.d.ts +12 -0
  83. package/dist/agent-runtime/engine/pieces/implementation-binding.js +40 -0
  84. package/dist/agent-runtime/engine/pieces/implementation-journal.d.ts +25 -0
  85. package/dist/agent-runtime/engine/pieces/implementation-journal.js +192 -0
  86. package/dist/agent-runtime/engine/pieces/implementation.d.ts +23 -0
  87. package/dist/agent-runtime/engine/pieces/implementation.js +176 -0
  88. package/dist/agent-runtime/engine/pieces/index.d.ts +7 -0
  89. package/dist/agent-runtime/engine/pieces/index.js +22 -0
  90. package/dist/agent-runtime/engine/pieces/openspec.d.ts +3 -0
  91. package/dist/agent-runtime/engine/pieces/openspec.js +69 -0
  92. package/dist/agent-runtime/engine/pieces/ports.d.ts +48 -0
  93. package/dist/agent-runtime/engine/pieces/ports.js +1 -0
  94. package/dist/agent-runtime/engine/pieces/project-memory.d.ts +3 -0
  95. package/dist/agent-runtime/engine/pieces/project-memory.js +13 -0
  96. package/dist/agent-runtime/engine/pieces/prompt.d.ts +5 -0
  97. package/dist/agent-runtime/engine/pieces/prompt.js +130 -0
  98. package/dist/agent-runtime/engine/pieces/role-turn.d.ts +7 -0
  99. package/dist/agent-runtime/engine/pieces/role-turn.js +73 -0
  100. package/dist/agent-runtime/engine/pieces/shared.d.ts +67 -0
  101. package/dist/agent-runtime/engine/pieces/shared.js +40 -0
  102. package/dist/agent-runtime/engine/pieces/shell.d.ts +6 -0
  103. package/dist/agent-runtime/engine/pieces/shell.js +47 -0
  104. package/dist/agent-runtime/engine/pieces/verify.d.ts +7 -0
  105. package/dist/agent-runtime/engine/pieces/verify.js +52 -0
  106. package/dist/agent-runtime/engine/preflight.d.ts +27 -0
  107. package/dist/agent-runtime/engine/preflight.js +54 -0
  108. package/dist/agent-runtime/engine/regex.d.ts +3 -0
  109. package/dist/agent-runtime/engine/regex.js +19 -0
  110. package/dist/agent-runtime/engine/run-status.d.ts +563 -0
  111. package/dist/agent-runtime/engine/run-status.js +61 -0
  112. package/dist/agent-runtime/engine/runs.d.ts +605 -0
  113. package/dist/agent-runtime/engine/runs.js +247 -0
  114. package/dist/agent-runtime/engine/state.d.ts +64 -0
  115. package/dist/agent-runtime/engine/state.js +98 -0
  116. package/dist/agent-runtime/engine/steering/inbox.d.ts +54 -0
  117. package/dist/agent-runtime/engine/steering/inbox.js +113 -0
  118. package/dist/agent-runtime/engine/storage/fork-allocation.d.ts +21 -0
  119. package/dist/agent-runtime/engine/storage/fork-allocation.js +143 -0
  120. package/dist/agent-runtime/engine/storage/private-path.d.ts +11 -0
  121. package/dist/agent-runtime/engine/storage/private-path.js +74 -0
  122. package/dist/agent-runtime/engine/store/sqlite-store.d.ts +26 -0
  123. package/dist/agent-runtime/engine/store/sqlite-store.js +227 -0
  124. package/dist/agent-runtime/evaluation-corpus.d.ts +125 -0
  125. package/dist/agent-runtime/evaluation-corpus.js +4 -0
  126. package/dist/agent-runtime/evaluation.d.ts +9 -3
  127. package/dist/agent-runtime/evaluation.js +50 -8
  128. package/dist/agent-runtime/executor-types.d.ts +53 -3
  129. package/dist/agent-runtime/executor-types.js +35 -2
  130. package/dist/agent-runtime/executors.js +2 -2
  131. package/dist/agent-runtime/graph/artifacts.d.ts +7 -0
  132. package/dist/agent-runtime/graph/artifacts.js +82 -9
  133. package/dist/agent-runtime/graph/nodes.d.ts +2 -0
  134. package/dist/agent-runtime/graph/nodes.js +2 -2
  135. package/dist/agent-runtime/graph/roles.d.ts +6 -0
  136. package/dist/agent-runtime/graph/roles.js +23 -17
  137. package/dist/agent-runtime/kimi-acp.js +6 -6
  138. package/dist/agent-runtime/openai-executor.js +17 -12
  139. package/dist/agent-runtime/openspec.d.ts +17 -2
  140. package/dist/agent-runtime/openspec.js +54 -20
  141. package/dist/agent-runtime/prompts.d.ts +4 -3
  142. package/dist/agent-runtime/prompts.js +26 -5
  143. package/dist/agent-runtime/recovery.d.ts +1 -1
  144. package/dist/agent-runtime/repository-context.js +1 -1
  145. package/dist/agent-runtime/role-routing.js +4 -2
  146. package/dist/agent-runtime/role-state.d.ts +5 -0
  147. package/dist/agent-runtime/verification-plan.d.ts +2 -0
  148. package/dist/agent-runtime/verification-plan.js +10 -0
  149. package/dist/agent-runtime/workflow-types.d.ts +2 -0
  150. package/dist/agent-runtime/workflow.d.ts +3 -1
  151. package/dist/agent-runtime/workflow.js +7 -3
  152. package/dist/agent-runtime/workspace-tools.d.ts +2 -2
  153. package/dist/agent-runtime/workspace-tools.js +6 -6
  154. package/dist/installer/cli.js +5 -0
  155. package/dist/installer/phases/scaffold.d.ts +2 -2
  156. package/dist/installer/phases/scaffold.js +3 -7
  157. package/dist/pipeline/pipeline-state.d.ts +38 -4
  158. package/dist/pipeline/pipeline-state.js +94 -21
  159. package/integration-contract.json +83 -11
  160. package/package.json +12 -5
  161. package/schemas/agent-runtime.schema.json +93 -1
  162. package/schemas/workflow-definition.schema.json +312 -0
  163. package/templates/kimi/specrails/run-skill.mjs +15 -1
  164. package/templates/commands/specrails/batch-implement.md +0 -32
@@ -0,0 +1,563 @@
1
+ import { RunDatabase } from './checkpoint/database.js';
2
+ import { RunLedger } from './checkpoint/ledger.js';
3
+ /** An observer has no valid execution token; every attempted mutation remains fenced. */
4
+ export declare function observeLedger(database: RunDatabase): RunLedger;
5
+ export declare function projectRunStatus(ledger: RunLedger, compact?: boolean): {
6
+ metrics: import("../efficiency-types.js").RuntimeEfficiency;
7
+ efficiencySummary: {
8
+ reservations: {
9
+ pendingInvocations: number;
10
+ knownTokens: number;
11
+ knownCostUsd: number;
12
+ tokensUnknown: boolean;
13
+ costUnknown: boolean;
14
+ };
15
+ schemaVersion: 1;
16
+ currentEvidenceIds: string[];
17
+ planHash: string | null;
18
+ candidateHash: string | null;
19
+ runId: string;
20
+ workflowVersion: string;
21
+ technicalAcceptance: string;
22
+ archive: import("../../pipeline/pipeline-state.js").PhaseStatus;
23
+ delivery: "pending" | "complete" | "pending-host";
24
+ roles: {
25
+ role: string;
26
+ provider: string | null;
27
+ model: string | null;
28
+ effort: string | null;
29
+ observedModel: null;
30
+ observedEffort: null;
31
+ origin: string;
32
+ tier: "base" | "escalation";
33
+ }[];
34
+ invocations: {
35
+ byKind: {
36
+ [k: string]: number;
37
+ };
38
+ total: number;
39
+ complete: boolean;
40
+ promptBytes: number | null;
41
+ contextBytes: number | null;
42
+ handoffBytes: number | null;
43
+ fullContexts: number;
44
+ incrementalContexts: number;
45
+ };
46
+ escalations: {
47
+ role: string;
48
+ attemptId: string;
49
+ provider: string;
50
+ model: string | null;
51
+ effort: string | null;
52
+ reason: string | null;
53
+ }[];
54
+ escalationsTruncated: boolean;
55
+ checks: {
56
+ invalidated: number | null;
57
+ available: boolean;
58
+ complete: boolean;
59
+ executed: number | null;
60
+ reused: number | null;
61
+ notRun: number | null;
62
+ durationMs: number | null;
63
+ };
64
+ metrics: import("../efficiency-types.js").RuntimeEfficiency;
65
+ };
66
+ revision: number;
67
+ eventCursor: number;
68
+ forkOf?: string | undefined;
69
+ type: "runtime-status";
70
+ engineVersion: number;
71
+ state: {
72
+ nextNodePath: string;
73
+ nextStep: string;
74
+ steps: {
75
+ [k: string]: {
76
+ kind: string;
77
+ status: string;
78
+ visits: number;
79
+ };
80
+ };
81
+ scopes: {
82
+ output?: unknown;
83
+ nodePath: string;
84
+ scopeId: string;
85
+ branch: import("node:sqlite").SQLOutputValue;
86
+ kind: string;
87
+ status: string;
88
+ visits: number;
89
+ attemptId: string | null;
90
+ }[];
91
+ lease: {
92
+ owner: string;
93
+ epoch: number;
94
+ expiresAt: number;
95
+ active: boolean;
96
+ } | null;
97
+ recoverableSteps: {
98
+ nodePath: string;
99
+ scopeId: string;
100
+ attemptId: string;
101
+ status: string;
102
+ effect: "write";
103
+ }[];
104
+ steering: {
105
+ receipts: import("./steering/inbox.js").SteeringReceipt[];
106
+ pending: number;
107
+ consumed: number;
108
+ truncated: boolean;
109
+ consumptionReported: true;
110
+ };
111
+ reservations: {
112
+ pendingInvocations: number;
113
+ knownTokens: number;
114
+ knownCostUsd: number;
115
+ tokensUnknown: boolean;
116
+ costUnknown: boolean;
117
+ };
118
+ pendingInterrupts: {
119
+ id: string;
120
+ nodePath: string;
121
+ scopeId: string;
122
+ branchId?: string;
123
+ attemptId: string;
124
+ kind: string;
125
+ requestedAt: string;
126
+ value: import("./contracts.js").JsonValue;
127
+ answer?: import("./contracts.js").JsonValue;
128
+ }[];
129
+ recentFailures: {
130
+ nodePath: import("node:sqlite").SQLOutputValue;
131
+ scopeId: import("node:sqlite").SQLOutputValue;
132
+ branch: import("node:sqlite").SQLOutputValue;
133
+ status: import("node:sqlite").SQLOutputValue;
134
+ attempt: import("node:sqlite").SQLOutputValue;
135
+ visit: import("node:sqlite").SQLOutputValue;
136
+ at: import("node:sqlite").SQLOutputValue;
137
+ error: {
138
+ code: import("node:sqlite").SQLOutputValue;
139
+ message: string;
140
+ };
141
+ }[];
142
+ schemaVersion: 2;
143
+ runId: string;
144
+ traceId: string;
145
+ workflowId: string;
146
+ workflowVersion: string;
147
+ workflowFingerprint: string;
148
+ inputFingerprint: string;
149
+ status: import("../workflow-types.js").WorkflowStatus;
150
+ createdAt: string;
151
+ updatedAt: string;
152
+ nextAttempt: number;
153
+ transitions: number;
154
+ executionCount: number;
155
+ history: import("../workflow-types.js").StepAttemptRecord[];
156
+ events: import("../workflow-types.js").WorkflowEvent[];
157
+ budget: import("./contracts.js").WorkflowBudget;
158
+ usage: {
159
+ costUsd: number | null;
160
+ inputTokens: number | null;
161
+ outputTokens: number | null;
162
+ knownCostUsd: number;
163
+ knownTokens: number;
164
+ durationMs: number;
165
+ };
166
+ pendingApproval?: {
167
+ stepId: string;
168
+ requestedAt: string;
169
+ grantedAt?: string;
170
+ reason?: string;
171
+ };
172
+ pendingQuestion?: {
173
+ stepId: string;
174
+ requestedAt: string;
175
+ question: string;
176
+ answeredAt?: string;
177
+ answer?: string;
178
+ };
179
+ error?: string;
180
+ } | {
181
+ nextNodePath: string;
182
+ nextStep: string;
183
+ steps: {
184
+ [k: string]: {
185
+ kind: string;
186
+ status: string;
187
+ visits: number;
188
+ };
189
+ };
190
+ scopes: {
191
+ output?: unknown;
192
+ nodePath: string;
193
+ scopeId: string;
194
+ branch: import("node:sqlite").SQLOutputValue;
195
+ kind: string;
196
+ status: string;
197
+ visits: number;
198
+ attemptId: string | null;
199
+ }[];
200
+ lease: {
201
+ owner: string;
202
+ epoch: number;
203
+ expiresAt: number;
204
+ active: boolean;
205
+ } | null;
206
+ recoverableSteps: {
207
+ nodePath: string;
208
+ scopeId: string;
209
+ attemptId: string;
210
+ status: string;
211
+ effect: "write";
212
+ }[];
213
+ steering: {
214
+ receipts: import("./steering/inbox.js").SteeringReceipt[];
215
+ pending: number;
216
+ consumed: number;
217
+ truncated: boolean;
218
+ consumptionReported: true;
219
+ };
220
+ reservations: {
221
+ pendingInvocations: number;
222
+ knownTokens: number;
223
+ knownCostUsd: number;
224
+ tokensUnknown: boolean;
225
+ costUnknown: boolean;
226
+ };
227
+ pendingInterrupts: {
228
+ id: string;
229
+ nodePath: string;
230
+ scopeId: string;
231
+ branchId?: string;
232
+ attemptId: string;
233
+ kind: string;
234
+ requestedAt: string;
235
+ value: import("./contracts.js").JsonValue;
236
+ answer?: import("./contracts.js").JsonValue;
237
+ }[];
238
+ recentFailures: {
239
+ nodePath: import("node:sqlite").SQLOutputValue;
240
+ scopeId: import("node:sqlite").SQLOutputValue;
241
+ branch: import("node:sqlite").SQLOutputValue;
242
+ status: import("node:sqlite").SQLOutputValue;
243
+ attempt: import("node:sqlite").SQLOutputValue;
244
+ visit: import("node:sqlite").SQLOutputValue;
245
+ at: import("node:sqlite").SQLOutputValue;
246
+ error: {
247
+ code: import("node:sqlite").SQLOutputValue;
248
+ message: string;
249
+ };
250
+ }[];
251
+ pendingQuestion?: {
252
+ stepId: string;
253
+ requestedAt: string;
254
+ question: string;
255
+ answeredAt?: string;
256
+ answer?: string;
257
+ } | undefined;
258
+ pendingApproval?: {
259
+ stepId: string;
260
+ requestedAt: string;
261
+ grantedAt?: string;
262
+ reason?: string;
263
+ } | undefined;
264
+ runId: string;
265
+ traceId: string;
266
+ status: import("../workflow-types.js").WorkflowStatus;
267
+ updatedAt: string;
268
+ usage: {
269
+ costUsd: number | null;
270
+ inputTokens: number | null;
271
+ outputTokens: number | null;
272
+ knownCostUsd: number;
273
+ knownTokens: number;
274
+ durationMs: number;
275
+ };
276
+ };
277
+ workflow: {
278
+ id: string;
279
+ version: string;
280
+ source: string;
281
+ };
282
+ completion: any;
283
+ };
284
+ /** Status never fingerprints a repository, changes ACLs or acquires an execution lease. */
285
+ export declare function statusRun(directory: string, compact?: boolean): Promise<{
286
+ metrics: import("../efficiency-types.js").RuntimeEfficiency;
287
+ efficiencySummary: {
288
+ reservations: {
289
+ pendingInvocations: number;
290
+ knownTokens: number;
291
+ knownCostUsd: number;
292
+ tokensUnknown: boolean;
293
+ costUnknown: boolean;
294
+ };
295
+ schemaVersion: 1;
296
+ currentEvidenceIds: string[];
297
+ planHash: string | null;
298
+ candidateHash: string | null;
299
+ runId: string;
300
+ workflowVersion: string;
301
+ technicalAcceptance: string;
302
+ archive: import("../../pipeline/pipeline-state.js").PhaseStatus;
303
+ delivery: "pending" | "complete" | "pending-host";
304
+ roles: {
305
+ role: string;
306
+ provider: string | null;
307
+ model: string | null;
308
+ effort: string | null;
309
+ observedModel: null;
310
+ observedEffort: null;
311
+ origin: string;
312
+ tier: "base" | "escalation";
313
+ }[];
314
+ invocations: {
315
+ byKind: {
316
+ [k: string]: number;
317
+ };
318
+ total: number;
319
+ complete: boolean;
320
+ promptBytes: number | null;
321
+ contextBytes: number | null;
322
+ handoffBytes: number | null;
323
+ fullContexts: number;
324
+ incrementalContexts: number;
325
+ };
326
+ escalations: {
327
+ role: string;
328
+ attemptId: string;
329
+ provider: string;
330
+ model: string | null;
331
+ effort: string | null;
332
+ reason: string | null;
333
+ }[];
334
+ escalationsTruncated: boolean;
335
+ checks: {
336
+ invalidated: number | null;
337
+ available: boolean;
338
+ complete: boolean;
339
+ executed: number | null;
340
+ reused: number | null;
341
+ notRun: number | null;
342
+ durationMs: number | null;
343
+ };
344
+ metrics: import("../efficiency-types.js").RuntimeEfficiency;
345
+ };
346
+ revision: number;
347
+ eventCursor: number;
348
+ forkOf?: string | undefined;
349
+ type: "runtime-status";
350
+ engineVersion: number;
351
+ state: {
352
+ nextNodePath: string;
353
+ nextStep: string;
354
+ steps: {
355
+ [k: string]: {
356
+ kind: string;
357
+ status: string;
358
+ visits: number;
359
+ };
360
+ };
361
+ scopes: {
362
+ output?: unknown;
363
+ nodePath: string;
364
+ scopeId: string;
365
+ branch: import("node:sqlite").SQLOutputValue;
366
+ kind: string;
367
+ status: string;
368
+ visits: number;
369
+ attemptId: string | null;
370
+ }[];
371
+ lease: {
372
+ owner: string;
373
+ epoch: number;
374
+ expiresAt: number;
375
+ active: boolean;
376
+ } | null;
377
+ recoverableSteps: {
378
+ nodePath: string;
379
+ scopeId: string;
380
+ attemptId: string;
381
+ status: string;
382
+ effect: "write";
383
+ }[];
384
+ steering: {
385
+ receipts: import("./steering/inbox.js").SteeringReceipt[];
386
+ pending: number;
387
+ consumed: number;
388
+ truncated: boolean;
389
+ consumptionReported: true;
390
+ };
391
+ reservations: {
392
+ pendingInvocations: number;
393
+ knownTokens: number;
394
+ knownCostUsd: number;
395
+ tokensUnknown: boolean;
396
+ costUnknown: boolean;
397
+ };
398
+ pendingInterrupts: {
399
+ id: string;
400
+ nodePath: string;
401
+ scopeId: string;
402
+ branchId?: string;
403
+ attemptId: string;
404
+ kind: string;
405
+ requestedAt: string;
406
+ value: import("./contracts.js").JsonValue;
407
+ answer?: import("./contracts.js").JsonValue;
408
+ }[];
409
+ recentFailures: {
410
+ nodePath: import("node:sqlite").SQLOutputValue;
411
+ scopeId: import("node:sqlite").SQLOutputValue;
412
+ branch: import("node:sqlite").SQLOutputValue;
413
+ status: import("node:sqlite").SQLOutputValue;
414
+ attempt: import("node:sqlite").SQLOutputValue;
415
+ visit: import("node:sqlite").SQLOutputValue;
416
+ at: import("node:sqlite").SQLOutputValue;
417
+ error: {
418
+ code: import("node:sqlite").SQLOutputValue;
419
+ message: string;
420
+ };
421
+ }[];
422
+ schemaVersion: 2;
423
+ runId: string;
424
+ traceId: string;
425
+ workflowId: string;
426
+ workflowVersion: string;
427
+ workflowFingerprint: string;
428
+ inputFingerprint: string;
429
+ status: import("../workflow-types.js").WorkflowStatus;
430
+ createdAt: string;
431
+ updatedAt: string;
432
+ nextAttempt: number;
433
+ transitions: number;
434
+ executionCount: number;
435
+ history: import("../workflow-types.js").StepAttemptRecord[];
436
+ events: import("../workflow-types.js").WorkflowEvent[];
437
+ budget: import("./contracts.js").WorkflowBudget;
438
+ usage: {
439
+ costUsd: number | null;
440
+ inputTokens: number | null;
441
+ outputTokens: number | null;
442
+ knownCostUsd: number;
443
+ knownTokens: number;
444
+ durationMs: number;
445
+ };
446
+ pendingApproval?: {
447
+ stepId: string;
448
+ requestedAt: string;
449
+ grantedAt?: string;
450
+ reason?: string;
451
+ };
452
+ pendingQuestion?: {
453
+ stepId: string;
454
+ requestedAt: string;
455
+ question: string;
456
+ answeredAt?: string;
457
+ answer?: string;
458
+ };
459
+ error?: string;
460
+ } | {
461
+ nextNodePath: string;
462
+ nextStep: string;
463
+ steps: {
464
+ [k: string]: {
465
+ kind: string;
466
+ status: string;
467
+ visits: number;
468
+ };
469
+ };
470
+ scopes: {
471
+ output?: unknown;
472
+ nodePath: string;
473
+ scopeId: string;
474
+ branch: import("node:sqlite").SQLOutputValue;
475
+ kind: string;
476
+ status: string;
477
+ visits: number;
478
+ attemptId: string | null;
479
+ }[];
480
+ lease: {
481
+ owner: string;
482
+ epoch: number;
483
+ expiresAt: number;
484
+ active: boolean;
485
+ } | null;
486
+ recoverableSteps: {
487
+ nodePath: string;
488
+ scopeId: string;
489
+ attemptId: string;
490
+ status: string;
491
+ effect: "write";
492
+ }[];
493
+ steering: {
494
+ receipts: import("./steering/inbox.js").SteeringReceipt[];
495
+ pending: number;
496
+ consumed: number;
497
+ truncated: boolean;
498
+ consumptionReported: true;
499
+ };
500
+ reservations: {
501
+ pendingInvocations: number;
502
+ knownTokens: number;
503
+ knownCostUsd: number;
504
+ tokensUnknown: boolean;
505
+ costUnknown: boolean;
506
+ };
507
+ pendingInterrupts: {
508
+ id: string;
509
+ nodePath: string;
510
+ scopeId: string;
511
+ branchId?: string;
512
+ attemptId: string;
513
+ kind: string;
514
+ requestedAt: string;
515
+ value: import("./contracts.js").JsonValue;
516
+ answer?: import("./contracts.js").JsonValue;
517
+ }[];
518
+ recentFailures: {
519
+ nodePath: import("node:sqlite").SQLOutputValue;
520
+ scopeId: import("node:sqlite").SQLOutputValue;
521
+ branch: import("node:sqlite").SQLOutputValue;
522
+ status: import("node:sqlite").SQLOutputValue;
523
+ attempt: import("node:sqlite").SQLOutputValue;
524
+ visit: import("node:sqlite").SQLOutputValue;
525
+ at: import("node:sqlite").SQLOutputValue;
526
+ error: {
527
+ code: import("node:sqlite").SQLOutputValue;
528
+ message: string;
529
+ };
530
+ }[];
531
+ pendingQuestion?: {
532
+ stepId: string;
533
+ requestedAt: string;
534
+ question: string;
535
+ answeredAt?: string;
536
+ answer?: string;
537
+ } | undefined;
538
+ pendingApproval?: {
539
+ stepId: string;
540
+ requestedAt: string;
541
+ grantedAt?: string;
542
+ reason?: string;
543
+ } | undefined;
544
+ runId: string;
545
+ traceId: string;
546
+ status: import("../workflow-types.js").WorkflowStatus;
547
+ updatedAt: string;
548
+ usage: {
549
+ costUsd: number | null;
550
+ inputTokens: number | null;
551
+ outputTokens: number | null;
552
+ knownCostUsd: number;
553
+ knownTokens: number;
554
+ durationMs: number;
555
+ };
556
+ };
557
+ workflow: {
558
+ id: string;
559
+ version: string;
560
+ source: string;
561
+ };
562
+ completion: any;
563
+ }>;
@@ -0,0 +1,61 @@
1
+ import { RunDatabase } from './checkpoint/database.js';
2
+ import { RunLedger } from './checkpoint/ledger.js';
3
+ import { EngineError } from './contracts.js';
4
+ import { ledgerWorkflowState } from './invocation-context.js';
5
+ import { runtimeEfficiency } from '../efficiency.js';
6
+ import path from 'node:path';
7
+ import { definitionEfficiencySummary } from './efficiency-summary.js';
8
+ import { ControlInbox } from './steering/inbox.js';
9
+ /** An observer has no valid execution token; every attempted mutation remains fenced. */
10
+ export function observeLedger(database) {
11
+ const row = database.sqlite.prepare('SELECT run_id,definition_json FROM runs').get();
12
+ if (!row)
13
+ throw new EngineError('run_not_found', 'Run does not exist');
14
+ const definition = JSON.parse(String(row.definition_json));
15
+ return new RunLedger(database, { runId: String(row.run_id), owner: 'read-only-observer', epoch: -1, expiresAt: 0 }, { maxTransitions: definition.maxTransitions });
16
+ }
17
+ export function projectRunStatus(ledger, compact = true) {
18
+ const row = ledger.run(), definition = JSON.parse(String(row.definition_json));
19
+ const base = ledgerWorkflowState(ledger, definition, '*'), pending = ledger.pendingInterrupts();
20
+ const steps = ledger.db.sqlite.prepare(`SELECT s.*, a.output_json, a.terminal_digest FROM steps s
21
+ LEFT JOIN attempts a ON a.attempt_id=s.last_attempt_id AND a.run_id=s.run_id
22
+ WHERE s.run_id=? ORDER BY s.node_path,s.scope_id`).all(ledger.runId);
23
+ const failures = ledger.db.sqlite.prepare("SELECT node_path,scope_id,branch,status,attempt,visit,ended_at,error_code,error_message FROM attempts WHERE run_id=? AND status IN ('failed','interrupted','blocked') ORDER BY started_at DESC LIMIT 8").all(ledger.runId);
24
+ const lease = ledger.lease.current();
25
+ const recoverable = ledger.db.sqlite.prepare("SELECT a.node_path,a.scope_id,a.attempt_id,a.status,v.effect FROM attempts a JOIN visits v ON a.visit_id=v.visit_id JOIN steps s ON s.last_attempt_id=a.attempt_id WHERE a.run_id=? AND a.terminal_digest IS NULL AND a.status IN ('running','interrupted') AND v.effect='write'").all(ledger.runId);
26
+ const next = pending[0]?.nodePath ?? (row.status === 'succeeded' || row.status === 'cancelled' ? null : base.nextStep);
27
+ const state = { ...(compact ? { runId: base.runId, traceId: base.traceId, status: base.status, updatedAt: base.updatedAt, usage: base.usage,
28
+ ...(base.pendingApproval ? { pendingApproval: base.pendingApproval } : {}), ...(base.pendingQuestion ? { pendingQuestion: base.pendingQuestion } : {}) } : base),
29
+ nextNodePath: next, nextStep: next,
30
+ steps: Object.fromEntries(steps.map(step => [String(step.node_path), { kind: String(step.kind), status: String(step.status), visits: Number(step.visits) }])),
31
+ scopes: steps.map(step => {
32
+ // Read only the current committed attempt. A previous successful visit is
33
+ // not evidence for a later pending/failed visit of the same node.
34
+ const result = !compact && step.terminal_digest && step.output_json
35
+ ? JSON.parse(String(step.output_json)) : undefined;
36
+ return { nodePath: String(step.node_path), scopeId: String(step.scope_id), branch: step.branch_id,
37
+ kind: String(step.kind), status: String(step.status), visits: Number(step.visits),
38
+ attemptId: step.last_attempt_id === null ? null : String(step.last_attempt_id),
39
+ ...(result && Object.hasOwn(result, 'output') ? { output: result.output } : {}) };
40
+ }),
41
+ lease: lease ? { owner: lease.owner, epoch: lease.epoch, expiresAt: lease.expiresAt, active: lease.expiresAt > Date.now() } : null,
42
+ recoverableSteps: recoverable.map(value => ({ nodePath: String(value.node_path), scopeId: String(value.scope_id), attemptId: String(value.attempt_id), status: String(value.status), effect: 'write' })),
43
+ steering: new ControlInbox(ledger.db, ledger.runId).status(),
44
+ reservations: ledger.reservationStatus(), pendingInterrupts: pending, recentFailures: failures.map(failure => ({ nodePath: failure.node_path, scopeId: failure.scope_id, branch: failure.branch,
45
+ status: failure.status, attempt: failure.attempt, visit: failure.visit, at: failure.ended_at, error: { code: failure.error_code, message: String(failure.error_message ?? '').slice(-6000) } })), };
46
+ return { type: 'runtime-status', engineVersion: 2, state,
47
+ workflow: { id: definition.id, version: definition.version, source: String(row.source) },
48
+ completion: row.completion_json ? JSON.parse(String(row.completion_json)) : null,
49
+ ...(row.fork_of ? { forkOf: String(row.fork_of) } : {}),
50
+ metrics: runtimeEfficiency(base), efficiencySummary: definitionEfficiencySummary(ledger, base), revision: ledger.db.revision, eventCursor: Number(row.next_event_sequence) - 1, };
51
+ }
52
+ /** Status never fingerprints a repository, changes ACLs or acquires an execution lease. */
53
+ export async function statusRun(directory, compact = true) {
54
+ const database = await RunDatabase.open(path.join(directory, 'run.sqlite'), { readOnly: true });
55
+ try {
56
+ return projectRunStatus(observeLedger(database), compact);
57
+ }
58
+ finally {
59
+ database.close();
60
+ }
61
+ }