fix(agents): a session file whose startedAt is no finite time is live (Issue #31, Mac review)

float("NaN") and a JSON NaN passed the old check, and every comparison with
NaN is false, so a live holder looked like a reused pid: the in-use gate let
the purge through and the session file was taken as stale. startedAt must
now be an int or float (not bool), finite and positive; anything else cannot
be told and counts as live. A dead pid is still stale whatever it says.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
GodopuandClaude Opus 5.5 committed 2026-10-16 03:21:50 +00:00
1 parent 6e0361cf43
commit f943b0db30
2 files changed
+35 -4

No files matched your search

@@ -1,4 +1,4 @@
import os, re, json, glob, stat, time, shutil, subprocess
import os, re, json, glob, math, stat, time, shutil, subprocess
from typing import Optional, Any
from lib_py.agents.base import BaseAgentAdapter, DiscoveryContext, conversation_in_use, scan_names, _plausible_id
from lib_py.verify_session import workspace_key
@@ -77,15 +77,19 @@ def _session_file_live(data: dict, pid) -> bool:
return False
except OSError:
pass
# startedAt is epoch ms: a finite positive number. A bool, a string, NaN
# (every comparison with it is false) or an infinity is no time at all.
started = data.get("startedAt")
if isinstance(started, bool) or not isinstance(started, (int, float)) \
or not math.isfinite(started) or started <= 0:
return True
started = started / 1000.0
try:
out = subprocess.run(["ps", "-p", str(pid), "-o", "lstart="], capture_output=True, text=True,
timeout=5, env=dict(os.environ, LC_ALL="C")).stdout
lstart = time.mktime(time.strptime(" ".join(out.split()), "%a %b %d %H:%M:%S %Y"))
started = float(data["startedAt"]) / 1000.0
except Exception:
return True
if started <= 0:
return True
# startedAt is written 1.7-3.2 s after the process starts; 2 s covers
# lstart's one-second resolution.
return lstart <= started + 2