@sensigo/realm 0.23.0 → 0.25.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.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,cAAc,uBAAuB,CAAC;AACtC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,OAAO,EAAE,8BAA8B,EAAE,MAAM,8BAA8B,CAAC;AAC9E,cAAc,gCAAgC,CAAC;AAC/C,cAAc,4BAA4B,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAI3D,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EACL,cAAc,EACd,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,wBAAwB,EACxB,yBAAyB,EACzB,2BAA2B,GAC5B,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAExE,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EACL,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,0CAA0C,CAAC;AAMlD,OAAO,EACL,kBAAkB,EAClB,gCAAgC,GACjC,MAAM,iCAAiC,CAAC;AAGzC,OAAO,EACL,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,EAChB,8BAA8B,GAC/B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,mBAAmB,EACnB,cAAc,GACf,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,eAAe,EACf,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,eAAe,GAChB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,oBAAoB,EACpB,aAAa,EACb,wBAAwB,EACxB,SAAS,EACT,4BAA4B,EAC5B,iCAAiC,EACjC,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAEvD,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,0BAA0B,EAC1B,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,0BAA0B,CAAC;AAGlC,MAAM,CAAC,MAAM,OAAO,GAAG,QAAQ,CAAC;AAYhC,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAEzE,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,+BAA+B,GAChC,MAAM,mCAAmC,CAAC;AAS3C,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,uBAAuB,EACvB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,2BAA2B,CAAC;AAQnC,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAEzE,WAAW;AACX,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,WAAW;AACX,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAE7D,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAE3D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAE/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mCAAmC,CAAC;AAMvE,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAEjE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAG7D,eAAe;AACf,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAGjG,aAAa;AACb,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAEnE,WAAW;AACX,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,mCAAmC,EACnC,qCAAqC,EACrC,aAAa,EACb,+BAA+B,GAChC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAG5D,+DAA+D;AAC/D,OAAO,EACL,cAAc,EACd,eAAe,EACf,eAAe,EACf,mBAAmB,GACpB,MAAM,2BAA2B,CAAC;AAGnC,qBAAqB;AACrB,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAC5E,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAC;AAChE,OAAO,EAAE,oBAAoB,EAAE,MAAM,iDAAiD,CAAC;AACvF,OAAO,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,0CAA0C,CAAC;AAI1E,OAAO,EACL,wBAAwB,EACxB,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,+BAA+B,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import type { FailedAttemptRecord } from '../observability/failed-attempt-record.js';
2
2
  import type { PerRunArtifactStore } from './per-run-artifact-store.js';
3
+ import type { OrphanSweepableStore, OrphanArtifact } from './orphan-sweepable-store.js';
3
4
  /**
4
5
  * Append-and-stop byte ceiling per sidecar (~80+ full ≤3072B records — ample forensics). Approximate
5
6
  * under concurrency: bounded overshoot ≈ concurrent-writers × max-record. Kept lock-free deliberately.
@@ -17,7 +18,7 @@ export interface FailedAttemptReadResult {
17
18
  * atomic and interleave-safe across concurrent processes (the size bound is what buys lock-freedom —
18
19
  * the deliberate difference from the WAL store).
19
20
  */
20
- export declare class FailedAttemptStore implements PerRunArtifactStore {
21
+ export declare class FailedAttemptStore implements PerRunArtifactStore, OrphanSweepableStore {
21
22
  private readonly runsDir;
22
23
  constructor(runsDir: string);
23
24
  /** Sidecar path — derived ONLY from the (server-generated UUID) runId. `.jsonl` is mandatory. */
@@ -40,5 +41,15 @@ export declare class FailedAttemptStore implements PerRunArtifactStore {
40
41
  * double-invocation already removed it) is a no-op, never an error.
41
42
  */
42
43
  deleteAllForRun(runId: string, _dirEntries?: readonly string[]): Promise<void>;
44
+ /**
45
+ * Returns every `.attempts.jsonl` sidecar whose runId is NOT in `liveRunIds` (issue #163) —
46
+ * candidate orphans for `realm run gc`'s remediation sweep. Does not apply an age floor or
47
+ * delete anything — see `OrphanSweepableStore`'s own doc for why that's the caller's job.
48
+ *
49
+ * FAIL-CLOSED: `ENOENT` on `runsDir` itself → `[]` (nothing has ever been created here). Any
50
+ * OTHER `readdir` or `stat` error THROWS — never fabricate an empty/partial list, which would
51
+ * make a live run's sidecar look orphaned.
52
+ */
53
+ listOrphans(liveRunIds: ReadonlySet<string>): Promise<OrphanArtifact[]>;
43
54
  }
44
55
  //# sourceMappingURL=failed-attempt-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"failed-attempt-store.d.ts","sourceRoot":"","sources":["../../src/store/failed-attempt-store.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAC;AACrF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAEvE;;;GAGG;AACH,eAAO,MAAM,gCAAgC,QAAa,CAAC;AAE3D,MAAM,WAAW,uBAAuB;IACtC,2EAA2E;IAC3E,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,sGAAsG;IACtG,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;;GAKG;AACH,qBAAa,kBAAmB,YAAW,mBAAmB;IAC5D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,OAAO,EAAE,MAAM;IAI3B,iGAAiG;IACjG,OAAO,CAAC,WAAW;IAInB;;;;OAIG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBxD;;;OAGG;IACG,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAgC3D;;;;;OAKG;IACG,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAGrF"}
1
+ {"version":3,"file":"failed-attempt-store.d.ts","sourceRoot":"","sources":["../../src/store/failed-attempt-store.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2CAA2C,CAAC;AACrF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,KAAK,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAcxF;;;GAGG;AACH,eAAO,MAAM,gCAAgC,QAAa,CAAC;AAE3D,MAAM,WAAW,uBAAuB;IACtC,2EAA2E;IAC3E,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,sGAAsG;IACtG,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;;GAKG;AACH,qBAAa,kBAAmB,YAAW,mBAAmB,EAAE,oBAAoB;IAClF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,OAAO,EAAE,MAAM;IAI3B,iGAAiG;IACjG,OAAO,CAAC,WAAW;IAInB;;;;OAIG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBxD;;;OAGG;IACG,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC;IA8B3D;;;;;OAKG;IACG,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IASpF;;;;;;;;OAQG;IACG,WAAW,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;CAyB9E"}
@@ -11,9 +11,14 @@
11
11
  // the keys/ subdir).
12
12
  // - The path is derived ONLY from the server-generated UUIDv4 runId (`[0-9a-f-]`), never from
13
13
  // caller-supplied input — a path-safety invariant.
14
- import { existsSync } from 'node:fs';
15
- import { appendFile, readFile, stat, unlink } from 'node:fs/promises';
14
+ import { appendFile, stat, readdir } from 'node:fs/promises';
16
15
  import { join } from 'node:path';
16
+ import { readIfExists, deleteIfExists, statIfExists, toArtifactDeleteFailedError, } from './fs-io.js';
17
+ /** The sidecar filename suffix — everything before it (the runId) is derived ONLY from the
18
+ * server-generated UUIDv4 runId, so stripping it back off is unambiguous (no delimiter
19
+ * ambiguity the way the WAL filename has, since there is no second segment after the runId
20
+ * here — see JsonTraceBufferStore.listOrphans for the trickier case). */
21
+ const SIDECAR_SUFFIX = '.attempts.jsonl';
17
22
  /**
18
23
  * Append-and-stop byte ceiling per sidecar (~80+ full ≤3072B records — ample forensics). Approximate
19
24
  * under concurrency: bounded overshoot ≈ concurrent-writers × max-record. Kept lock-free deliberately.
@@ -65,7 +70,12 @@ export class FailedAttemptStore {
65
70
  */
66
71
  async read(runId) {
67
72
  const path = this.sidecarPath(runId);
68
- if (!existsSync(path))
73
+ // issue #183: readIfExists distinguishes absence (undefined → empty result, the pre-existing
74
+ // behavior) from a genuine I/O failure (now propagates, rather than being silently swallowed
75
+ // into the same empty result an absent file produces — that conflation is exactly what let a
76
+ // real read failure masquerade as "no failed attempts recorded").
77
+ const content = await readIfExists(path);
78
+ if (content === undefined)
69
79
  return { records: [], capped: false };
70
80
  let capped = false;
71
81
  try {
@@ -75,13 +85,6 @@ export class FailedAttemptStore {
75
85
  catch {
76
86
  // ignore — capped stays false
77
87
  }
78
- let content;
79
- try {
80
- content = await readFile(path, 'utf8');
81
- }
82
- catch {
83
- return { records: [], capped };
84
- }
85
88
  const records = [];
86
89
  for (const raw of content.split('\n')) {
87
90
  const trimmed = raw.trim();
@@ -103,7 +106,50 @@ export class FailedAttemptStore {
103
106
  * double-invocation already removed it) is a no-op, never an error.
104
107
  */
105
108
  async deleteAllForRun(runId, _dirEntries) {
106
- await unlink(this.sidecarPath(runId)).catch(() => { });
109
+ const path = this.sidecarPath(runId);
110
+ try {
111
+ await deleteIfExists(path);
112
+ }
113
+ catch (err) {
114
+ throw toArtifactDeleteFailedError(runId, 'FailedAttemptStore', [], path, err);
115
+ }
116
+ }
117
+ /**
118
+ * Returns every `.attempts.jsonl` sidecar whose runId is NOT in `liveRunIds` (issue #163) —
119
+ * candidate orphans for `realm run gc`'s remediation sweep. Does not apply an age floor or
120
+ * delete anything — see `OrphanSweepableStore`'s own doc for why that's the caller's job.
121
+ *
122
+ * FAIL-CLOSED: `ENOENT` on `runsDir` itself → `[]` (nothing has ever been created here). Any
123
+ * OTHER `readdir` or `stat` error THROWS — never fabricate an empty/partial list, which would
124
+ * make a live run's sidecar look orphaned.
125
+ */
126
+ async listOrphans(liveRunIds) {
127
+ let entries;
128
+ try {
129
+ entries = await readdir(this.runsDir);
130
+ }
131
+ catch (err) {
132
+ if (err.code === 'ENOENT')
133
+ return [];
134
+ throw err;
135
+ }
136
+ const orphans = [];
137
+ for (const name of entries) {
138
+ if (!name.endsWith(SIDECAR_SUFFIX))
139
+ continue;
140
+ const runId = name.slice(0, -SIDECAR_SUFFIX.length);
141
+ if (liveRunIds.has(runId))
142
+ continue;
143
+ const path = join(this.runsDir, name);
144
+ // #183 discipline: statIfExists returns undefined only on ENOENT (a benign vanished-
145
+ // between-readdir-and-stat race — skip it); any other errno throws, aborting the WHOLE
146
+ // sweep (fail-closed) rather than silently omitting this one artifact.
147
+ const info = await statIfExists(path);
148
+ if (info === undefined)
149
+ continue;
150
+ orphans.push({ path, runId, mtimeMs: info.mtimeMs });
151
+ }
152
+ return orphans;
107
153
  }
108
154
  }
109
155
  //# sourceMappingURL=failed-attempt-store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"failed-attempt-store.js","sourceRoot":"","sources":["../../src/store/failed-attempt-store.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"failed-attempt-store.js","sourceRoot":"","sources":["../../src/store/failed-attempt-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,65 @@
1
+ import type { Stats } from 'node:fs';
2
+ import { WorkflowError } from '../types/workflow-error.js';
3
+ /**
4
+ * Thrown by the fs-io primitives for any non-ENOENT errno. Callers map this to a typed,
5
+ * domain-specific `WorkflowError` (e.g. `ENGINE_ARTIFACT_DELETE_FAILED` via
6
+ * {@link toArtifactDeleteFailedError} below) at the aggregate layer — this class exists only to
7
+ * carry the raw path + errno + cause across that boundary without losing information.
8
+ */
9
+ export declare class FsIoError extends Error {
10
+ readonly path: string;
11
+ readonly code: string;
12
+ constructor(op: string, path: string, cause: unknown);
13
+ }
14
+ /**
15
+ * Exported ONLY so the retry policy itself can be unit-tested directly with an injected fake
16
+ * `op` (mocking `node:fs/promises`'s real `unlink`/`readFile`/`stat` under Vitest+ESM is brittle —
17
+ * "Cannot spy on export ... Module namespace is not configurable in ESM" — so the policy is
18
+ * decoupled from any specific fs call and tested in isolation instead). Not part of the module's
19
+ * intended per-call public surface (`deleteIfExists`/`readIfExists`/`statIfExists` are).
20
+ */
21
+ export declare function withWin32Retry<T>(op: () => Promise<T>): Promise<T>;
22
+ /**
23
+ * Deletes `path`. ENOENT → `false` (already gone — success, idempotent). Any other errno → throws
24
+ * {@link FsIoError}. Returns `true` if this call actually deleted the file.
25
+ */
26
+ export declare function deleteIfExists(path: string): Promise<boolean>;
27
+ /**
28
+ * Reads `path` as utf8. ENOENT → `undefined` (absent). Any other errno → throws {@link FsIoError}.
29
+ * Parsing is the CALLER's job — this returns raw bytes only.
30
+ */
31
+ export declare function readIfExists(path: string): Promise<string | undefined>;
32
+ /**
33
+ * Stats `path`. ENOENT → `undefined` (absent). Any other errno → throws {@link FsIoError}.
34
+ */
35
+ export declare function statIfExists(path: string): Promise<Stats | undefined>;
36
+ /**
37
+ * Retryable classification for the `ENGINE_ARTIFACT_DELETE_FAILED` aggregate error (issue #183):
38
+ * `EACCES`/`EISDIR`/`EPERM`/`EROFS` are permanent (retrying won't help — same permission/mount
39
+ * state); `EBUSY`/`EIO` are transient (a lock held elsewhere, a flaky disk read) — worth
40
+ * retrying. Any other or unknown errno defaults to `false` — conservative, since advertising a
41
+ * retry that might not help is worse than not advertising one that would have.
42
+ */
43
+ export declare function isRetryableArtifactErrno(code: string): boolean;
44
+ /** One artifact this store failed to delete, at the aggregate layer. */
45
+ export interface ArtifactDeleteFailure {
46
+ artifact: string;
47
+ code: string;
48
+ message: string;
49
+ }
50
+ /**
51
+ * Builds the aggregate `ENGINE_ARTIFACT_DELETE_FAILED` `WorkflowError` every
52
+ * `PerRunArtifactStore.deleteAllForRun` implementation throws on a genuine (non-ENOENT) failure —
53
+ * the single typed shape `purge` (and any other caller) can rely on regardless of which store, or
54
+ * which internal read/delete step, actually failed. `retryable` is true iff ANY listed failure is
55
+ * itself retryable (a partial success followed by one transient failure is worth retrying as a
56
+ * whole).
57
+ */
58
+ export declare function artifactDeleteFailedError(runId: string, store: string, deleted: string[], failures: ArtifactDeleteFailure[]): WorkflowError;
59
+ /**
60
+ * Convenience for the common single-failure case: extracts the errno (from an {@link FsIoError}
61
+ * or a raw `NodeJS.ErrnoException`) and message from `err`, then wraps it via
62
+ * {@link artifactDeleteFailedError}.
63
+ */
64
+ export declare function toArtifactDeleteFailedError(runId: string, store: string, deleted: string[], artifact: string, err: unknown): WorkflowError;
65
+ //# sourceMappingURL=fs-io.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-io.d.ts","sourceRoot":"","sources":["../../src/store/fs-io.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAkB3D;;;;;GAKG;AACH,qBAAa,SAAU,SAAQ,KAAK;IAClC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAEV,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CASrD;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAgBxE;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQnE;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAO5E;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC,CAO3E;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE9D;AAED,wEAAwE;AACxE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACvC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EAAE,EACjB,QAAQ,EAAE,qBAAqB,EAAE,GAChC,aAAa,CASf;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EAAE,EACjB,QAAQ,EAAE,MAAM,EAChB,GAAG,EAAE,OAAO,GACX,aAAa,CAIf"}
@@ -0,0 +1,159 @@
1
+ // fs-io.ts — the ENOENT-discriminating filesystem primitive (issue #183).
2
+ //
3
+ // Every store I/O site must distinguish three outcomes, never conflate them:
4
+ // 1. ENOENT → absence → success (idempotent: a delete of a missing file succeeds; a read of a
5
+ // missing file returns "absent").
6
+ // 2. Any OTHER errno (EACCES/EPERM/EIO/EROFS/EBUSY/EISDIR/ENOTDIR/…) → THROW a typed error.
7
+ // ENOTDIR is corruption, not absence — it must be loud.
8
+ // 3. Parse/JSON corruption → RECOVER (per-line skip / self-heal) + a loud structured warning.
9
+ // Never silence, never throw. This is the CALLER's job — these primitives return raw
10
+ // bytes/booleans/stats only, never parse.
11
+ //
12
+ // A `process.platform === 'win32'`-gated bounded retry absorbs transient EBUSY/EPERM/ENOTEMPTY —
13
+ // the same shape Node's own `fs.rm` uses (`maxRetries`/`retryDelay`) — because Windows
14
+ // file-locking (an antivirus scan, an open handle from another process) can make a delete/read
15
+ // transiently fail where POSIX would succeed immediately. No retry/delay on POSIX: a genuine
16
+ // EACCES there is not transient, and retrying would only slow down a real permission failure.
17
+ import { unlink, readFile, stat } from 'node:fs/promises';
18
+ import { WorkflowError } from '../types/workflow-error.js';
19
+ const WIN32_RETRY_COUNT = 3;
20
+ const WIN32_RETRY_DELAY_MS = 50;
21
+ const WIN32_RETRYABLE_CODES = new Set(['EBUSY', 'EPERM', 'ENOTEMPTY']);
22
+ /** Errno classified as transient (worth retrying) for the ENGINE_ARTIFACT_DELETE_FAILED
23
+ * aggregate's `retryable` field — a lock held elsewhere, a flaky disk read. */
24
+ const RETRYABLE_ARTIFACT_ERRNO = new Set(['EBUSY', 'EIO']);
25
+ /** Errno classified as permanent (retrying will not help — same permission/mount state). Listed
26
+ * explicitly (rather than "everything else") so the default for an unrecognized/unknown errno
27
+ * stays the conservative `false` — never advertise a retry that might not help. */
28
+ const NON_RETRYABLE_ARTIFACT_ERRNO = new Set(['EACCES', 'EISDIR', 'EPERM', 'EROFS']);
29
+ function errnoCode(err) {
30
+ return err?.code;
31
+ }
32
+ /**
33
+ * Thrown by the fs-io primitives for any non-ENOENT errno. Callers map this to a typed,
34
+ * domain-specific `WorkflowError` (e.g. `ENGINE_ARTIFACT_DELETE_FAILED` via
35
+ * {@link toArtifactDeleteFailedError} below) at the aggregate layer — this class exists only to
36
+ * carry the raw path + errno + cause across that boundary without losing information.
37
+ */
38
+ export class FsIoError extends Error {
39
+ path;
40
+ code;
41
+ constructor(op, path, cause) {
42
+ const code = errnoCode(cause) ?? 'UNKNOWN';
43
+ const causeMessage = cause instanceof Error ? cause.message : String(cause);
44
+ super(`${op} failed for '${path}' (${code}): ${causeMessage}`);
45
+ this.name = 'FsIoError';
46
+ this.path = path;
47
+ this.code = code;
48
+ if (cause instanceof Error)
49
+ this.cause = cause;
50
+ }
51
+ }
52
+ /**
53
+ * Exported ONLY so the retry policy itself can be unit-tested directly with an injected fake
54
+ * `op` (mocking `node:fs/promises`'s real `unlink`/`readFile`/`stat` under Vitest+ESM is brittle —
55
+ * "Cannot spy on export ... Module namespace is not configurable in ESM" — so the policy is
56
+ * decoupled from any specific fs call and tested in isolation instead). Not part of the module's
57
+ * intended per-call public surface (`deleteIfExists`/`readIfExists`/`statIfExists` are).
58
+ */
59
+ export async function withWin32Retry(op) {
60
+ if (process.platform !== 'win32')
61
+ return op();
62
+ let lastErr;
63
+ for (let attempt = 0; attempt <= WIN32_RETRY_COUNT; attempt++) {
64
+ try {
65
+ return await op();
66
+ }
67
+ catch (err) {
68
+ lastErr = err;
69
+ const code = errnoCode(err);
70
+ if (code === undefined || !WIN32_RETRYABLE_CODES.has(code))
71
+ throw err;
72
+ if (attempt < WIN32_RETRY_COUNT) {
73
+ await new Promise((resolve) => setTimeout(resolve, WIN32_RETRY_DELAY_MS));
74
+ }
75
+ }
76
+ }
77
+ throw lastErr;
78
+ }
79
+ /**
80
+ * Deletes `path`. ENOENT → `false` (already gone — success, idempotent). Any other errno → throws
81
+ * {@link FsIoError}. Returns `true` if this call actually deleted the file.
82
+ */
83
+ export async function deleteIfExists(path) {
84
+ try {
85
+ await withWin32Retry(() => unlink(path));
86
+ return true;
87
+ }
88
+ catch (err) {
89
+ if (errnoCode(err) === 'ENOENT')
90
+ return false;
91
+ throw new FsIoError('unlink', path, err);
92
+ }
93
+ }
94
+ /**
95
+ * Reads `path` as utf8. ENOENT → `undefined` (absent). Any other errno → throws {@link FsIoError}.
96
+ * Parsing is the CALLER's job — this returns raw bytes only.
97
+ */
98
+ export async function readIfExists(path) {
99
+ try {
100
+ return await withWin32Retry(() => readFile(path, 'utf8'));
101
+ }
102
+ catch (err) {
103
+ if (errnoCode(err) === 'ENOENT')
104
+ return undefined;
105
+ throw new FsIoError('readFile', path, err);
106
+ }
107
+ }
108
+ /**
109
+ * Stats `path`. ENOENT → `undefined` (absent). Any other errno → throws {@link FsIoError}.
110
+ */
111
+ export async function statIfExists(path) {
112
+ try {
113
+ return await withWin32Retry(() => stat(path));
114
+ }
115
+ catch (err) {
116
+ if (errnoCode(err) === 'ENOENT')
117
+ return undefined;
118
+ throw new FsIoError('stat', path, err);
119
+ }
120
+ }
121
+ /**
122
+ * Retryable classification for the `ENGINE_ARTIFACT_DELETE_FAILED` aggregate error (issue #183):
123
+ * `EACCES`/`EISDIR`/`EPERM`/`EROFS` are permanent (retrying won't help — same permission/mount
124
+ * state); `EBUSY`/`EIO` are transient (a lock held elsewhere, a flaky disk read) — worth
125
+ * retrying. Any other or unknown errno defaults to `false` — conservative, since advertising a
126
+ * retry that might not help is worse than not advertising one that would have.
127
+ */
128
+ export function isRetryableArtifactErrno(code) {
129
+ return RETRYABLE_ARTIFACT_ERRNO.has(code) && !NON_RETRYABLE_ARTIFACT_ERRNO.has(code);
130
+ }
131
+ /**
132
+ * Builds the aggregate `ENGINE_ARTIFACT_DELETE_FAILED` `WorkflowError` every
133
+ * `PerRunArtifactStore.deleteAllForRun` implementation throws on a genuine (non-ENOENT) failure —
134
+ * the single typed shape `purge` (and any other caller) can rely on regardless of which store, or
135
+ * which internal read/delete step, actually failed. `retryable` is true iff ANY listed failure is
136
+ * itself retryable (a partial success followed by one transient failure is worth retrying as a
137
+ * whole).
138
+ */
139
+ export function artifactDeleteFailedError(runId, store, deleted, failures) {
140
+ const summary = failures.map((f) => `${f.artifact} (${f.code})`).join(', ');
141
+ return new WorkflowError(`${store} failed to delete artifact(s) for run '${runId}': ${summary}`, {
142
+ code: 'ENGINE_ARTIFACT_DELETE_FAILED',
143
+ category: 'ENGINE',
144
+ agentAction: 'report_to_user',
145
+ retryable: failures.some((f) => isRetryableArtifactErrno(f.code)),
146
+ details: { runId, store, deleted, failures },
147
+ });
148
+ }
149
+ /**
150
+ * Convenience for the common single-failure case: extracts the errno (from an {@link FsIoError}
151
+ * or a raw `NodeJS.ErrnoException`) and message from `err`, then wraps it via
152
+ * {@link artifactDeleteFailedError}.
153
+ */
154
+ export function toArtifactDeleteFailedError(runId, store, deleted, artifact, err) {
155
+ const code = err instanceof FsIoError ? err.code : (errnoCode(err) ?? 'UNKNOWN');
156
+ const message = err instanceof Error ? err.message : String(err);
157
+ return artifactDeleteFailedError(runId, store, deleted, [{ artifact, code, message }]);
158
+ }
159
+ //# sourceMappingURL=fs-io.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs-io.js","sourceRoot":"","sources":["../../src/store/fs-io.ts"],"names":[],"mappings":"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"}
@@ -27,6 +27,17 @@ export interface ReconcileSummary {
27
27
  extra_live_run_ids: string[];
28
28
  }>;
29
29
  }
30
+ /**
31
+ * GLOBAL LOCK ORDER (issue #184): run-file lock BEFORE key lock, never the reverse.
32
+ * `deleteAllForRun` is the only site that nests them (run-file lock held, key lock acquired
33
+ * inside it, key lock released, then the run file is deleted and the run-file lock released).
34
+ * Every other method that touches both takes them SEQUENTIALLY, never nested: `save()` releases
35
+ * its run-file lock before `registerImportedKey()` acquires the key lock; `create()` only ever
36
+ * takes the key lock (the run file it writes under that lock is a fresh path, not yet lockable
37
+ * meaningfully — no run-file lock is held during `create()`). Violating this order (acquiring a
38
+ * key lock and THEN a run-file lock while still holding the key lock) is the classic two-lock
39
+ * deadlock shape and must never be introduced.
40
+ */
30
41
  export declare class JsonFileStore implements RunStore, PerRunArtifactStore {
31
42
  private readonly runsDir;
32
43
  /** This store round-trips the per-claim `claims` liveness clock (issue #101). */
@@ -41,7 +52,14 @@ export declare class JsonFileStore implements RunStore, PerRunArtifactStore {
41
52
  private keyPath;
42
53
  private ensureDir;
43
54
  private ensureKeysDir;
44
- /** Read a pointer file; returns undefined if absent or unparseable (self-heals via reclaim/fallback). */
55
+ /**
56
+ * Read a pointer file. Absence (ENOENT) → undefined. A genuine I/O failure (permissions, a
57
+ * torn mount, …) THROWS — issue #183: previously any error here, I/O or parse alike, silently
58
+ * self-healed to "absent," which let a real read failure masquerade as a missing pointer. Parse
59
+ * corruption (a torn/garbage pointer file) still self-heals to undefined — `create()` and
60
+ * `reconcileKeys()` both depend on that recovery — but is no longer SILENT: a loud, structured
61
+ * warning is emitted so an operator/log consumer can see the corruption happened.
62
+ */
45
63
  private readPointer;
46
64
  /** Write (or overwrite) a pointer file for `run` under `key`. params_hash is derived from the owned run. */
47
65
  private writePointer;
@@ -88,6 +106,34 @@ export declare class JsonFileStore implements RunStore, PerRunArtifactStore {
88
106
  */
89
107
  reconcileKeys(workflowId?: string, dryRun?: boolean): Promise<ReconcileSummary>;
90
108
  list(workflowId?: string): Promise<RunRecord[]>;
109
+ /**
110
+ * The raw set of run IDs present in `runsDir` (issue #163) — every `<id>.json` BASENAME, with
111
+ * NO record parse. Deliberately NOT `list()`: `list()` parses each file as a `RunRecord`
112
+ * (`JSON.parse(raw) as RunRecord`, uncaught) — a syntactically corrupt-but-PRESENT `<id>.json`
113
+ * would throw there, whereas here it correctly still counts as a live run (the file exists on
114
+ * disk; whatever reads it later is a separate concern from whether `realm run gc`'s orphan
115
+ * sweep should treat this run's WAL/sidecar as run-less). Using `list()` for the orphan sweep's
116
+ * `liveRunIds` would wrongly orphan — and reap — a live-but-corrupt run's artifacts.
117
+ *
118
+ * Concrete method, NOT on the `RunStore` interface (issue #163) — `gc` constructs a concrete
119
+ * `JsonFileStore` directly (as it already does for `runsDirPath`), so no external `RunStore`
120
+ * implementer is forced to add this.
121
+ *
122
+ * FAIL-CLOSED, load-bearing: `ENOENT` (no `runsDir` at all — nothing has ever been created) is
123
+ * the ONLY tolerated case, yielding an empty set (no runs exist, so nothing is "wrongly" live or
124
+ * orphaned). Any OTHER `readdir` error (permissions, a torn mount) THROWS — a fabricated empty
125
+ * set here would make the orphan sweep believe NO runs exist, and reap every live run's
126
+ * artifacts as "run-less." This is the single most dangerous failure mode in the whole feature;
127
+ * see `orphan-sweepable-store.ts`'s own doc for the matching contract on the artifact-store side.
128
+ */
129
+ listRunIds(): Promise<ReadonlySet<string>>;
130
+ /**
131
+ * Builds the `STATE_RUN_BUSY` error thrown when `deleteAllForRun` cannot proceed because
132
+ * another writer holds the run-file (or key) lock, or because the run is no longer terminal
133
+ * (issue #184). Retryable: a live writer self-heals (the lock is released), and a genuinely
134
+ * stale lock is eventually stolen by the next contender.
135
+ */
136
+ private runBusyError;
91
137
  /**
92
138
  * Deletes every artifact this store owns for `runId` (issue #107): the idempotency-key
93
139
  * pointer (conditionally) and the run file itself. Exact-path — ignores `dirEntries` (this
@@ -95,6 +141,15 @@ export declare class JsonFileStore implements RunStore, PerRunArtifactStore {
95
141
  *
96
142
  * Idempotent: if the run file is already gone (a concurrent purge, or a double-invocation),
97
143
  * this is a no-op, not an error.
144
+ *
145
+ * issue #184 — the resurrect-race fix: the WHOLE body runs under the run-file lock (matching
146
+ * `update()`/`claimStep()`), and the run's terminal state is RE-VERIFIED under that lock, not
147
+ * just at selection time. `RESUMABLE_PHASES ⊂ TERMINAL_PHASES` and `resume.ts` sets
148
+ * `terminal_state: false`, and `atomicWriteFile` (a temp write + `rename`) recreates a
149
+ * deleted target on `rename` — so, unlocked, a concurrent `realm resume` racing a batch purge
150
+ * could resurrect the run file as a LIVE run with its WAL/sidecar/pointer already gone, while
151
+ * purge still reported `purged`. Re-checking terminal state under the SAME lock `update()`
152
+ * uses closes that window: `deleteAllForRun` now unconditionally refuses a non-terminal run.
98
153
  */
99
154
  deleteAllForRun(runId: string, _dirEntries?: readonly string[]): Promise<void>;
100
155
  }
@@ -1 +1 @@
1
- {"version":3,"file":"json-file-store.d.ts","sourceRoot":"","sources":["../../src/store/json-file-store.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAE1E,OAAO,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAyBvE,+DAA+D;AAC/D,MAAM,WAAW,gBAAgB;IAC/B,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAC;IACpB,wEAAwE;IACxE,aAAa,EAAE,MAAM,CAAC;IACtB,uCAAuC;IACvC,MAAM,EAAE,OAAO,CAAC;IAChB,8DAA8D;IAC9D,eAAe,EAAE,KAAK,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;QACpB,GAAG,EAAE,MAAM,CAAC;QACZ,gBAAgB,EAAE,MAAM,CAAC;QACzB,aAAa,EAAE,MAAM,EAAE,CAAC;KACzB,CAAC,CAAC;IACH,mFAAmF;IACnF,kBAAkB,EAAE,KAAK,CAAC;QACxB,WAAW,EAAE,MAAM,CAAC;QACpB,GAAG,EAAE,MAAM,CAAC;QACZ,gBAAgB,EAAE,MAAM,CAAC;QACzB,kBAAkB,EAAE,MAAM,EAAE,CAAC;KAC9B,CAAC,CAAC;CACJ;AA2BD,qBAAa,aAAc,YAAW,QAAQ,EAAE,mBAAmB;IACjE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC,iFAAiF;IACjF,QAAQ,CAAC,cAAc,QAAQ;gBAEnB,OAAO,CAAC,EAAE,MAAM;IAI5B,qDAAqD;IACrD,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,OAAO,CAAC,QAAQ;IAIhB,sGAAsG;IACtG,OAAO,CAAC,OAAO;IAIf,wDAAwD;IACxD,OAAO,CAAC,OAAO;YAKD,SAAS;YAIT,aAAa;IAI3B,yGAAyG;YAC3F,WAAW;IASzB,4GAA4G;YAC9F,YAAY;IAW1B,6EAA6E;YAC/D,aAAa;IAwB3B,wGAAwG;YAC1F,sBAAsB;IAS9B,MAAM,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC;QAAE,GAAG,EAAE,SAAS,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IA6DtF;;;;;OAKG;YACW,SAAS;IAUvB,2GAA2G;IAC3G,OAAO,CAAC,gBAAgB;IAUlB,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAoCtC,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IAuD7C,SAAS,CACb,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,kBAAkB,GAC7B,OAAO,CAAC,SAAS,CAAC;IA0ErB;;;;;;;OAOG;IAIG,IAAI,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAyC5C;;;;OAIG;YACW,mBAAmB;IA8BjC;;;;;OAKG;IACG,aAAa,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA4D7E,IAAI,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAiCrD;;;;;;;OAOG;IACG,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CA2BrF"}
1
+ {"version":3,"file":"json-file-store.d.ts","sourceRoot":"","sources":["../../src/store/json-file-store.ts"],"names":[],"mappings":"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"}