@sift-wiki/conductor 0.2.0-beta.1 → 0.2.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 (95) hide show
  1. package/dist/adapters/claudeAgent.js +1 -0
  2. package/dist/adapters/claudeAgent.js.map +1 -1
  3. package/dist/adapters/codexAgent.js +1 -0
  4. package/dist/adapters/codexAgent.js.map +1 -1
  5. package/dist/adapters/fakeAgent.js +1 -0
  6. package/dist/adapters/fakeAgent.js.map +1 -1
  7. package/dist/adapters/httpAgent.js +1 -0
  8. package/dist/adapters/httpAgent.js.map +1 -1
  9. package/dist/adapters/processAgent.js +4 -0
  10. package/dist/adapters/processAgent.js.map +1 -1
  11. package/dist/adapters/provider/runProvider.js +4 -0
  12. package/dist/adapters/provider/runProvider.js.map +1 -1
  13. package/dist/adapters/provider/store.js +3 -4
  14. package/dist/adapters/provider/store.js.map +1 -1
  15. package/dist/adapters/types.d.ts +9 -0
  16. package/dist/cli.d.ts +6 -0
  17. package/dist/cli.js +16 -4
  18. package/dist/cli.js.map +1 -1
  19. package/dist/conductorClient.d.ts +56 -19
  20. package/dist/conductorClient.js +91 -40
  21. package/dist/conductorClient.js.map +1 -1
  22. package/dist/config.js +4 -5
  23. package/dist/config.js.map +1 -1
  24. package/dist/daemon.d.ts +19 -6
  25. package/dist/daemon.js +199 -121
  26. package/dist/daemon.js.map +1 -1
  27. package/dist/desktop/app/controller.d.ts +1 -1
  28. package/dist/desktop/app/runtimeController.d.ts +7 -0
  29. package/dist/desktop/app/runtimeController.js +12 -1
  30. package/dist/desktop/app/runtimeController.js.map +1 -1
  31. package/dist/localApi/contracts.d.ts +15 -4
  32. package/dist/localApi/contracts.js +19 -1
  33. package/dist/localApi/contracts.js.map +1 -1
  34. package/dist/localApi/recovery.d.ts +66 -0
  35. package/dist/localApi/recovery.js +118 -0
  36. package/dist/localApi/recovery.js.map +1 -0
  37. package/dist/localApi/server.js +3 -1
  38. package/dist/localApi/server.js.map +1 -1
  39. package/dist/localApp/service.js +16 -4
  40. package/dist/localApp/service.js.map +1 -1
  41. package/dist/protocol/fenced.d.ts +135 -0
  42. package/dist/protocol/fenced.js +142 -0
  43. package/dist/protocol/fenced.js.map +1 -0
  44. package/dist/redaction.js +2 -0
  45. package/dist/redaction.js.map +1 -1
  46. package/dist/runtime/atomicFile.d.ts +6 -0
  47. package/dist/runtime/atomicFile.js +78 -0
  48. package/dist/runtime/atomicFile.js.map +1 -0
  49. package/dist/runtime/daemonCapabilities.d.ts +7 -0
  50. package/dist/runtime/daemonCapabilities.js +24 -0
  51. package/dist/runtime/daemonCapabilities.js.map +1 -0
  52. package/dist/runtime/eventOutbox.d.ts +100 -0
  53. package/dist/runtime/eventOutbox.js +206 -0
  54. package/dist/runtime/eventOutbox.js.map +1 -0
  55. package/dist/runtime/executionJournal.d.ts +102 -0
  56. package/dist/runtime/executionJournal.js +209 -0
  57. package/dist/runtime/executionJournal.js.map +1 -0
  58. package/dist/runtime/executionSafety.d.ts +76 -0
  59. package/dist/runtime/executionSafety.js +207 -0
  60. package/dist/runtime/executionSafety.js.map +1 -0
  61. package/dist/runtime/fencedExecutionState.d.ts +43 -0
  62. package/dist/runtime/fencedExecutionState.js +158 -0
  63. package/dist/runtime/fencedExecutionState.js.map +1 -0
  64. package/dist/runtime/leaseManager.d.ts +38 -0
  65. package/dist/runtime/leaseManager.js +102 -0
  66. package/dist/runtime/leaseManager.js.map +1 -0
  67. package/dist/runtime/localRunQueue.d.ts +1 -1
  68. package/dist/runtime/localRunQueue.js +8 -0
  69. package/dist/runtime/localRunQueue.js.map +1 -1
  70. package/dist/runtime/localSessionCache.d.ts +1 -1
  71. package/dist/runtime/localSessionCache.js.map +1 -1
  72. package/dist/runtime/process.d.ts +13 -1
  73. package/dist/runtime/process.js +39 -9
  74. package/dist/runtime/process.js.map +1 -1
  75. package/dist/runtime/recoveryCoordinator.d.ts +19 -0
  76. package/dist/runtime/recoveryCoordinator.js +183 -0
  77. package/dist/runtime/recoveryCoordinator.js.map +1 -0
  78. package/dist/runtime/runtimeLock.d.ts +33 -0
  79. package/dist/runtime/runtimeLock.js +140 -0
  80. package/dist/runtime/runtimeLock.js.map +1 -0
  81. package/dist/runtime/runtimeService.d.ts +6 -1
  82. package/dist/runtime/runtimeService.js +54 -20
  83. package/dist/runtime/runtimeService.js.map +1 -1
  84. package/dist/runtime/taskExecution.d.ts +4 -0
  85. package/dist/runtime/taskExecution.js +32 -12
  86. package/dist/runtime/taskExecution.js.map +1 -1
  87. package/dist/types.d.ts +28 -13
  88. package/dist/version.d.ts +1 -1
  89. package/dist/version.js +1 -1
  90. package/dist/version.js.map +1 -1
  91. package/dist/workTypes.d.ts +5 -5
  92. package/dist-web/assets/index-SwT063kc.js +72 -0
  93. package/dist-web/index.html +2 -2
  94. package/package.json +1 -1
  95. package/dist-web/assets/index-D5X9InfE.js +0 -72
@@ -0,0 +1,206 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { readFile } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { z } from "zod";
5
+ import { defaultConfigPath } from "../config.js";
6
+ import { attemptAuthorityFenceSchema, authorityFence } from "../protocol/fenced.js";
7
+ import { redactSecrets } from "../redaction.js";
8
+ import { atomicWriteOwnerOnly, isNodeError } from "./atomicFile.js";
9
+ export const OUTBOX_SCHEMA_VERSION = 1;
10
+ const MAX_OUTBOX_BYTES = 1024 * 1024;
11
+ const DEFAULT_MAX_ENTRIES = 1_000;
12
+ const eventTypeSchema = z.enum([
13
+ "health",
14
+ "progress",
15
+ "log",
16
+ "artifact",
17
+ "approval_requested",
18
+ "completed",
19
+ "failed",
20
+ "cancelled",
21
+ ]);
22
+ const outboxEntrySchema = z.object({
23
+ clientEventId: z.string().min(1).max(200),
24
+ clientSequence: z.number().int().positive(),
25
+ attemptId: z.string().min(1),
26
+ runId: z.string().min(1),
27
+ authority: attemptAuthorityFenceSchema,
28
+ event: z.object({
29
+ eventType: eventTypeSchema,
30
+ payload: z.record(z.string(), z.unknown()).optional(),
31
+ occurredAt: z.iso.datetime().optional(),
32
+ }).strict(),
33
+ attempts: z.number().int().nonnegative(),
34
+ enqueuedAt: z.number().int().nonnegative(),
35
+ nextAttemptAt: z.number().int().nonnegative(),
36
+ lastErrorMessage: z.string().max(1_000).optional(),
37
+ }).strict();
38
+ const outboxFileSchema = z.object({
39
+ schemaVersion: z.literal(OUTBOX_SCHEMA_VERSION),
40
+ entries: z.array(outboxEntrySchema),
41
+ updatedAt: z.iso.datetime(),
42
+ }).strict();
43
+ const legacyOutboxFileSchema = outboxFileSchema.omit({ schemaVersion: true }).extend({
44
+ schemaVersion: z.literal(0),
45
+ }).strict();
46
+ export class DurableEventOutbox {
47
+ path;
48
+ options;
49
+ loaded = false;
50
+ snapshot = emptySnapshot();
51
+ constructor(path = defaultEventOutboxPath(), options = {}) {
52
+ this.path = path;
53
+ this.options = options;
54
+ }
55
+ async enqueue(input) {
56
+ await this.load();
57
+ if (this.snapshot.entries.length >= (this.options.maxEntries ?? DEFAULT_MAX_ENTRIES)) {
58
+ throw new Error("Durable event outbox is full; refusing to lose an acknowledged event identity.");
59
+ }
60
+ const now = this.nowMs();
61
+ const entry = outboxEntrySchema.parse({
62
+ clientEventId: this.createId(),
63
+ clientSequence: input.clientSequence,
64
+ attemptId: input.attemptId,
65
+ runId: input.runId,
66
+ authority: authorityFence(input.authority),
67
+ event: sanitizeEvent(input.event),
68
+ attempts: 0,
69
+ enqueuedAt: now,
70
+ nextAttemptAt: now,
71
+ ...(input.error === undefined ? {} : { lastErrorMessage: safeError(input.error) }),
72
+ });
73
+ this.snapshot.entries.push(entry);
74
+ await this.persist();
75
+ return structuredClone(entry);
76
+ }
77
+ async due(nowMs = this.nowMs()) {
78
+ await this.load();
79
+ return structuredClone(this.snapshot.entries.filter((entry) => entry.nextAttemptAt <= nowMs));
80
+ }
81
+ async acknowledge(attemptId, acknowledgedClientSequence) {
82
+ await this.load();
83
+ this.snapshot.entries = this.snapshot.entries.filter((entry) => entry.attemptId !== attemptId || entry.clientSequence > acknowledgedClientSequence);
84
+ await this.persist();
85
+ }
86
+ async discardAttempt(attemptId) {
87
+ await this.load();
88
+ this.snapshot.entries = this.snapshot.entries.filter((entry) => entry.attemptId !== attemptId);
89
+ await this.persist();
90
+ }
91
+ async listAttempt(attemptId) {
92
+ await this.load();
93
+ return structuredClone(this.snapshot.entries
94
+ .filter((entry) => entry.attemptId === attemptId)
95
+ .sort((left, right) => left.clientSequence - right.clientSequence));
96
+ }
97
+ async recordFailure(clientEventId, error, nextAttemptAt) {
98
+ await this.load();
99
+ const entry = this.snapshot.entries.find((candidate) => candidate.clientEventId === clientEventId);
100
+ if (entry === undefined)
101
+ return;
102
+ entry.attempts += 1;
103
+ entry.nextAttemptAt = nextAttemptAt;
104
+ entry.lastErrorMessage = safeError(error);
105
+ await this.persist();
106
+ }
107
+ async stats() {
108
+ await this.load();
109
+ return {
110
+ retainedEntries: this.snapshot.entries.length,
111
+ lastClientSequence: Math.max(0, ...this.snapshot.entries.map((entry) => entry.clientSequence)),
112
+ };
113
+ }
114
+ async load() {
115
+ if (this.loaded)
116
+ return;
117
+ const contents = await readOptional(this.path);
118
+ if (contents === undefined) {
119
+ this.loaded = true;
120
+ return;
121
+ }
122
+ const parsed = parseSnapshot(contents);
123
+ if (parsed !== undefined) {
124
+ this.snapshot = parsed.snapshot;
125
+ this.loaded = true;
126
+ if (parsed.migrated)
127
+ await this.persist();
128
+ return;
129
+ }
130
+ const backup = await readOptional(`${this.path}.last-good`);
131
+ const recovered = backup === undefined ? undefined : parseSnapshot(backup);
132
+ if (recovered === undefined) {
133
+ throw new Error("Durable event outbox is corrupt and has no valid last-good snapshot.");
134
+ }
135
+ this.snapshot = recovered.snapshot;
136
+ this.loaded = true;
137
+ await this.persist();
138
+ }
139
+ async persist() {
140
+ this.snapshot.updatedAt = new Date(this.nowMs()).toISOString();
141
+ const parsed = outboxFileSchema.parse(this.snapshot);
142
+ const contents = `${JSON.stringify(parsed, null, 2)}\n`;
143
+ if (Buffer.byteLength(contents, "utf8") > MAX_OUTBOX_BYTES) {
144
+ throw new Error(`Durable event outbox exceeds its ${String(MAX_OUTBOX_BYTES)} byte limit.`);
145
+ }
146
+ await atomicWriteOwnerOnly(this.path, contents, { ...this.options, backup: true });
147
+ }
148
+ nowMs() {
149
+ return (this.options.nowMs ?? Date.now)();
150
+ }
151
+ createId() {
152
+ return (this.options.createId ?? randomUUID)();
153
+ }
154
+ }
155
+ export function defaultEventOutboxPath(env = process.env) {
156
+ return path.join(path.dirname(defaultConfigPath(env)), "runtime", "event-outbox.json");
157
+ }
158
+ function emptySnapshot() {
159
+ return { schemaVersion: OUTBOX_SCHEMA_VERSION, entries: [], updatedAt: new Date(0).toISOString() };
160
+ }
161
+ function parseSnapshot(contents) {
162
+ let raw;
163
+ try {
164
+ raw = JSON.parse(contents);
165
+ }
166
+ catch {
167
+ return undefined;
168
+ }
169
+ const current = outboxFileSchema.safeParse(raw);
170
+ if (current.success)
171
+ return { snapshot: current.data, migrated: false };
172
+ const legacy = legacyOutboxFileSchema.safeParse(raw);
173
+ if (!legacy.success)
174
+ return undefined;
175
+ return { snapshot: { ...legacy.data, schemaVersion: OUTBOX_SCHEMA_VERSION }, migrated: true };
176
+ }
177
+ function sanitizeEvent(event) {
178
+ return {
179
+ ...event,
180
+ ...(event.payload === undefined ? {} : { payload: sanitizeJson(event.payload) }),
181
+ };
182
+ }
183
+ function sanitizeJson(value) {
184
+ return Object.fromEntries(Object.entries(value).map(([key, entry]) => {
185
+ if (typeof entry === "string")
186
+ return [key, redactSecrets(entry)];
187
+ if (Array.isArray(entry)) {
188
+ return [key, entry.map((item) => typeof item === "string" ? redactSecrets(item) : item)];
189
+ }
190
+ return [key, entry];
191
+ }));
192
+ }
193
+ function safeError(error) {
194
+ return redactSecrets(error instanceof Error ? error.message : "Unknown event delivery failure.").slice(0, 1_000);
195
+ }
196
+ async function readOptional(filePath) {
197
+ try {
198
+ return await readFile(filePath, "utf8");
199
+ }
200
+ catch (error) {
201
+ if (isNodeError(error) && error.code === "ENOENT")
202
+ return undefined;
203
+ throw error;
204
+ }
205
+ }
206
+ //# sourceMappingURL=eventOutbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eventOutbox.js","sourceRoot":"","sources":["../../src/runtime/eventOutbox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,102 @@
1
+ import { z } from "zod";
2
+ import { type AttemptAuthority } from "../protocol/fenced.js";
3
+ import { type AtomicWriteOptions } from "./atomicFile.js";
4
+ export declare const JOURNAL_SCHEMA_VERSION = 1;
5
+ declare const processIdentitySchema: z.ZodObject<{
6
+ pid: z.ZodNumber;
7
+ startMarker: z.ZodString;
8
+ }, z.core.$strict>;
9
+ declare const journalPhaseSchema: z.ZodEnum<{
10
+ superseded: "superseded";
11
+ claimed: "claimed";
12
+ starting: "starting";
13
+ running: "running";
14
+ authority_uncertain: "authority_uncertain";
15
+ recovering: "recovering";
16
+ interrupted: "interrupted";
17
+ overtime: "overtime";
18
+ terminal: "terminal";
19
+ }>;
20
+ export declare const executionJournalSchema: z.ZodObject<{
21
+ schemaVersion: z.ZodLiteral<1>;
22
+ attemptId: z.ZodString;
23
+ jobId: z.ZodString;
24
+ runId: z.ZodString;
25
+ taskRecordId: z.ZodOptional<z.ZodString>;
26
+ localKey: z.ZodString;
27
+ adapterType: z.ZodString;
28
+ authority: z.ZodObject<{
29
+ attemptId: z.ZodString;
30
+ leaseGeneration: z.ZodNumber;
31
+ leaseExpiresAt: z.ZodISODateTime;
32
+ mustStopAt: z.ZodISODateTime;
33
+ }, z.core.$strict>;
34
+ accessMode: z.ZodEnum<{
35
+ inspect: "inspect";
36
+ write: "write";
37
+ }>;
38
+ phase: z.ZodEnum<{
39
+ superseded: "superseded";
40
+ claimed: "claimed";
41
+ starting: "starting";
42
+ running: "running";
43
+ authority_uncertain: "authority_uncertain";
44
+ recovering: "recovering";
45
+ interrupted: "interrupted";
46
+ overtime: "overtime";
47
+ terminal: "terminal";
48
+ }>;
49
+ leaseHealth: z.ZodOptional<z.ZodEnum<{
50
+ healthy: "healthy";
51
+ retrying: "retrying";
52
+ "authority-uncertain": "authority-uncertain";
53
+ lost: "lost";
54
+ }>>;
55
+ provider: z.ZodObject<{
56
+ resumeSupported: z.ZodBoolean;
57
+ sessionId: z.ZodOptional<z.ZodString>;
58
+ processIdentity: z.ZodOptional<z.ZodObject<{
59
+ pid: z.ZodNumber;
60
+ startMarker: z.ZodString;
61
+ }, z.core.$strict>>;
62
+ }, z.core.$strict>;
63
+ lastAcknowledgedClientSequence: z.ZodNumber;
64
+ nextClientSequence: z.ZodNumber;
65
+ settlementIdempotencyKey: z.ZodOptional<z.ZodString>;
66
+ lastProgressAt: z.ZodOptional<z.ZodISODateTime>;
67
+ noProgressObservedAt: z.ZodOptional<z.ZodISODateTime>;
68
+ updatedAt: z.ZodISODateTime;
69
+ interruptionReason: z.ZodOptional<z.ZodString>;
70
+ terminalResult: z.ZodOptional<z.ZodObject<{
71
+ status: z.ZodEnum<{
72
+ cancelled: "cancelled";
73
+ completed: "completed";
74
+ failed: "failed";
75
+ overtime: "overtime";
76
+ }>;
77
+ summary: z.ZodString;
78
+ }, z.core.$strict>>;
79
+ }, z.core.$strict>;
80
+ export type SafeProcessIdentity = z.infer<typeof processIdentitySchema>;
81
+ export type ExecutionJournal = z.infer<typeof executionJournalSchema>;
82
+ export type ExecutionJournalPhase = z.infer<typeof journalPhaseSchema>;
83
+ export type JournalReadResult = {
84
+ journal: ExecutionJournal;
85
+ recoveredFromLastGood: boolean;
86
+ migrated: boolean;
87
+ };
88
+ export declare class ExecutionJournalStore {
89
+ readonly directory: string;
90
+ private readonly writeOptions;
91
+ constructor(directory?: string, writeOptions?: AtomicWriteOptions);
92
+ write(journal: ExecutionJournal): Promise<void>;
93
+ read(attemptId: string): Promise<JournalReadResult | undefined>;
94
+ listUnfinished(): Promise<JournalReadResult[]>;
95
+ list(): Promise<JournalReadResult[]>;
96
+ delete(attemptId: string): Promise<void>;
97
+ private pathFor;
98
+ private enforceRetention;
99
+ }
100
+ export declare function defaultExecutionJournalDirectory(env?: NodeJS.ProcessEnv): string;
101
+ export declare function authorityFromJournal(journal: ExecutionJournal): AttemptAuthority;
102
+ export {};
@@ -0,0 +1,209 @@
1
+ import { readFile, readdir, rename, rm } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { z } from "zod";
4
+ import { defaultConfigPath } from "../config.js";
5
+ import { attemptAuthoritySchema } from "../protocol/fenced.js";
6
+ import { redactSecrets } from "../redaction.js";
7
+ import { atomicWriteOwnerOnly, isNodeError } from "./atomicFile.js";
8
+ export const JOURNAL_SCHEMA_VERSION = 1;
9
+ const MAX_JOURNAL_BYTES = 64 * 1024;
10
+ const MAX_JOURNALS = 100;
11
+ const processIdentitySchema = z.object({
12
+ pid: z.number().int().positive(),
13
+ startMarker: z.string().min(1).max(500),
14
+ }).strict();
15
+ const journalPhaseSchema = z.enum([
16
+ "claimed",
17
+ "starting",
18
+ "running",
19
+ "authority_uncertain",
20
+ "recovering",
21
+ "interrupted",
22
+ "overtime",
23
+ "superseded",
24
+ "terminal",
25
+ ]);
26
+ const terminalResultSchema = z.object({
27
+ status: z.enum(["completed", "failed", "cancelled", "overtime"]),
28
+ summary: z.string().min(1).max(4_000),
29
+ }).strict();
30
+ export const executionJournalSchema = z.object({
31
+ schemaVersion: z.literal(JOURNAL_SCHEMA_VERSION),
32
+ attemptId: z.string().min(1),
33
+ jobId: z.string().min(1),
34
+ runId: z.string().min(1),
35
+ taskRecordId: z.string().min(1).optional(),
36
+ localKey: z.string().min(1),
37
+ adapterType: z.string().min(1),
38
+ authority: attemptAuthoritySchema,
39
+ accessMode: z.enum(["inspect", "write"]),
40
+ phase: journalPhaseSchema,
41
+ leaseHealth: z.enum(["healthy", "retrying", "authority-uncertain", "lost"]).optional(),
42
+ provider: z.object({
43
+ resumeSupported: z.boolean(),
44
+ sessionId: z.string().min(1).max(500).optional(),
45
+ processIdentity: processIdentitySchema.optional(),
46
+ }).strict(),
47
+ lastAcknowledgedClientSequence: z.number().int().nonnegative(),
48
+ nextClientSequence: z.number().int().positive(),
49
+ settlementIdempotencyKey: z.string().min(1).max(200).optional(),
50
+ lastProgressAt: z.iso.datetime().optional(),
51
+ noProgressObservedAt: z.iso.datetime().optional(),
52
+ updatedAt: z.iso.datetime(),
53
+ interruptionReason: z.string().min(1).max(1_000).optional(),
54
+ terminalResult: terminalResultSchema.optional(),
55
+ }).strict();
56
+ const legacyJournalSchema = executionJournalSchema.omit({ schemaVersion: true }).extend({
57
+ schemaVersion: z.literal(0),
58
+ }).strict();
59
+ export class ExecutionJournalStore {
60
+ directory;
61
+ writeOptions;
62
+ constructor(directory = defaultExecutionJournalDirectory(), writeOptions = {}) {
63
+ this.directory = directory;
64
+ this.writeOptions = writeOptions;
65
+ }
66
+ async write(journal) {
67
+ const parsed = executionJournalSchema.parse(sanitizeJournal(journal));
68
+ const contents = serializeBounded(parsed, MAX_JOURNAL_BYTES, "Execution journal");
69
+ await this.enforceRetention(parsed.attemptId);
70
+ await atomicWriteOwnerOnly(this.pathFor(parsed.attemptId), contents, {
71
+ ...this.writeOptions,
72
+ backup: true,
73
+ });
74
+ }
75
+ async read(attemptId) {
76
+ const filePath = this.pathFor(attemptId);
77
+ const primary = await readOptional(filePath);
78
+ if (primary === undefined)
79
+ return undefined;
80
+ const parsed = parseJournal(primary);
81
+ if (parsed !== undefined) {
82
+ if (parsed.migrated)
83
+ await this.write(parsed.journal);
84
+ return { ...parsed, recoveredFromLastGood: false };
85
+ }
86
+ const backup = await readOptional(`${filePath}.last-good`);
87
+ const recovered = backup === undefined ? undefined : parseJournal(backup);
88
+ if (recovered === undefined) {
89
+ await quarantine(filePath);
90
+ throw new Error("Execution recovery state is corrupt and has no valid last-good snapshot.");
91
+ }
92
+ await this.write(recovered.journal);
93
+ return { ...recovered, recoveredFromLastGood: true };
94
+ }
95
+ async listUnfinished() {
96
+ return (await this.list()).filter((result) => activeRecoveryPhase(result.journal.phase));
97
+ }
98
+ async list() {
99
+ let names;
100
+ try {
101
+ names = await readdir(this.directory);
102
+ }
103
+ catch (error) {
104
+ if (isNodeError(error) && error.code === "ENOENT")
105
+ return [];
106
+ throw error;
107
+ }
108
+ const results = [];
109
+ for (const name of names.filter((candidate) => candidate.endsWith(".json")).sort()) {
110
+ const attemptId = decodeURIComponent(name.slice(0, -5));
111
+ const result = await this.read(attemptId);
112
+ if (result !== undefined)
113
+ results.push(result);
114
+ }
115
+ return results;
116
+ }
117
+ async delete(attemptId) {
118
+ await rm(this.pathFor(attemptId), { force: true });
119
+ await rm(`${this.pathFor(attemptId)}.last-good`, { force: true });
120
+ }
121
+ pathFor(attemptId) {
122
+ return path.join(this.directory, `${encodeURIComponent(attemptId)}.json`);
123
+ }
124
+ async enforceRetention(currentAttemptId) {
125
+ let names;
126
+ try {
127
+ names = await readdir(this.directory);
128
+ }
129
+ catch (error) {
130
+ if (isNodeError(error) && error.code === "ENOENT")
131
+ return;
132
+ throw error;
133
+ }
134
+ const journals = names.filter((name) => name.endsWith(".json"));
135
+ if (journals.length >= MAX_JOURNALS && !journals.includes(`${encodeURIComponent(currentAttemptId)}.json`)) {
136
+ throw new Error(`Execution journal retention limit of ${String(MAX_JOURNALS)} was reached.`);
137
+ }
138
+ }
139
+ }
140
+ export function defaultExecutionJournalDirectory(env = process.env) {
141
+ return path.join(path.dirname(defaultConfigPath(env)), "runtime", "executions");
142
+ }
143
+ function parseJournal(contents) {
144
+ let raw;
145
+ try {
146
+ raw = JSON.parse(contents);
147
+ }
148
+ catch {
149
+ return undefined;
150
+ }
151
+ const current = executionJournalSchema.safeParse(raw);
152
+ if (current.success)
153
+ return { journal: current.data, migrated: false };
154
+ const legacy = legacyJournalSchema.safeParse(raw);
155
+ if (!legacy.success)
156
+ return undefined;
157
+ return {
158
+ journal: { ...legacy.data, schemaVersion: JOURNAL_SCHEMA_VERSION },
159
+ migrated: true,
160
+ };
161
+ }
162
+ function sanitizeJournal(journal) {
163
+ return {
164
+ ...journal,
165
+ ...(journal.interruptionReason === undefined
166
+ ? {}
167
+ : { interruptionReason: redactSecrets(journal.interruptionReason) }),
168
+ ...(journal.terminalResult === undefined
169
+ ? {}
170
+ : { terminalResult: { ...journal.terminalResult, summary: redactSecrets(journal.terminalResult.summary) } }),
171
+ };
172
+ }
173
+ function serializeBounded(value, maxBytes, label) {
174
+ const contents = `${JSON.stringify(value, null, 2)}\n`;
175
+ if (Buffer.byteLength(contents, "utf8") > maxBytes) {
176
+ throw new Error(`${label} exceeds its ${String(maxBytes)} byte limit.`);
177
+ }
178
+ return contents;
179
+ }
180
+ async function readOptional(filePath) {
181
+ try {
182
+ return await readFile(filePath, "utf8");
183
+ }
184
+ catch (error) {
185
+ if (isNodeError(error) && error.code === "ENOENT")
186
+ return undefined;
187
+ throw error;
188
+ }
189
+ }
190
+ async function quarantine(filePath) {
191
+ try {
192
+ await rename(filePath, `${filePath}.corrupt-${String(Date.now())}`);
193
+ }
194
+ catch (error) {
195
+ if (!isNodeError(error) || error.code !== "ENOENT")
196
+ throw error;
197
+ }
198
+ }
199
+ export function authorityFromJournal(journal) {
200
+ return journal.authority;
201
+ }
202
+ function activeRecoveryPhase(phase) {
203
+ return phase === "claimed"
204
+ || phase === "starting"
205
+ || phase === "running"
206
+ || phase === "authority_uncertain"
207
+ || phase === "recovering";
208
+ }
209
+ //# sourceMappingURL=executionJournal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executionJournal.js","sourceRoot":"","sources":["../../src/runtime/executionJournal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ import type { LocalAgentAdapter, Sleep } from "../adapters/types.js";
2
+ import type { DaemonClient, DaemonTimer } from "../daemon.js";
3
+ import type { ClaimedJob, JsonObject, LeaseRefresh, RunEventInput } from "../types.js";
4
+ import type { LocalLogSpool } from "./localLogSpool.js";
5
+ import type { RunEventRetryBuffer } from "./runEventRetryBuffer.js";
6
+ import type { DurableEventOutbox } from "./eventOutbox.js";
7
+ import type { ExecutionJournalStore } from "./executionJournal.js";
8
+ import { FencedExecutionState } from "./fencedExecutionState.js";
9
+ import type { LocalRuntimeSessionCache, LocalRuntimeSessionStatus } from "./localSessionCache.js";
10
+ export type ActiveLeaseState = {
11
+ done: boolean;
12
+ cancelRequested: boolean;
13
+ timedOut: boolean;
14
+ hardStop: boolean;
15
+ authorityUncertain: boolean;
16
+ };
17
+ export type NoProgressObserver = {
18
+ recordProgress(): void;
19
+ stop(): Promise<void>;
20
+ };
21
+ export declare const defaultDaemonTimer: DaemonTimer;
22
+ export declare function createFencedState(input: {
23
+ job: ClaimedJob;
24
+ adapter: LocalAgentAdapter | undefined;
25
+ journalStore?: ExecutionJournalStore | undefined;
26
+ eventOutbox?: DurableEventOutbox | undefined;
27
+ now: () => Date;
28
+ }): Promise<FencedExecutionState | undefined>;
29
+ export declare function emitRunEvent(input: {
30
+ client: DaemonClient;
31
+ credential: string;
32
+ job: ClaimedJob;
33
+ event: RunEventInput;
34
+ buffer?: RunEventRetryBuffer | undefined;
35
+ logSpool?: LocalLogSpool | undefined;
36
+ fencedState?: FencedExecutionState | undefined;
37
+ progressObserver?: NoProgressObserver | undefined;
38
+ }): Promise<void>;
39
+ export declare function observeRunProgress(input: {
40
+ job: ClaimedJob;
41
+ timer: DaemonTimer;
42
+ fencedState?: FencedExecutionState | undefined;
43
+ logSpool?: LocalLogSpool | undefined;
44
+ now: () => Date;
45
+ }): NoProgressObserver;
46
+ export declare function rejectExhaustedClaim(job: ClaimedJob, fencedState: FencedExecutionState | undefined): Promise<boolean>;
47
+ export declare function refreshLeaseUntilDone(input: {
48
+ client: DaemonClient;
49
+ credential: string;
50
+ jobId: string;
51
+ sleep: Sleep;
52
+ sleepSignal: AbortSignal;
53
+ adapterAbort: AbortController;
54
+ state: ActiveLeaseState;
55
+ leaseRefreshMs: number;
56
+ fencedState?: FencedExecutionState | undefined;
57
+ monotonicNowMs?: (() => number) | undefined;
58
+ random?: (() => number) | undefined;
59
+ nowMs?: (() => number) | undefined;
60
+ continueInspectOnly?: boolean | undefined;
61
+ }): Promise<void>;
62
+ export declare function renewFencedLease(input: {
63
+ client: DaemonClient;
64
+ credential: string;
65
+ jobId: string;
66
+ fencedState: FencedExecutionState;
67
+ sleep: Sleep;
68
+ signal?: AbortSignal | undefined;
69
+ nowMs?: (() => number) | undefined;
70
+ monotonicNowMs?: (() => number) | undefined;
71
+ random?: (() => number) | undefined;
72
+ }): Promise<LeaseRefresh>;
73
+ export declare function scheduleRunTimeout(job: ClaimedJob, timer: DaemonTimer, adapterAbort: AbortController, state: {
74
+ timedOut: boolean;
75
+ }, now: () => Date): unknown;
76
+ export declare function updateLocalSession(cache: LocalRuntimeSessionCache | undefined, job: ClaimedJob, status: LocalRuntimeSessionStatus, errorSummary?: JsonObject): void;