@zelari/core 2.22.0 → 2.23.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/session/writer.d.ts
CHANGED
|
@@ -16,16 +16,63 @@ export declare class SessionLogLockedError extends Error {
|
|
|
16
16
|
export interface SessionLogWriterOptions {
|
|
17
17
|
/** Locks older than this may be taken over. Default 10 minutes. */
|
|
18
18
|
staleLockMs?: number;
|
|
19
|
+
/** Heartbeat-stale threshold for a LIVE owner. Default 120 s (env ZELARI_SPINE_HEARTBEAT_STALE_MS). */
|
|
20
|
+
heartbeatStaleMs?: number;
|
|
21
|
+
/** Liveness probe for the lock owner pid (injectable for tests). */
|
|
22
|
+
probe?: LockLivenessProbe;
|
|
19
23
|
/** Injectable clock for tests. */
|
|
20
24
|
now?: () => number;
|
|
21
25
|
}
|
|
26
|
+
/** Parsed shape of a `writer.lock` payload (all fields optional/tolerant). */
|
|
27
|
+
export interface LockInfo {
|
|
28
|
+
ownership?: string;
|
|
29
|
+
/** Owner pid — absent on pre-liveness locks; never trusted without a probe. */
|
|
30
|
+
pid?: number;
|
|
31
|
+
/** Lock creation/heartbeat ts (ms epoch); 0/undefined = unknown. */
|
|
32
|
+
ts?: number;
|
|
33
|
+
}
|
|
34
|
+
/** Liveness probe for a pid: true = alive. Injectable for tests. */
|
|
35
|
+
export type LockLivenessProbe = (pid: number) => boolean;
|
|
36
|
+
/** Default probe: signal 0 — ESRCH ⇒ dead, anything else (EPERM…) ⇒ alive. */
|
|
37
|
+
export declare function defaultLockLivenessProbe(pid: number): boolean;
|
|
38
|
+
export declare const DEFAULT_HEARTBEAT_STALE_MS = 120000;
|
|
39
|
+
/** Heartbeat-stale threshold: explicit value > env ZELARI_SPINE_HEARTBEAT_STALE_MS > 120 s. */
|
|
40
|
+
export declare function resolveHeartbeatStaleMs(env?: Record<string, string | undefined>): number;
|
|
41
|
+
export type LockTakeoverVerdict = {
|
|
42
|
+
takeover: true;
|
|
43
|
+
reason: 'pid-dead' | 'heartbeat-stale' | 'stale';
|
|
44
|
+
} | {
|
|
45
|
+
takeover: false;
|
|
46
|
+
reason: 'alive-fresh' | 'no-pid-locked';
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Pure takeover decision for an existing writer.lock, shared by the writer
|
|
50
|
+
* and the CLI boot sweep (spineLockSweep). Decision order:
|
|
51
|
+
* 1. lock pid dead ⇒ takeover immediately;
|
|
52
|
+
* 2. pid alive + ts fresher than the heartbeat threshold ⇒ stay locked;
|
|
53
|
+
* 3. pid alive but heartbeat-stale ⇒ likely PID reuse or a hung owner ⇒
|
|
54
|
+
* takeover. MIXED-VERSION CAVEAT: writers from pre-heartbeat versions
|
|
55
|
+
* never refresh ts on append, so a LIVE-but-idle old writer can be
|
|
56
|
+
* misjudged stale here — accepted trade-off for liveness recovery;
|
|
57
|
+
* 4. lock without a usable pid ⇒ legacy 10-minute staleness rule.
|
|
58
|
+
*/
|
|
59
|
+
export declare function evaluateLockTakeover(lockInfo: LockInfo, opts: {
|
|
60
|
+
now: number;
|
|
61
|
+
probe: LockLivenessProbe;
|
|
62
|
+
heartbeatStaleMs?: number;
|
|
63
|
+
staleLockMs?: number;
|
|
64
|
+
}): LockTakeoverVerdict;
|
|
22
65
|
export declare class SessionLogWriter {
|
|
23
66
|
private readonly sessionId;
|
|
24
67
|
private readonly eventsPath;
|
|
25
68
|
private readonly lockPath;
|
|
26
69
|
private readonly ownership;
|
|
27
70
|
private readonly staleLockMs;
|
|
71
|
+
private readonly heartbeatStaleMs;
|
|
72
|
+
private readonly probe;
|
|
28
73
|
private readonly now;
|
|
74
|
+
/** Last heartbeat ts written into the lock (throttle window anchor). */
|
|
75
|
+
private lastHeartbeatAt;
|
|
29
76
|
private nextSeq;
|
|
30
77
|
private closed;
|
|
31
78
|
private chain;
|
|
@@ -36,6 +83,15 @@ export declare class SessionLogWriter {
|
|
|
36
83
|
get currentSeq(): number;
|
|
37
84
|
private lockPayload;
|
|
38
85
|
private acquireLock;
|
|
86
|
+
/** Min interval between lock-ts refreshes (≤ ~1 rewrite/second). */
|
|
87
|
+
private static readonly HEARTBEAT_MIN_INTERVAL_MS;
|
|
88
|
+
/**
|
|
89
|
+
* Lock heartbeat: while we own the lock, refresh its ts so concurrent
|
|
90
|
+
* writers can tell a live owner from a hung one. Best-effort and throttled
|
|
91
|
+
* to at most ~1 rewrite/second; it rides the append chain so close() always
|
|
92
|
+
* lands AFTER the last heartbeat (never resurrects a removed lock).
|
|
93
|
+
*/
|
|
94
|
+
private maybeHeartbeat;
|
|
39
95
|
/** Append one event; returns the validated envelope with its assigned seq. */
|
|
40
96
|
append(input: SessionEventInput): Promise<SessionEventEnvelope>;
|
|
41
97
|
/** Flush pending appends, mark closed, release the ownership lock. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../src/session/writer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EAGL,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACvB,MAAM,YAAY,CAAC;AAEpB,qBAAa,qBAAsB,SAAQ,KAAK;aAG5B,WAAW,EAAE,MAAM;aACnB,KAAK,EAAE,MAAM;IAH/B,QAAQ,CAAC,IAAI,wBAAwB;gBAEnB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM;CAKhC;AAED,MAAM,WAAW,uBAAuB;IACtC,mEAAmE;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kCAAkC;IAClC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAID,qBAAa,gBAAgB;
|
|
1
|
+
{"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../src/session/writer.ts"],"names":[],"mappings":"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"}
|
package/dist/session/writer.js
CHANGED
|
@@ -22,13 +22,69 @@ export class SessionLogLockedError extends Error {
|
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
const DEFAULT_STALE_LOCK_MS = 10 * 60 * 1000;
|
|
25
|
+
/** Default probe: signal 0 — ESRCH ⇒ dead, anything else (EPERM…) ⇒ alive. */
|
|
26
|
+
export function defaultLockLivenessProbe(pid) {
|
|
27
|
+
try {
|
|
28
|
+
process.kill(pid, 0);
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
return err.code !== 'ESRCH';
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export const DEFAULT_HEARTBEAT_STALE_MS = 120_000;
|
|
36
|
+
/** Heartbeat-stale threshold: explicit value > env ZELARI_SPINE_HEARTBEAT_STALE_MS > 120 s. */
|
|
37
|
+
export function resolveHeartbeatStaleMs(env = process.env) {
|
|
38
|
+
const raw = env.ZELARI_SPINE_HEARTBEAT_STALE_MS;
|
|
39
|
+
if (raw) {
|
|
40
|
+
const parsed = Number.parseInt(raw, 10);
|
|
41
|
+
if (Number.isFinite(parsed) && parsed > 0)
|
|
42
|
+
return parsed;
|
|
43
|
+
}
|
|
44
|
+
return DEFAULT_HEARTBEAT_STALE_MS;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Pure takeover decision for an existing writer.lock, shared by the writer
|
|
48
|
+
* and the CLI boot sweep (spineLockSweep). Decision order:
|
|
49
|
+
* 1. lock pid dead ⇒ takeover immediately;
|
|
50
|
+
* 2. pid alive + ts fresher than the heartbeat threshold ⇒ stay locked;
|
|
51
|
+
* 3. pid alive but heartbeat-stale ⇒ likely PID reuse or a hung owner ⇒
|
|
52
|
+
* takeover. MIXED-VERSION CAVEAT: writers from pre-heartbeat versions
|
|
53
|
+
* never refresh ts on append, so a LIVE-but-idle old writer can be
|
|
54
|
+
* misjudged stale here — accepted trade-off for liveness recovery;
|
|
55
|
+
* 4. lock without a usable pid ⇒ legacy 10-minute staleness rule.
|
|
56
|
+
*/
|
|
57
|
+
export function evaluateLockTakeover(lockInfo, opts) {
|
|
58
|
+
const heartbeatStaleMs = opts.heartbeatStaleMs ?? DEFAULT_HEARTBEAT_STALE_MS;
|
|
59
|
+
const staleLockMs = opts.staleLockMs ?? DEFAULT_STALE_LOCK_MS;
|
|
60
|
+
const ts = typeof lockInfo.ts === 'number' && Number.isFinite(lockInfo.ts) && lockInfo.ts > 0
|
|
61
|
+
? lockInfo.ts
|
|
62
|
+
: 0;
|
|
63
|
+
const pid = typeof lockInfo.pid === 'number' && Number.isFinite(lockInfo.pid) && lockInfo.pid > 0
|
|
64
|
+
? lockInfo.pid
|
|
65
|
+
: undefined;
|
|
66
|
+
if (pid !== undefined) {
|
|
67
|
+
if (!opts.probe(pid))
|
|
68
|
+
return { takeover: true, reason: 'pid-dead' };
|
|
69
|
+
if (ts > 0 && opts.now - ts < heartbeatStaleMs)
|
|
70
|
+
return { takeover: false, reason: 'alive-fresh' };
|
|
71
|
+
return { takeover: true, reason: 'heartbeat-stale' };
|
|
72
|
+
}
|
|
73
|
+
if (ts > 0 && opts.now - ts > staleLockMs)
|
|
74
|
+
return { takeover: true, reason: 'stale' };
|
|
75
|
+
return { takeover: false, reason: 'no-pid-locked' };
|
|
76
|
+
}
|
|
25
77
|
export class SessionLogWriter {
|
|
26
78
|
sessionId;
|
|
27
79
|
eventsPath;
|
|
28
80
|
lockPath;
|
|
29
81
|
ownership = crypto.randomUUID();
|
|
30
82
|
staleLockMs;
|
|
83
|
+
heartbeatStaleMs;
|
|
84
|
+
probe;
|
|
31
85
|
now;
|
|
86
|
+
/** Last heartbeat ts written into the lock (throttle window anchor). */
|
|
87
|
+
lastHeartbeatAt = 0;
|
|
32
88
|
nextSeq;
|
|
33
89
|
closed = false;
|
|
34
90
|
chain = Promise.resolve();
|
|
@@ -38,6 +94,8 @@ export class SessionLogWriter {
|
|
|
38
94
|
this.lockPath = path.join(sessionDir, 'writer.lock');
|
|
39
95
|
this.nextSeq = startSeq;
|
|
40
96
|
this.staleLockMs = options.staleLockMs ?? DEFAULT_STALE_LOCK_MS;
|
|
97
|
+
this.heartbeatStaleMs = options.heartbeatStaleMs ?? resolveHeartbeatStaleMs();
|
|
98
|
+
this.probe = options.probe ?? defaultLockLivenessProbe;
|
|
41
99
|
this.now = options.now ?? Date.now;
|
|
42
100
|
}
|
|
43
101
|
/** Create the writer and acquire the ownership lock. */
|
|
@@ -60,6 +118,7 @@ export class SessionLogWriter {
|
|
|
60
118
|
const payload = this.lockPayload();
|
|
61
119
|
try {
|
|
62
120
|
await fs.writeFile(this.lockPath, payload, { encoding: 'utf-8', flag: 'wx', mode: 0o644 });
|
|
121
|
+
this.lastHeartbeatAt = this.now();
|
|
63
122
|
return;
|
|
64
123
|
}
|
|
65
124
|
catch (err) {
|
|
@@ -68,21 +127,46 @@ export class SessionLogWriter {
|
|
|
68
127
|
}
|
|
69
128
|
const existing = await fs.readFile(this.lockPath, 'utf-8').catch(() => null);
|
|
70
129
|
let owner = 'unknown';
|
|
71
|
-
|
|
130
|
+
const lockInfo = {};
|
|
72
131
|
if (existing) {
|
|
73
132
|
try {
|
|
74
133
|
const parsed = JSON.parse(existing);
|
|
75
134
|
owner = parsed.ownership ?? owner;
|
|
76
|
-
|
|
135
|
+
lockInfo.ownership = parsed.ownership;
|
|
136
|
+
lockInfo.pid = parsed.pid;
|
|
137
|
+
lockInfo.ts = parsed.ts;
|
|
77
138
|
}
|
|
78
139
|
catch {
|
|
79
|
-
// Corrupt lock file —
|
|
140
|
+
// Corrupt lock file — no usable pid/ts; the legacy staleness rule decides.
|
|
80
141
|
}
|
|
81
142
|
}
|
|
82
|
-
const
|
|
83
|
-
|
|
143
|
+
const verdict = evaluateLockTakeover(lockInfo, {
|
|
144
|
+
now: this.now(),
|
|
145
|
+
probe: this.probe,
|
|
146
|
+
heartbeatStaleMs: this.heartbeatStaleMs,
|
|
147
|
+
staleLockMs: this.staleLockMs,
|
|
148
|
+
});
|
|
149
|
+
if (!verdict.takeover)
|
|
84
150
|
throw new SessionLogLockedError(this.eventsPath, owner);
|
|
85
151
|
await fs.writeFile(this.lockPath, payload, { encoding: 'utf-8' });
|
|
152
|
+
this.lastHeartbeatAt = this.now();
|
|
153
|
+
}
|
|
154
|
+
/** Min interval between lock-ts refreshes (≤ ~1 rewrite/second). */
|
|
155
|
+
static HEARTBEAT_MIN_INTERVAL_MS = 1000;
|
|
156
|
+
/**
|
|
157
|
+
* Lock heartbeat: while we own the lock, refresh its ts so concurrent
|
|
158
|
+
* writers can tell a live owner from a hung one. Best-effort and throttled
|
|
159
|
+
* to at most ~1 rewrite/second; it rides the append chain so close() always
|
|
160
|
+
* lands AFTER the last heartbeat (never resurrects a removed lock).
|
|
161
|
+
*/
|
|
162
|
+
maybeHeartbeat() {
|
|
163
|
+
const ts = this.now();
|
|
164
|
+
if (ts - this.lastHeartbeatAt < SessionLogWriter.HEARTBEAT_MIN_INTERVAL_MS)
|
|
165
|
+
return;
|
|
166
|
+
this.lastHeartbeatAt = ts;
|
|
167
|
+
void fs.writeFile(this.lockPath, this.lockPayload(), { encoding: 'utf-8' }).catch(() => {
|
|
168
|
+
/* best-effort — a lost refresh is retried after the throttle window */
|
|
169
|
+
});
|
|
86
170
|
}
|
|
87
171
|
/** Append one event; returns the validated envelope with its assigned seq. */
|
|
88
172
|
async append(input) {
|
|
@@ -99,6 +183,7 @@ export class SessionLogWriter {
|
|
|
99
183
|
};
|
|
100
184
|
SessionEventEnvelopeSchema.parse(envelope);
|
|
101
185
|
this.nextSeq += 1;
|
|
186
|
+
this.chain = this.chain.then(() => this.maybeHeartbeat());
|
|
102
187
|
const line = JSON.stringify(envelope) + '\n';
|
|
103
188
|
this.chain = this.chain.then(() => fs.appendFile(this.eventsPath, line, 'utf-8'));
|
|
104
189
|
await this.chain;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"writer.js","sourceRoot":"","sources":["../../src/session/writer.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EACL,sBAAsB,EACtB,0BAA0B,GAG3B,MAAM,YAAY,CAAC;AAEpB,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAG5B;IACA;IAHT,IAAI,GAAG,oBAAoB,CAAC;IACrC,YACkB,WAAmB,EACnB,KAAa;QAE7B,KAAK,CAAC,4CAA4C,WAAW,WAAW,KAAK,GAAG,CAAC,CAAC;QAHlE,gBAAW,GAAX,WAAW,CAAQ;QACnB,UAAK,GAAL,KAAK,CAAQ;QAG7B,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;IACtC,CAAC;CACF;
|
|
1
|
+
{"version":3,"file":"writer.js","sourceRoot":"","sources":["../../src/session/writer.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zelari/core",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.23.0",
|
|
4
4
|
"description": "Zelari Code core library — provider-neutral agent loop (AgentHarness), multi-agent council orchestration, and built-in skills. Used by the zelari-code CLI; consumable by other agent frontends.",
|
|
5
5
|
"author": "Anathema Studio <https://anathema-studio.com/>",
|
|
6
6
|
"license": "Apache-2.0",
|