@sentropic/track 0.2.1 → 0.2.2
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/events/lock.d.ts +42 -0
- package/dist/events/lock.d.ts.map +1 -0
- package/dist/events/lock.js +91 -0
- package/dist/events/lock.js.map +1 -0
- package/dist/events/store.d.ts.map +1 -1
- package/dist/events/store.js +47 -41
- package/dist/events/store.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-process write serialization for the single-stream event log.
|
|
3
|
+
*
|
|
4
|
+
* `EventStore.appendCommand` runs read → validate → compute (prevHash/seq) → append → writeHead as a
|
|
5
|
+
* critical section with NO mutual exclusion. Two writers on the same `events.jsonl` (a CLI run while an
|
|
6
|
+
* MCP server is live, two `track-mcp` instances, an h2a sidecar) both read the same N-event prefix,
|
|
7
|
+
* compute the SAME `prevHash`/`seq`, and append — producing a broken `prevHash` chain + duplicate `seq`
|
|
8
|
+
* + a stale `head.json`. The fail-closed guard then refuses EVERY future append (a permanent, human-only
|
|
9
|
+
* repair): an integrity-DoS triggerable by any concurrent writer. `withFileLock` serializes that section
|
|
10
|
+
* across processes so the single-writer contract holds in practice, not just in intent.
|
|
11
|
+
*
|
|
12
|
+
* DELIBERATELY NO automatic stale-lock stealing (review verdict, Lot v2.3b-0): pathname-based stealing
|
|
13
|
+
* is intrinsically racy — two waiters can both judge a lock abandoned, the slower `unlink` then deletes
|
|
14
|
+
* the WINNER's fresh lock and mutual exclusion is broken; and an age-based steal can preempt a merely
|
|
15
|
+
* SLOW live holder (large log, slow disk, SIGSTOP/suspend), putting two writers in the critical section.
|
|
16
|
+
* Both failure modes recreate the exact corruption this lock exists to prevent. Posture instead:
|
|
17
|
+
* fail-closed with a DIAGNOSED timeout — the error reports the holder PID and whether it is still
|
|
18
|
+
* running, so a human can safely remove an orphaned lock (the only way one arises is a writer dying
|
|
19
|
+
* mid-append, e.g. SIGKILL/power loss; appends take milliseconds). This matches the store's existing
|
|
20
|
+
* fail-closed stance (a torn trailing line is also detected, never silently repaired).
|
|
21
|
+
*
|
|
22
|
+
* Scope: same-host writers only (advisory `O_EXCL` lockfile + local PID diagnosis). Shared/networked
|
|
23
|
+
* filesystems (NFS) are out of scope, as is the store itself (single host, single writer — SPEC).
|
|
24
|
+
* Operational only — it does NOT touch the frozen event contract (stream/seq/prevHash/hash).
|
|
25
|
+
* Upgrade path: `flock(2)` on a held fd would auto-release on process death (no orphan, no manual rm),
|
|
26
|
+
* but Node's stdlib does not expose it — adopt only if a native dep ever becomes acceptable.
|
|
27
|
+
*/
|
|
28
|
+
export interface LockOptions {
|
|
29
|
+
/** Max time to wait to acquire before throwing (never hang). */
|
|
30
|
+
timeoutMs?: number;
|
|
31
|
+
/** Poll interval while contended. */
|
|
32
|
+
retryMs?: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Run `fn` while holding an exclusive cross-process lock on `<targetPath>.lock`. Released in `finally`
|
|
36
|
+
* (only its own generation — a token mismatch means the lock is no longer ours and is left alone).
|
|
37
|
+
* Throws a diagnosed error after `timeoutMs` rather than hanging or stealing. NOT reentrant (the store
|
|
38
|
+
* never nests appends). NOTE: the store is synchronous, so a contended acquire blocks the whole event
|
|
39
|
+
* loop for up to `timeoutMs` — acceptable for the CLI and the (serial) stdio MCP server.
|
|
40
|
+
*/
|
|
41
|
+
export declare function withFileLock<T>(targetPath: string, fn: () => T, options?: LockOptions): T;
|
|
42
|
+
//# sourceMappingURL=lock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../src/events/lock.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,WAAW,WAAW;IAC1B,gEAAgE;IAChE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAgDD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,OAAO,GAAE,WAAgB,GAAG,CAAC,CAyC7F"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { closeSync, mkdirSync, openSync, readFileSync, unlinkSync, writeSync } from 'node:fs';
|
|
2
|
+
import { randomBytes } from 'node:crypto';
|
|
3
|
+
import { hostname } from 'node:os';
|
|
4
|
+
import { dirname } from 'node:path';
|
|
5
|
+
const DEFAULTS = { timeoutMs: 10_000, retryMs: 20 };
|
|
6
|
+
/** Synchronous sleep — the store is fully synchronous. Blocks the thread without burning CPU. */
|
|
7
|
+
function sleepSync(ms) {
|
|
8
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, Math.max(1, ms));
|
|
9
|
+
}
|
|
10
|
+
/** Is `pid` a live process on THIS host? ESRCH ⇒ dead; EPERM ⇒ alive but not ours to signal. */
|
|
11
|
+
function isAlive(pid) {
|
|
12
|
+
if (!Number.isInteger(pid) || pid <= 0)
|
|
13
|
+
return false;
|
|
14
|
+
try {
|
|
15
|
+
process.kill(pid, 0);
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
catch (err) {
|
|
19
|
+
return err.code === 'EPERM';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function readHolder(lockPath) {
|
|
23
|
+
try {
|
|
24
|
+
return JSON.parse(readFileSync(lockPath, 'utf8'));
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return undefined; // missing, torn, or empty — caller decides what that means
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/** Human-actionable diagnosis for a timeout: who holds it, and is removing it safe? */
|
|
31
|
+
function diagnose(lockPath) {
|
|
32
|
+
const holder = readHolder(lockPath);
|
|
33
|
+
if (holder === undefined) {
|
|
34
|
+
return 'holder record unreadable (lock vanished or torn)';
|
|
35
|
+
}
|
|
36
|
+
const liveness = isAlive(holder.pid)
|
|
37
|
+
? 'still RUNNING — another track writer is active, do not remove'
|
|
38
|
+
: 'NOT running — orphaned (writer died mid-append); safe to delete the lock file to recover';
|
|
39
|
+
return `held by pid ${holder.pid}@${holder.host} since ${new Date(holder.time).toISOString()}, ${liveness}`;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Run `fn` while holding an exclusive cross-process lock on `<targetPath>.lock`. Released in `finally`
|
|
43
|
+
* (only its own generation — a token mismatch means the lock is no longer ours and is left alone).
|
|
44
|
+
* Throws a diagnosed error after `timeoutMs` rather than hanging or stealing. NOT reentrant (the store
|
|
45
|
+
* never nests appends). NOTE: the store is synchronous, so a contended acquire blocks the whole event
|
|
46
|
+
* loop for up to `timeoutMs` — acceptable for the CLI and the (serial) stdio MCP server.
|
|
47
|
+
*/
|
|
48
|
+
export function withFileLock(targetPath, fn, options = {}) {
|
|
49
|
+
const { timeoutMs, retryMs } = { ...DEFAULTS, ...options };
|
|
50
|
+
const lockPath = `${targetPath}.lock`;
|
|
51
|
+
mkdirSync(dirname(lockPath), { recursive: true });
|
|
52
|
+
const token = randomBytes(12).toString('hex');
|
|
53
|
+
const deadline = Date.now() + timeoutMs;
|
|
54
|
+
for (;;) {
|
|
55
|
+
try {
|
|
56
|
+
const fd = openSync(lockPath, 'wx'); // O_CREAT|O_EXCL|O_WRONLY — fails with EEXIST if held
|
|
57
|
+
try {
|
|
58
|
+
const holder = { pid: process.pid, host: hostname(), time: Date.now(), token };
|
|
59
|
+
writeSync(fd, JSON.stringify(holder));
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
closeSync(fd);
|
|
63
|
+
}
|
|
64
|
+
break; // acquired
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
if (err.code !== 'EEXIST')
|
|
68
|
+
throw err;
|
|
69
|
+
if (Date.now() >= deadline) {
|
|
70
|
+
throw new Error(`withFileLock: timed out after ${timeoutMs}ms waiting for ${lockPath} — ${diagnose(lockPath)}.`);
|
|
71
|
+
}
|
|
72
|
+
sleepSync(retryMs);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
return fn();
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
// Release ONLY our own generation. If the file no longer carries our token (e.g. a human removed an
|
|
80
|
+
// orphan and another writer acquired), deleting it would break THEIR mutual exclusion — leave it.
|
|
81
|
+
if (readHolder(lockPath)?.token === token) {
|
|
82
|
+
try {
|
|
83
|
+
unlinkSync(lockPath);
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
// already gone — nothing to release
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=lock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock.js","sourceRoot":"","sources":["../../src/events/lock.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/events/store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/events/store.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,YAAY,EAAqB,UAAU,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAGnF;;;;;;;GAOG;AACH,qBAAa,UAAU;IACT,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,MAAM;IAE7C,mFAAmF;IACnF,OAAO,IAAI,UAAU,EAAE;IAiBvB;;;;OAIG;IACH,aAAa,CACX,MAAM,EAAE,aAAa,CAAC,YAAY,CAAC,EACnC,IAAI,GAAE;QAAE,KAAK,CAAC,EAAE,IAAI,CAAA;KAAO,GAC1B,UAAU,EAAE;IAqEf;;;;;;;OAOG;IACH,OAAO,CAAC,YAAY;CAcrB"}
|
package/dist/events/store.js
CHANGED
|
@@ -3,6 +3,7 @@ import { dirname } from 'node:path';
|
|
|
3
3
|
import { canonicalize, materialize } from './canonical.js';
|
|
4
4
|
import { contentHashOf } from './frame.js';
|
|
5
5
|
import { readHead, writeHead } from './head.js';
|
|
6
|
+
import { withFileLock } from './lock.js';
|
|
6
7
|
import { validate } from './validate.js';
|
|
7
8
|
/**
|
|
8
9
|
* Append-only single-writer event store over `.track/events.jsonl` (SPEC §3, §4).
|
|
@@ -51,48 +52,53 @@ export class EventStore {
|
|
|
51
52
|
if (isBatch && opts.cmdId === undefined) {
|
|
52
53
|
throw new Error('EventStore.appendCommand: a multi-event command requires a cmdId');
|
|
53
54
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
55
|
+
// Serialize the read→validate→compute→append→writeHead critical section ACROSS processes. Without
|
|
56
|
+
// it, two concurrent writers compute the same prevHash/seq and corrupt the single stream, which the
|
|
57
|
+
// fail-closed guard below then turns into a permanent write-DoS for every future writer (see lock.ts).
|
|
58
|
+
return withFileLock(this.filePath, () => {
|
|
59
|
+
const existing = this.readAll();
|
|
60
|
+
const integrity = validate(existing, readHead(this.filePath));
|
|
61
|
+
if (!integrity.ok) {
|
|
62
|
+
const kinds = integrity.findings.map((f) => f.kind).join(', ');
|
|
63
|
+
throw new Error(`EventStore.appendCommand: refusing to extend an invalid log ` +
|
|
64
|
+
`(${integrity.findings.length} finding(s): ${kinds})`);
|
|
65
|
+
}
|
|
66
|
+
let prevHash = existing.length > 0 ? existing[existing.length - 1].contentHash : null;
|
|
67
|
+
// Next per-aggregate seq = max(seq) + 1, aligned with validate's authority.
|
|
68
|
+
const lastSeqByAggregate = new Map();
|
|
69
|
+
for (const e of existing) {
|
|
70
|
+
lastSeqByAggregate.set(e.aggregateId, e.seq);
|
|
71
|
+
}
|
|
72
|
+
const events = [];
|
|
73
|
+
inputs.forEach((input, i) => {
|
|
74
|
+
const seq = (lastSeqByAggregate.get(input.aggregateId) ?? 0) + 1;
|
|
75
|
+
lastSeqByAggregate.set(input.aggregateId, seq);
|
|
76
|
+
const core = isBatch
|
|
77
|
+
? { ...input, cmdId: opts.cmdId, cmd: { i, n } }
|
|
78
|
+
: { ...input };
|
|
79
|
+
// Materialize ONCE to an inert plain-data snapshot, then hash AND persist that same
|
|
80
|
+
// snapshot — so a live payload (Proxy / getter / toJSON) cannot diverge between the two.
|
|
81
|
+
const materialized = materialize(core);
|
|
82
|
+
const contentHash = contentHashOf(materialized);
|
|
83
|
+
const event = { ...materialized, seq, prevHash, contentHash };
|
|
84
|
+
events.push(event);
|
|
85
|
+
prevHash = contentHash;
|
|
86
|
+
});
|
|
87
|
+
// Validate the FULL candidate stream (not just the existing prefix): the command itself
|
|
88
|
+
// could introduce a cross-event violation (e.g. an aggregate-mismatch, a malformed batch).
|
|
89
|
+
const candidate = validate([...existing, ...events]);
|
|
90
|
+
if (!candidate.ok) {
|
|
91
|
+
const kinds = candidate.findings.map((f) => f.kind).join(', ');
|
|
92
|
+
throw new Error(`EventStore.appendCommand: command would produce an invalid log ` +
|
|
93
|
+
`(${candidate.findings.length} finding(s): ${kinds})`);
|
|
94
|
+
}
|
|
95
|
+
this.appendAtomic(events);
|
|
96
|
+
writeHead(this.filePath, {
|
|
97
|
+
streamLength: existing.length + events.length,
|
|
98
|
+
lastContentHash: events[events.length - 1].contentHash,
|
|
99
|
+
});
|
|
100
|
+
return events;
|
|
94
101
|
});
|
|
95
|
-
return events;
|
|
96
102
|
}
|
|
97
103
|
/**
|
|
98
104
|
* Append all of a command's lines in one fsync'd write. Each line is the event's `canonicalize`
|
package/dist/events/store.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/events/store.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,UAAU,EACV,SAAS,EACT,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,SAAS,GACV,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAEnC,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAC1C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/events/store.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED