mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-11-05 20:52:22 +01:00
refactor(runtime): centralize verified process lifecycle
Extract the generic process lifecycle layer (src/process_lifecycle.py) shared by runtime-owned subprocesses: process identity (pid + boot-bound start token), identity-bound observation, group and pidfd probes, the TERM -> verify -> KILL -> verify escalation with re-gating before escalation, identity-scoped sweeps, and the termination receipt. Containment, the PTY shell, the Cookbook survivor sweep, the browser lifecycle, web_tools browser cleanup, kill_process_tree and the startup reaper consume it while keeping their own ownership semantics. Safety corrections: - browser membership and identity are bound in one snapshot; no identity is recaptured after membership is decided - web_tools legacy pid-file and profile-match kills signal only verified identities; browser CLI groups only while their spawn identity verifies - Cookbook and legacy-tmux descendant capture bind membership to identity - PTY teardown never signals the server's own process group - unverifiable processes are reported, never signalled
This commit is contained in:
@@ -132,3 +132,34 @@ def test_legacy_cleanup_against_a_private_real_tmux_server(tmp_path, monkeypatch
|
||||
assert containment.active_grants() == []
|
||||
finally:
|
||||
subprocess.run([real_tmux, "-S", socket, "kill-server"], capture_output=True)
|
||||
|
||||
|
||||
def test_a_descendant_reissued_after_the_table_read_is_never_released(legacy, monkeypatch):
|
||||
reads = {"n": 0}
|
||||
|
||||
def table():
|
||||
reads["n"] += 1
|
||||
rows = {4200: process_ownership.ProcessInfo(4200, 4100, "/bin/bash --noprofile --norc")}
|
||||
if reads["n"] <= 2:
|
||||
rows[4201] = process_ownership.ProcessInfo(4201, 4200, "sleep 60")
|
||||
else:
|
||||
# The child exited and its pid now names an unrelated process.
|
||||
rows[4201] = process_ownership.ProcessInfo(4201, 1, "sshd: stranger")
|
||||
return rows
|
||||
|
||||
monkeypatch.setattr(process_ownership, "process_table", table)
|
||||
process_reaper.reap_legacy_agent_tmux()
|
||||
assert 4201 not in [pid for pid, _ in legacy["released"]]
|
||||
|
||||
|
||||
def test_an_unidentifiable_descendant_keeps_the_session_unsignalled(legacy, monkeypatch):
|
||||
def start_token(pid):
|
||||
if pid == 4201:
|
||||
raise process_ownership.InspectionUnavailable("/proc/4201/stat")
|
||||
return f"token:{pid}"
|
||||
|
||||
monkeypatch.setattr(process_ownership, "start_token", start_token)
|
||||
report = process_reaper.reap_legacy_agent_tmux()
|
||||
assert report["unverifiable"] == 1
|
||||
assert legacy["released"] == []
|
||||
assert all(call[1] != "kill-session" for call in legacy["calls"])
|
||||
|
||||
Reference in New Issue
Block a user