@vincemakes/kiso-runtime 0.1.38 → 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.
@@ -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": "0.1.38",
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",
@@ -21,11 +21,11 @@
21
21
  "test": "vitest run"
22
22
  },
23
23
  "dependencies": {
24
- "@vincemakes/kiso-core": "0.1.35"
24
+ "@vincemakes/kiso-core": "1.0.0"
25
25
  },
26
26
  "peerDependencies": {
27
- "@vincemakes/kiso-provider-anthropic": "0.1.36",
28
- "@vincemakes/kiso-provider-openai": "0.1.36"
27
+ "@vincemakes/kiso-provider-anthropic": "1.0.0",
28
+ "@vincemakes/kiso-provider-openai": "1.0.0"
29
29
  },
30
30
  "peerDependenciesMeta": {
31
31
  "@vincemakes/kiso-provider-anthropic": {
@@ -36,7 +36,7 @@
36
36
  }
37
37
  },
38
38
  "devDependencies": {
39
- "@vincemakes/kiso-evals": "0.1.36",
39
+ "@vincemakes/kiso-evals": "1.0.0",
40
40
  "@types/node": "^26.1.2",
41
41
  "typescript": "^5.7.2",
42
42
  "vitest": "^3.0.0"