fix(execute_code): parallel cells no longer orphan kernel processes; LSP stops treating package dirs as project roots

Session kernels: a kernel mid-spawn (proc=None) read as dead, so every
concurrent cell for one owner replaced the registry entry and the
winner's process leaked outside the registry (110 live kernels, 1.1 GB,
330 threads under one 4-capped process). Reap/evict also tore down
kernels with cells attached, rmtree-ing the staging dir under the
spawner. Kernels now track attached cells: only settled kernels are
reaped/evicted, a kernel dropped while busy is torn down by its last
cell, and in-cell registry pops never remove a replacement.

LSP: a directory holding __init__.py is a package, not a project root.
hermes_cli/setup.py matched the python marker list and gave every
worktree a second pyright rooted at hermes_cli/ (70 of 105 reaped
clients in one session, ~40 servers / 8.7 GB live).
This commit is contained in:
Teknium
2026-09-02 21:20:41 -07:00
parent c368b145da
commit 4dac5f28af
4 changed files with 121 additions and 16 deletions
+25
View File
@@ -307,6 +307,31 @@ class TestKernelOwnershipAndLifecycle(unittest.TestCase):
stale.proc.wait(timeout=10)
self.assertFalse(stale.alive())
def test_parallel_cells_share_one_kernel_process(self):
"""Parallel cells for one owner race the first spawn. Each racer
used to see proc=None as 'dead', replace the registry entry, and
orphan the winner's process — 110 live kernels under a 4-capped
process (Sep 2026). Every kernel process must stay registry-owned."""
import subprocess
import threading
results = []
with _kernel_config():
def _cell():
results.append(self._run_as("conv-a", "import time; time.sleep(0.3)", task_id="t"))
threads = [threading.Thread(target=_cell) for _ in range(6)]
for t in threads:
t.start()
for t in threads:
t.join()
self.assertEqual([r["status"] for r in results], ["success"] * 6)
self.assertEqual(len(_KERNELS), 1)
live = subprocess.run(
["pgrep", "-fc", "-P", str(os.getpid()), "hermes_kernel_runner"],
capture_output=True, text=True,
).stdout.strip()
self.assertEqual(live, "1")
class TestPerCellRpcAuthority(unittest.TestCase):
"""Interpreter state persists across cells; RPC authority must not."""