fix(update): the pause record's owner identity uses the reader's creation-time probe

identity() took its creation time from process_identity._process_create_time
(psutil only), while identity_is_live judges with update_lock.incarnation_live,
whose producer update_lock.process_create_time falls back to the stdlib probe.
Without psutil every record was written with ct=None, which the reader can only
call unprovable (live), so a killed updater's pause was never orphaned on such a
host. identity() now calls update_lock.process_create_time, the same producer
the marker uses.

Review 5411136378 (#132338) fix 2.
This commit is contained in:
Teknium
2026-10-05 05:59:54 -07:00
parent 183eff2f5d
commit ccca876c94
2 changed files with 17 additions and 7 deletions

View File

@@ -70,15 +70,15 @@ def record_path() -> Path:
return get_default_hermes_root() / f"{RECORD_STEM}.{_install_key()}.json"
def _create_time(pid: int) -> float | None:
from hermes_cli.process_identity import _process_create_time
return _process_create_time(pid)
def identity(pid: int | None = None) -> dict:
"""``{"pid", "ct"}`` with ``ct`` spelled like the update marker's line 3 (``ct:<s.3f>``)."""
"""``{"pid", "ct"}`` with ``ct`` spelled like the update marker's line 3 (``ct:<s.3f>``).
The creation time comes from the probe :func:`identity_is_live` judges with
(``update_lock.process_create_time``: psutil, else stdlib), so a host without psutil still
writes a provable identity instead of ``ct=None``."""
from hermes_cli import update_lock
pid = os.getpid() if pid is None else int(pid)
created = _create_time(pid)
created = update_lock.process_create_time(pid)
return {"pid": pid, "ct": None if created is None else f"ct:{created:.3f}"}

View File

@@ -650,3 +650,13 @@ def test_a_malformed_retired_list_is_set_aside_only_when_nothing_refers_to_it(tm
with pytest.raises(pause_record.RetiredUnknown):
pause_record.orphans()
assert retired.read_text(encoding="utf-8-sig") == "{trunc"
def test_a_host_without_psutil_records_an_identity_the_liveness_rule_can_prove(monkeypatch):
"""Review 5411136378 fix 2: the record's creation time comes from the same probe the reader
judges with, so a psutil-less host never writes ``ct=None`` (unprovable, so never orphaned)."""
from hermes_cli import update_lock
monkeypatch.setitem(sys.modules, "psutil", None) # `import psutil` raises ImportError
ident = pause_record.identity()
assert ident["ct"] is not None, "no creation time without psutil"
assert update_lock.incarnation_live(ident["pid"], ident["ct"]) is True