@vincemakes/kiso-runtime 1.0.0 → 1.0.1
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/lock-adapter.js +33 -1
- package/package.json +1 -1
package/dist/lock-adapter.js
CHANGED
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
* pauses plus SIGSTOP/SIGCONT, and locate the freeze points via
|
|
62
62
|
* ready-marker files (ADR-0050 §test affordances).
|
|
63
63
|
*/
|
|
64
|
+
import { execFileSync } from "node:child_process";
|
|
64
65
|
import { closeSync, fsyncSync, linkSync, openSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
|
|
65
66
|
import { randomUUID } from "node:crypto";
|
|
66
67
|
import { join } from "node:path";
|
|
@@ -78,14 +79,45 @@ export class LockUnavailableError extends Error {
|
|
|
78
79
|
this.name = "LockUnavailableError";
|
|
79
80
|
}
|
|
80
81
|
}
|
|
82
|
+
/**
|
|
83
|
+
* ADR-0050 Amendment 1 (Finding R-I-1): the liveness probe is
|
|
84
|
+
* state-aware. A dead holder can linger in the process table after a
|
|
85
|
+
* kill — the exiting state (STAT E on macOS: the kill landing while a
|
|
86
|
+
* pty syscall is blocked, the dead session's terminal left open) or an
|
|
87
|
+
* un-reaped zombie (STAT Z). POSIX reports BOTH alive to kill(pid, 0)
|
|
88
|
+
* (they exist until reaped), so the takeover refused a holder that can
|
|
89
|
+
* never execute another session write. Both states are probed and
|
|
90
|
+
* judged DEAD. A probe failure (unreadable state) maintains the
|
|
91
|
+
* pre-amendment behavior — alive, the fail-safe refusal (prefer a false
|
|
92
|
+
* refusal over a double-write). Live-process semantics and the PID-reuse
|
|
93
|
+
* rules do not move: a live foreign writer is still refused.
|
|
94
|
+
*/
|
|
81
95
|
function isAlive(pid) {
|
|
82
96
|
try {
|
|
83
97
|
process.kill(pid, 0);
|
|
84
|
-
return true;
|
|
85
98
|
}
|
|
86
99
|
catch (err) {
|
|
87
100
|
return err.code === "EPERM";
|
|
88
101
|
}
|
|
102
|
+
const state = processState(pid);
|
|
103
|
+
return state !== "E" && state !== "Z";
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* The process state via `ps -o state= -p <pid>` (macOS/Linux). The
|
|
107
|
+
* state is the FIRST character (a multi-char string like "Ss+" is a
|
|
108
|
+
* combined flag set). An empty or unreadable state — the process
|
|
109
|
+
* vanished between the kill and the probe, or ps itself failed —
|
|
110
|
+
* returns null; isAlive's fail-safe branch then judges the holder alive
|
|
111
|
+
* (the pre-amendment behavior).
|
|
112
|
+
*/
|
|
113
|
+
function processState(pid) {
|
|
114
|
+
try {
|
|
115
|
+
const state = execFileSync("ps", ["-o", "state=", "-p", String(pid)], { encoding: "utf8" }).trim();
|
|
116
|
+
return state.length > 0 ? (state[0] ?? null) : null;
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
89
121
|
}
|
|
90
122
|
/**
|
|
91
123
|
* Read a lock file's holder identity (round 4 formats, unchanged — the
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vincemakes/kiso-runtime",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "kiso runtime — durable multi-turn agent sessions: AgentDefinition, AgentRuntime, AgentSession, Run, append-only JSONL store.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|