@deepthonk/core 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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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"}
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,13 @@ 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
47
  export declare function pruneTraceToPlan(trace: ResumeTrace, plan: InternalResumePlan): ResumeTrace;
46
48
  export declare function buildPopulationMap(config: RunConfig, populations: Map<number, Candidate[]>, candidates: Candidate[], plan: InternalResumePlan): Map<number, Candidate[]>;
47
49
  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[]>;
50
+ 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
51
  export declare function replayBudgetUsage(config: RunConfig, usage: UsageRecord[]): BudgetTracker;
50
52
  export declare function persistPrunedTrace(runDir: string, pruned: ResumeTrace): Promise<void>;
51
53
  export declare function assertNoPruneInProgress(runDir: string): void;