- Remove dead agent_identities read path and PyYAML import from workspace_uuid.py - Defer eager PyYAML import in verify_session.py to lazy YAML fallback branch - Simplify UUID resolution to 2-tier model (tier-1 own row ID -> tier-2 adapter scan) - Clean up unused Drift D and ghost cache clearing in reconcile.sh and stop_session.sh - Add 3 regression guards in tests/test_tier1_unit.py (266/266 PASS) - Update IMPROVEMENTS.md, VERSIONS.md, and SKILL.md files
109 lines
3.8 KiB
Python
109 lines
3.8 KiB
Python
# verify_session.py — session UUID verification logic
|
|
# Extracted from lib.sh VERIFY_SESSION_PYTHON block
|
|
|
|
_MAM_ORC_CACHE = None
|
|
|
|
def mam_orchestrator_uuids():
|
|
global _MAM_ORC_CACHE
|
|
if _MAM_ORC_CACHE is not None:
|
|
return _MAM_ORC_CACHE
|
|
import os, sys, json, sqlite3
|
|
override = os.environ.get("MAM_ORCHESTRATOR_UUIDS")
|
|
if override is not None:
|
|
if not override.strip():
|
|
_MAM_ORC_CACHE = []
|
|
return _MAM_ORC_CACHE
|
|
if override.strip().startswith("["):
|
|
try:
|
|
parsed = json.loads(override)
|
|
if isinstance(parsed, list):
|
|
_MAM_ORC_CACHE = [str(x) for x in parsed if x]
|
|
return _MAM_ORC_CACHE
|
|
except Exception:
|
|
pass
|
|
_MAM_ORC_CACHE = [x.strip() for x in override.split(",") if x.strip()]
|
|
return _MAM_ORC_CACHE
|
|
|
|
res = []
|
|
d_obj = None
|
|
try:
|
|
if "MAM_STATE_JSON" in os.environ and os.environ.get("MAM_STATE_JSON"):
|
|
d_obj = json.loads(os.environ.get("MAM_STATE_JSON"))
|
|
except Exception:
|
|
d_obj = None
|
|
|
|
if d_obj is None or "orchestrator_uuids" not in d_obj:
|
|
yaml_p = os.environ.get("AGENT_SESSIONS_YAML") or os.environ.get("YAML_PATH")
|
|
if yaml_p:
|
|
db_p = os.path.splitext(yaml_p)[0] + ".db"
|
|
if os.path.exists(db_p):
|
|
try:
|
|
conn = sqlite3.connect(db_p, timeout=5.0)
|
|
r = conn.execute("SELECT data FROM state WHERE id=1").fetchone()
|
|
if r and r[0]:
|
|
d_obj = json.loads(r[0])
|
|
conn.close()
|
|
except Exception:
|
|
pass
|
|
if (d_obj is None or "orchestrator_uuids" not in d_obj) and os.path.exists(yaml_p):
|
|
try:
|
|
import yaml
|
|
with open(yaml_p) as f:
|
|
d_obj = yaml.safe_load(f) or {}
|
|
except Exception:
|
|
pass
|
|
|
|
raw = d_obj.get("orchestrator_uuids") if isinstance(d_obj, dict) else None
|
|
if raw is not None:
|
|
if isinstance(raw, list) and all(isinstance(x, str) and x.strip() for x in raw):
|
|
res = list(raw)
|
|
else:
|
|
sys.stderr.write("WARNING: malformed orchestrator_uuids in state, disabling orchestrator exclusion gate\n")
|
|
res = []
|
|
_MAM_ORC_CACHE = res
|
|
return _MAM_ORC_CACHE
|
|
|
|
def mam_row_own_uuid(row):
|
|
if not isinstance(row, dict):
|
|
return None
|
|
for k in ["claude_session_id_own", "agy_conversation_id_own", "hermes_conversation_id_own", "cline_conversation_id_own"]:
|
|
v = row.get(k)
|
|
if v:
|
|
return v
|
|
return None
|
|
|
|
def workspace_key(path):
|
|
import os
|
|
try:
|
|
p = os.path.realpath(path)
|
|
except Exception:
|
|
p = path
|
|
return p.replace("/", "-").replace("_", "-")
|
|
|
|
def verify_session_uuid(ws, agent, uuid, row=None, home_dir=None, claude_dir=None, mode="discover"):
|
|
import os, json, sqlite3
|
|
from lib_py.agents.registry import get_adapter
|
|
from lib_py.agents.base import DiscoveryContext
|
|
|
|
row = row or {}
|
|
epoch = row.get("herdr_session_epoch", 0) if mode == "discover" else 0
|
|
cwd = row.get("pane", {}).get("cwd", "") or ws
|
|
|
|
if workspace_key(cwd) != workspace_key(ws):
|
|
return False
|
|
|
|
if mode == "discover" and uuid in mam_orchestrator_uuids():
|
|
if uuid != mam_row_own_uuid(row):
|
|
return False
|
|
|
|
if (mode == "revalidate" and row.get("session_id_source") == "assigned"
|
|
and not row.get("session_id_verified")):
|
|
return True
|
|
|
|
adapter = get_adapter(agent)
|
|
if not adapter:
|
|
return False
|
|
|
|
ctx = DiscoveryContext(workspace=ws, agent_name=agent, home_dir=home_dir, claude_dir=claude_dir, epoch=epoch, row=row, mode=mode)
|
|
return adapter.verify_artifact(uuid, ctx)
|