@deepthonk/core 0.1.4 → 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 (43) hide show
  1. package/README.md +26 -11
  2. package/dist/artifacts.js +178 -11
  3. package/dist/artifacts.js.map +1 -1
  4. package/dist/bradleyTerry.d.ts +1 -0
  5. package/dist/bradleyTerry.js +27 -2
  6. package/dist/bradleyTerry.js.map +1 -1
  7. package/dist/budget.d.ts +7 -1
  8. package/dist/budget.js +6 -1
  9. package/dist/budget.js.map +1 -1
  10. package/dist/budgetTracker.d.ts +6 -1
  11. package/dist/budgetTracker.js +32 -1
  12. package/dist/budgetTracker.js.map +1 -1
  13. package/dist/checkpointStore.d.ts +56 -0
  14. package/dist/checkpointStore.js +351 -0
  15. package/dist/checkpointStore.js.map +1 -0
  16. package/dist/critique.d.ts +3 -1
  17. package/dist/critique.js +24 -9
  18. package/dist/critique.js.map +1 -1
  19. package/dist/index.d.ts +2 -0
  20. package/dist/index.js +2 -0
  21. package/dist/index.js.map +1 -1
  22. package/dist/lifecycle.d.ts +33 -1
  23. package/dist/lifecycle.js +207 -6
  24. package/dist/lifecycle.js.map +1 -1
  25. package/dist/phaseRunner.d.ts +6 -1
  26. package/dist/phaseRunner.js +53 -19
  27. package/dist/phaseRunner.js.map +1 -1
  28. package/dist/resume.d.ts +10 -3
  29. package/dist/resume.js +357 -39
  30. package/dist/resume.js.map +1 -1
  31. package/dist/runner.d.ts +3 -1
  32. package/dist/runner.js +894 -246
  33. package/dist/runner.js.map +1 -1
  34. package/dist/schemas.d.ts +397 -47
  35. package/dist/schemas.js +67 -5
  36. package/dist/schemas.js.map +1 -1
  37. package/dist/services.d.ts +9 -0
  38. package/dist/services.js +115 -12
  39. package/dist/services.js.map +1 -1
  40. package/dist/traceStore.d.ts +31 -2
  41. package/dist/traceStore.js +182 -21
  42. package/dist/traceStore.js.map +1 -1
  43. package/package.json +1 -1
@@ -27,8 +27,37 @@ export interface RunStatus {
27
27
  fix?: string;
28
28
  };
29
29
  }
30
+ export interface RunLockData {
31
+ schema_version: 1;
32
+ claim_id: string;
33
+ job_id?: string;
34
+ hostname: string;
35
+ worker_pid: number;
36
+ claimed_at: string;
37
+ }
38
+ export interface RunLockClaim {
39
+ claimId: string;
40
+ fingerprint: string;
41
+ lock: RunLockData;
42
+ }
43
+ export type RunLockInspection = {
44
+ state: "missing";
45
+ } | {
46
+ state: "valid";
47
+ fingerprint: string;
48
+ lock: RunLockData;
49
+ sameHost: boolean;
50
+ workerAlive: boolean;
51
+ } | {
52
+ state: "malformed";
53
+ fingerprint: string;
54
+ };
30
55
  export declare function claimRunLock(runDir: string, jobId?: string): Promise<boolean>;
31
- export declare function releaseRunLock(runDir: string): Promise<void>;
56
+ export declare function claimRunLockOwnership(runDir: string, jobId?: string): Promise<RunLockClaim | undefined>;
57
+ export declare function inspectRunLock(runDir: string): Promise<RunLockInspection>;
58
+ export declare function reclaimRunLock(runDir: string, expectedFingerprint: string): Promise<boolean>;
59
+ export declare function verifyRunLockClaim(runDir: string, claim: RunLockClaim, jobId?: string): Promise<boolean>;
60
+ export declare function releaseRunLock(runDir: string, claimId?: string): Promise<void>;
32
61
  export declare function readRunStatus(runDir: string): Promise<RunStatus | undefined>;
33
62
  export declare function requestRunCancel(runDir: string): Promise<void>;
34
63
  export declare function isRunCancelRequested(runDir: string): Promise<boolean>;
@@ -47,6 +76,7 @@ export interface UsageDelta {
47
76
  export type CallRole = "generator" | "judge" | "mutator" | "finalizer";
48
77
  export interface UsageRecord {
49
78
  schema_version: 1;
79
+ usage_id?: string;
50
80
  ts: string;
51
81
  phase: string;
52
82
  role: CallRole;
@@ -62,4 +92,6 @@ export interface UsageRecord {
62
92
  total_usd?: number;
63
93
  latency_ms?: number;
64
94
  retry_count?: number;
95
+ outcome?: "success" | "failed";
96
+ error_code?: string;
65
97
  }
package/dist/lifecycle.js CHANGED
@@ -1,36 +1,237 @@
1
+ import { createHash, randomUUID } from "node:crypto";
1
2
  import { mkdir, readFile, unlink, writeFile } from "node:fs/promises";
3
+ import { hostname } from "node:os";
2
4
  import { join } from "node:path";
3
5
  import { runArtifactFiles } from "./artifacts.js";
4
6
  import { ConfigError } from "./errors.js";
7
+ const localClaims = new Map();
8
+ const runLockGuardFile = ".run.lock.guard";
9
+ const lockWaitTimeoutMs = 1_000;
5
10
  export async function claimRunLock(runDir, jobId) {
11
+ return Boolean(await claimRunLockOwnership(runDir, jobId));
12
+ }
13
+ export async function claimRunLockOwnership(runDir, jobId) {
6
14
  await mkdir(runDir, { recursive: true });
15
+ const path = join(runDir, runArtifactFiles.lock);
16
+ const guard = await acquireRunLockGuard(runDir);
7
17
  try {
8
- await writeFile(join(runDir, runArtifactFiles.lock), `${JSON.stringify({ job_id: jobId, worker_pid: process.pid, claimed_at: new Date().toISOString() }, null, 2)}\n`, { encoding: "utf8", flag: "wx" });
9
- return true;
18
+ const inspection = await inspectRunLock(runDir);
19
+ if (inspection.state !== "missing") {
20
+ if (inspection.state !== "valid" || !inspection.sameHost || inspection.workerAlive)
21
+ return undefined;
22
+ const current = await readFile(path, "utf8").catch(() => undefined);
23
+ if (current === undefined || lockFingerprint(current) !== inspection.fingerprint)
24
+ return undefined;
25
+ await unlink(path);
26
+ localClaims.delete(path);
27
+ }
28
+ const lock = {
29
+ schema_version: 1,
30
+ claim_id: randomUUID(),
31
+ job_id: jobId,
32
+ hostname: hostname(),
33
+ worker_pid: process.pid,
34
+ claimed_at: new Date().toISOString()
35
+ };
36
+ const raw = `${JSON.stringify(lock, null, 2)}\n`;
37
+ await writeFile(path, raw, { encoding: "utf8", flag: "wx" });
38
+ const claim = { claimId: lock.claim_id, fingerprint: lockFingerprint(raw), lock };
39
+ localClaims.set(path, claim.claimId);
40
+ return claim;
10
41
  }
11
42
  catch (error) {
12
- if (error.code === "EEXIST")
13
- return false;
43
+ if (error instanceof ConfigError)
44
+ throw error;
14
45
  throw new ConfigError(`Could not claim run directory lock: ${error.message}`, {
15
46
  code: "run.lock_failed",
16
47
  retryable: false,
17
48
  fix: "Choose a writable run directory."
18
49
  });
19
50
  }
51
+ finally {
52
+ await releaseRunLockGuard(guard);
53
+ }
54
+ }
55
+ export async function inspectRunLock(runDir) {
56
+ const path = join(runDir, runArtifactFiles.lock);
57
+ let raw;
58
+ try {
59
+ raw = await readFile(path, "utf8");
60
+ }
61
+ catch (error) {
62
+ if (error.code === "ENOENT")
63
+ return { state: "missing" };
64
+ throw new ConfigError(`Could not inspect run directory lock: ${error.message}`, {
65
+ code: "run.lock_inspect_failed",
66
+ retryable: false,
67
+ fix: "Inspect the run directory lock file and permissions."
68
+ });
69
+ }
70
+ const fingerprint = lockFingerprint(raw);
71
+ try {
72
+ const value = JSON.parse(raw);
73
+ if (value.schema_version !== 1 ||
74
+ typeof value.claim_id !== "string" ||
75
+ typeof value.hostname !== "string" ||
76
+ typeof value.worker_pid !== "number" ||
77
+ !Number.isInteger(value.worker_pid) ||
78
+ typeof value.claimed_at !== "string") {
79
+ return { state: "malformed", fingerprint };
80
+ }
81
+ const lock = value;
82
+ const sameHost = lock.hostname === hostname();
83
+ return { state: "valid", fingerprint, lock, sameHost, workerAlive: sameHost ? isLivePid(lock.worker_pid) : true };
84
+ }
85
+ catch {
86
+ return { state: "malformed", fingerprint };
87
+ }
20
88
  }
21
- export async function releaseRunLock(runDir) {
89
+ export async function reclaimRunLock(runDir, expectedFingerprint) {
90
+ const path = join(runDir, runArtifactFiles.lock);
91
+ const guard = await acquireRunLockGuard(runDir);
22
92
  try {
23
- await unlink(join(runDir, runArtifactFiles.lock));
93
+ const raw = await readFile(path, "utf8");
94
+ if (lockFingerprint(raw) !== expectedFingerprint)
95
+ return false;
96
+ await unlink(path);
97
+ localClaims.delete(path);
98
+ return true;
24
99
  }
25
100
  catch (error) {
26
101
  if (error.code === "ENOENT")
102
+ return false;
103
+ throw error;
104
+ }
105
+ finally {
106
+ await releaseRunLockGuard(guard);
107
+ }
108
+ }
109
+ export async function verifyRunLockClaim(runDir, claim, jobId) {
110
+ const path = join(runDir, runArtifactFiles.lock);
111
+ if (localClaims.get(path) !== claim.claimId)
112
+ return false;
113
+ const guard = await acquireRunLockGuard(runDir);
114
+ try {
115
+ const inspection = await inspectRunLock(runDir);
116
+ return (inspection.state === "valid" &&
117
+ inspection.fingerprint === claim.fingerprint &&
118
+ inspection.lock.claim_id === claim.claimId &&
119
+ inspection.lock.job_id === jobId);
120
+ }
121
+ finally {
122
+ await releaseRunLockGuard(guard);
123
+ }
124
+ }
125
+ export async function releaseRunLock(runDir, claimId) {
126
+ const path = join(runDir, runArtifactFiles.lock);
127
+ const expectedClaimId = claimId ?? localClaims.get(path);
128
+ const guard = await acquireRunLockGuard(runDir);
129
+ try {
130
+ const inspection = await inspectRunLock(runDir);
131
+ if (inspection.state === "missing") {
132
+ localClaims.delete(path);
27
133
  return;
134
+ }
135
+ if (inspection.state !== "valid" || !expectedClaimId || inspection.lock.claim_id !== expectedClaimId) {
136
+ throw new ConfigError("Refusing to release a run lock not owned by this claimant.", {
137
+ code: "run.lock_not_owned",
138
+ retryable: false,
139
+ fix: "Inspect the current lock and use fingerprinted reclaim only after verifying that its owner is no longer active."
140
+ });
141
+ }
142
+ await unlink(path);
143
+ localClaims.delete(path);
144
+ }
145
+ catch (error) {
146
+ if (error instanceof ConfigError)
147
+ throw error;
28
148
  throw new ConfigError(`Could not release run directory lock: ${error.message}`, {
29
149
  code: "run.lock_release_failed",
30
150
  retryable: false,
31
151
  fix: "Inspect the run directory lock file and permissions."
32
152
  });
33
153
  }
154
+ finally {
155
+ await releaseRunLockGuard(guard);
156
+ }
157
+ }
158
+ async function acquireRunLockGuard(runDir) {
159
+ await mkdir(runDir, { recursive: true });
160
+ const path = join(runDir, runLockGuardFile);
161
+ const deadline = Date.now() + lockWaitTimeoutMs;
162
+ let blockingFingerprint;
163
+ while (true) {
164
+ const owner = {
165
+ schema_version: 1,
166
+ claim_id: randomUUID(),
167
+ job_id: "run-lock-guard",
168
+ hostname: hostname(),
169
+ worker_pid: process.pid,
170
+ claimed_at: new Date().toISOString()
171
+ };
172
+ const raw = `${JSON.stringify(owner)}\n`;
173
+ try {
174
+ await writeFile(path, raw, { encoding: "utf8", flag: "wx" });
175
+ return { path, claimId: owner.claim_id, fingerprint: lockFingerprint(raw) };
176
+ }
177
+ catch (error) {
178
+ if (error.code !== "EEXIST")
179
+ throw error;
180
+ const observed = await readFile(path, "utf8").catch(() => undefined);
181
+ if (observed)
182
+ blockingFingerprint = lockFingerprint(observed);
183
+ if (Date.now() >= deadline) {
184
+ throw new ConfigError(`Timed out waiting for the run-lock guard${blockingFingerprint ? ` (${blockingFingerprint})` : ""}.`, {
185
+ code: "run.lock_guard_timeout",
186
+ retryable: true,
187
+ fix: "Retry after the active lock operation finishes. If its process crashed, inspect .run.lock.guard and remove that exact verified file manually; guards are never auto-reclaimed."
188
+ });
189
+ }
190
+ await delay(5);
191
+ }
192
+ }
193
+ }
194
+ async function releaseRunLockGuard(claim) {
195
+ const raw = await readFile(claim.path, "utf8").catch(() => undefined);
196
+ if (!raw || lockFingerprint(raw) !== claim.fingerprint || parseLockOwner(raw)?.claim_id !== claim.claimId) {
197
+ throw new ConfigError("Run-lock guard ownership changed before release.", {
198
+ code: "run.lock_guard_not_owned",
199
+ retryable: true
200
+ });
201
+ }
202
+ await unlink(claim.path);
203
+ }
204
+ function parseLockOwner(raw) {
205
+ try {
206
+ const value = JSON.parse(raw);
207
+ if (value.schema_version === 1 &&
208
+ typeof value.claim_id === "string" &&
209
+ typeof value.hostname === "string" &&
210
+ typeof value.worker_pid === "number" &&
211
+ Number.isInteger(value.worker_pid) &&
212
+ typeof value.claimed_at === "string") {
213
+ return value;
214
+ }
215
+ }
216
+ catch {
217
+ // Invalid guards are never auto-reclaimed.
218
+ }
219
+ return undefined;
220
+ }
221
+ function delay(ms) {
222
+ return new Promise((resolve) => setTimeout(resolve, ms));
223
+ }
224
+ function lockFingerprint(raw) {
225
+ return `sha256:${createHash("sha256").update(raw).digest("hex")}`;
226
+ }
227
+ function isLivePid(pid) {
228
+ try {
229
+ process.kill(pid, 0);
230
+ return true;
231
+ }
232
+ catch (error) {
233
+ return error.code !== "ESRCH";
234
+ }
34
235
  }
35
236
  export async function readRunStatus(runDir) {
36
237
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"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"}
@@ -1 +1,6 @@
1
- export declare function runLimitedPhase<T>(jobs: ReadonlyArray<() => Promise<T>>, concurrency: number): Promise<T[]>;
1
+ export type PhaseJob<T> = (signal: AbortSignal) => Promise<T>;
2
+ export interface RunLimitedPhaseOptions {
3
+ signal?: AbortSignal;
4
+ }
5
+ export declare const maxPhaseConcurrency = 1024;
6
+ export declare function runLimitedPhase<T>(jobs: Iterable<PhaseJob<T>>, concurrency: number, options?: RunLimitedPhaseOptions): Promise<T[]>;
@@ -1,26 +1,60 @@
1
- import pLimit from "p-limit";
2
- export async function runLimitedPhase(jobs, concurrency) {
3
- const limit = pLimit(concurrency);
4
- const results = new Array(jobs.length);
5
- const completed = new Array(jobs.length).fill(false);
1
+ export const maxPhaseConcurrency = 1_024;
2
+ export async function runLimitedPhase(jobs, concurrency, options = {}) {
3
+ if (!Number.isInteger(concurrency) || concurrency < 1 || concurrency > maxPhaseConcurrency) {
4
+ throw new RangeError(`Phase concurrency must be a positive integer no greater than ${maxPhaseConcurrency}, got ${concurrency}.`);
5
+ }
6
+ const iterator = jobs[Symbol.iterator]();
7
+ const results = [];
8
+ const controller = new AbortController();
9
+ let nextIndex = 0;
6
10
  let firstError;
7
- await Promise.all(jobs.map((job, index) => limit(async () => {
8
- if (firstError !== undefined)
9
- return;
10
- try {
11
- results[index] = await job();
12
- completed[index] = true;
11
+ const abort = () => {
12
+ if (firstError === undefined)
13
+ firstError = abortReason(options.signal);
14
+ if (!controller.signal.aborted)
15
+ controller.abort(firstError);
16
+ };
17
+ if (options.signal?.aborted)
18
+ abort();
19
+ else
20
+ options.signal?.addEventListener("abort", abort, { once: true });
21
+ const worker = async () => {
22
+ while (firstError === undefined) {
23
+ const next = iterator.next();
24
+ if (next.done)
25
+ return;
26
+ const index = nextIndex;
27
+ nextIndex += 1;
28
+ try {
29
+ results[index] = await next.value(controller.signal);
30
+ }
31
+ catch (error) {
32
+ if (firstError === undefined) {
33
+ firstError = error;
34
+ if (!controller.signal.aborted)
35
+ controller.abort(error);
36
+ }
37
+ return;
38
+ }
13
39
  }
14
- catch (error) {
15
- if (firstError === undefined)
16
- firstError = error;
17
- }
18
- })));
40
+ };
41
+ try {
42
+ await Promise.all(Array.from({ length: concurrency }, () => worker()));
43
+ }
44
+ finally {
45
+ options.signal?.removeEventListener("abort", abort);
46
+ if (firstError !== undefined)
47
+ iterator.return?.();
48
+ }
19
49
  if (firstError !== undefined)
20
50
  throw firstError;
21
- if (completed.some((value) => !value)) {
22
- throw new Error("Phase completed without producing every result.");
23
- }
24
51
  return results;
25
52
  }
53
+ function abortReason(signal) {
54
+ if (signal?.reason !== undefined)
55
+ return signal.reason;
56
+ const error = new Error("Phase aborted.");
57
+ error.name = "AbortError";
58
+ return error;
59
+ }
26
60
  //# sourceMappingURL=phaseRunner.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"phaseRunner.js","sourceRoot":"","sources":["../src/phaseRunner.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,SAAS,CAAC;AAE7B,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAqC,EACrC,WAAmB;IAEnB,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;IAClC,MAAM,OAAO,GAAG,IAAI,KAAK,CAAI,IAAI,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,IAAI,KAAK,CAAU,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9D,IAAI,UAAmB,CAAC;IAExB,MAAM,OAAO,CAAC,GAAG,CACf,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CACtB,KAAK,CAAC,KAAK,IAAI,EAAE;QACf,IAAI,UAAU,KAAK,SAAS;YAAE,OAAO;QACrC,IAAI,CAAC;YACH,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,GAAG,EAAE,CAAC;YAC7B,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,UAAU,KAAK,SAAS;gBAAE,UAAU,GAAG,KAAK,CAAC;QACnD,CAAC;IACH,CAAC,CAAC,CACH,CACF,CAAC;IAEF,IAAI,UAAU,KAAK,SAAS;QAAE,MAAM,UAAU,CAAC;IAC/C,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"phaseRunner.js","sourceRoot":"","sources":["../src/phaseRunner.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,CAAC;AAEzC,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAA2B,EAC3B,WAAmB,EACnB,UAAkC,EAAE;IAEpC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,WAAW,GAAG,CAAC,IAAI,WAAW,GAAG,mBAAmB,EAAE,CAAC;QAC3F,MAAM,IAAI,UAAU,CAClB,gEAAgE,mBAAmB,SAAS,WAAW,GAAG,CAC3G,CAAC;IACJ,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;IACzC,MAAM,OAAO,GAAQ,EAAE,CAAC;IACxB,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,UAAmB,CAAC;IACxB,MAAM,KAAK,GAAG,GAAS,EAAE;QACvB,IAAI,UAAU,KAAK,SAAS;YAAE,UAAU,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACvE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO;YAAE,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC/D,CAAC,CAAC;IACF,IAAI,OAAO,CAAC,MAAM,EAAE,OAAO;QAAE,KAAK,EAAE,CAAC;;QAChC,OAAO,CAAC,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAEtE,MAAM,MAAM,GAAG,KAAK,IAAmB,EAAE;QACvC,OAAO,UAAU,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC7B,IAAI,IAAI,CAAC,IAAI;gBAAE,OAAO;YACtB,MAAM,KAAK,GAAG,SAAS,CAAC;YACxB,SAAS,IAAI,CAAC,CAAC;YACf,IAAI,CAAC;gBACH,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YACvD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;oBAC7B,UAAU,GAAG,KAAK,CAAC;oBACnB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO;wBAAE,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBAC1D,CAAC;gBACD,OAAO;YACT,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACzE,CAAC;YAAS,CAAC;QACT,OAAO,CAAC,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACpD,IAAI,UAAU,KAAK,SAAS;YAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;IACpD,CAAC;IACD,IAAI,UAAU,KAAK,SAAS;QAAE,MAAM,UAAU,CAAC;IAC/C,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,WAAW,CAAC,MAA+B;IAClD,IAAI,MAAM,EAAE,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,MAAM,CAAC;IACvD,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAC1C,KAAK,CAAC,IAAI,GAAG,YAAY,CAAC;IAC1B,OAAO,KAAK,CAAC;AACf,CAAC"}
package/dist/resume.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { BudgetTracker } from "./budgetTracker.js";
2
- import type { RunStatus, UsageRecord } from "./lifecycle.js";
2
+ import { type RunStatus, type UsageRecord } from "./lifecycle.js";
3
3
  import type { BtScore, Candidate, Comparison, PhaseName, RunConfig } from "./schemas.js";
4
4
  export declare const pruneSentinelFile = ".prune-in-progress";
5
5
  export interface ResumeTrace {
@@ -41,11 +41,18 @@ export declare function resolveResumeRunId(config: RunConfig & {
41
41
  }, status: RunStatus | undefined, events: Array<Record<string, unknown>>): string;
42
42
  export declare function buildResumePlan(config: RunConfig, events: Array<Record<string, unknown>>): InternalResumePlan;
43
43
  export declare function resumeConfigError(message: string, code: string, fix?: string): never;
44
+ export declare function assertNoLegacyRedactedBudget(config: Record<string, unknown>): void;
45
+ export declare function repairLegacyBudgetConfig(runDir: string, replacements: Record<string, number>): Promise<string[]>;
44
46
  export declare function toResumePlanStatus(runDir: string, runId: string, plan: InternalResumePlan): ResumePlanStatus;
45
- export declare function pruneTraceToPlan(trace: ResumeTrace, plan: InternalResumePlan): ResumeTrace;
47
+ export declare function pruneTraceToPlan(trace: ResumeTrace, plan: InternalResumePlan, options?: {
48
+ dropUsageIds?: ReadonlySet<string>;
49
+ }): ResumeTrace;
46
50
  export declare function buildPopulationMap(config: RunConfig, populations: Map<number, Candidate[]>, candidates: Candidate[], plan: InternalResumePlan): Map<number, Candidate[]>;
47
51
  export declare function groupComparisons(comparisons: Comparison[]): Map<number | "final", Comparison[]>;
48
- export declare function reconstructScores(config: RunConfig, populationByGeneration: Map<number, Candidate[]>, comparisonsByGeneration: Map<number | "final", Comparison[]>, existingScores: BtScore[], plan: InternalResumePlan): Map<number | "final", BtScore[]>;
52
+ export declare function reconstructScores(config: RunConfig, populationByGeneration: Map<number, Candidate[]>, comparisonsByGeneration: Map<number | "final", Comparison[]>, existingScores: BtScore[], plan: InternalResumePlan, runId?: string): Map<number | "final", BtScore[]>;
49
53
  export declare function replayBudgetUsage(config: RunConfig, usage: UsageRecord[]): BudgetTracker;
54
+ export declare function applyUsageRecords(tracker: BudgetTracker, usage: UsageRecord[]): void;
55
+ export declare function validateUsageRecords(usage: UsageRecord[]): void;
56
+ export declare function validatedReceiptUsageIds(usage: unknown[]): Set<string>;
50
57
  export declare function persistPrunedTrace(runDir: string, pruned: ResumeTrace): Promise<void>;
51
58
  export declare function assertNoPruneInProgress(runDir: string): void;