Files
hermes-agent/tests/hermes_cli/test_update_obligation_identity.py
T
Teknium 89c85b8466 fix(update): settle stale receipt warnings from matching live gateways
Reconcile receipt-only restart obligations at the shared warning/catch-up
predicate, requiring every historical runtime/profile identity to have a
current live gateway successor. Preserve missing and unknown obligations,
non-gateway identities, and independently authoritative pending markers.

Keep failed receipts unchanged instead of recording an unverified success.
Live isolated two-process A/B reproduces the warning on base and settles
it after the fix; stale, unknown, and missing-profile controls still warn.

Reported-by: duanzhiwei0315
Inspired-by: zengzheqing (#104295), RootZ3n (#100249)
2026-09-07 08:20:46 -07:00

87 lines
2.7 KiB
Python

"""A historical receipt cannot outweigh complete, identity-matched live evidence."""
import json
import pytest
from hermes_cli import update_cmd, update_cmd_fleet, update_receipt
from hermes_constants import get_hermes_home
@pytest.mark.parametrize("profiles", [["alpha"], ["alpha", "beta"]])
def test_current_successors_settle_historical_obligations(monkeypatch, profiles):
home = get_hermes_home()
directory = home / "logs" / "update_receipts"
directory.mkdir(parents=True)
receipt = {
"outcome": "failed",
"plan": {
"runtimes": [
{"kind": "gateway", "profile": p, "pid": 1, "code_sha": "old"}
for p in profiles
]
},
}
path = directory / "latest.json"
path.write_text(json.dumps(receipt))
monkeypatch.setattr(update_cmd, "_current_checkout_sha", lambda: "new")
monkeypatch.setattr(
update_receipt,
"collect_fleet_versions",
lambda: [
{"profile": p, "pid": 2, "state": "current", "code_sha": "new"}
for p in profiles
],
)
assert not update_cmd_fleet._pending_fleet_restart_needed()
assert (
json.loads(path.read_text()) == receipt
) # Historical failure remains truthful.
@pytest.mark.parametrize(
"bad",
[
"missing",
"unknown",
"down",
"stale",
"wrong-sha",
"wrong-kind",
"unknown-profile",
"marker",
],
)
def test_every_owed_identity_requires_current_evidence(monkeypatch, bad):
home = get_hermes_home()
directory = home / "logs" / "update_receipts"
directory.mkdir(parents=True)
if bad == "marker":
(home / "fleet_restart_pending").write_text("expected_sha=new\n")
owed = {"kind": "gateway", "profile": "beta", "code_sha": "old"}
if bad == "wrong-kind":
owed["kind"] = "serve"
if bad == "unknown-profile":
owed["profile"] = "unknown"
(directory / "latest.json").write_text(
json.dumps({
"outcome": "failed",
"plan": {
"runtimes": [
{"kind": "gateway", "profile": "alpha", "code_sha": "old"},
owed,
]
},
})
)
rows = [{"profile": "alpha", "state": "current", "code_sha": "new"}]
if bad != "missing":
rows.append({
"profile": "beta",
"state": bad if bad in {"unknown", "down", "stale"} else "current",
"code_sha": "old" if bad == "wrong-sha" else "new",
})
monkeypatch.setattr(update_cmd, "_current_checkout_sha", lambda: "new")
monkeypatch.setattr(update_receipt, "collect_fleet_versions", lambda: rows)
assert update_cmd_fleet._pending_fleet_restart_needed()