fix(issue-10,11,13,15): complete agy purge, orchestrator purge, workspace-anchored registry
Issue #10 - agy purge_artifacts left resumable pieces behind: it now also removes the SQLite sidecars (-wal/-shm/-journal), the title annotation and the presence lock (the lock only once no live process references the conversation), and residual_artifacts() reports anything under ~/.gemini/antigravity-cli still carrying the uuid. Issue #13 - the orchestrator has no herdr_sessions row, so its conversation could not be purged by any skill. `lib_py.agents purge <agent|auto> <uuid>` resolves the adapter from what is on disk (orchestrator_uuids stores bare uuids), refuses while a live process names the uuid (conversation_in_use: process list minus the caller's own lineage, plus lsof), and prints what it purged. `orc_onboard.sh --remove <uuid> --purge-conversation --yes [--agent]` runs it before the registry update so a refusal changes nothing (exit 4 without --yes, 5 while in use). Issue #11 - "Successfully removeed": conjugate add/remove explicitly. Issue #15 - the job registry and audit log followed the caller's cwd, so the pytest suite (create_session.sh with its default onboarding job, run from the repo root) had left 593 test records in the real .mam/jobs. Defaults now resolve MAM_JOBS_DIR / DELEGATE_JOB_LOGS_DIR, then $WORKSPACE_ROOT/.mam/..., then the cwd (mqtt_common.default_registry_dir / get_logs_dir; registry.py, publish_event.py, service.py, create_session.sh, stop_session.sh); the sandbox fixture pins both. The tier suites that used to leak now leave the real registry untouched (881 records before and after). Tests: test_issue10_13_purge.py (13), test_issue15_registry_isolation.py (7); T-O13 pins the corrected message; the R1 helper test and B-9 logs-dir test now assert the workspace-anchored contract; publish_event snapshot updated. Refs #10 #11 #13 #15 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
This commit is contained in:
1 parent
bd3df890dc
commit
c82ea75a15
20 files changed
+723
-33
No files matched your search
@@ -1,4 +1,4 @@
|
||||
import os, json, sqlite3, shutil
|
||||
import os, sys, json, sqlite3, shutil
|
||||
from typing import Optional, Any
|
||||
from lib_py.agents.base import BaseAgentAdapter, DiscoveryContext
|
||||
|
||||
@@ -71,18 +71,55 @@ class AgyAgentAdapter(BaseAgentAdapter):
|
||||
return False
|
||||
return True
|
||||
|
||||
def _cli_root(self, ctx: DiscoveryContext) -> str:
|
||||
return f"{ctx.home_dir}/.gemini/antigravity-cli"
|
||||
|
||||
def purge_artifacts(self, uuid: str, ctx: DiscoveryContext) -> list:
|
||||
# Issue #10: a purge must leave nothing resumable behind. Besides the
|
||||
# conversation DB and the brain dir, agy keeps SQLite sidecars (-wal /
|
||||
# -shm / -journal, created whenever the DB is opened - the stop path
|
||||
# itself does so while capturing the id, and an unflushed WAL can still
|
||||
# hold conversation content), the title annotation and a presence lock.
|
||||
purged = []
|
||||
db = self.artifact_path(uuid, ctx)
|
||||
if os.path.exists(db):
|
||||
os.remove(db)
|
||||
purged.append(db)
|
||||
brain = f"{ctx.home_dir}/.gemini/antigravity-cli/brain/{uuid}"
|
||||
for path in [db] + [f"{db}{suffix}" for suffix in ("-wal", "-shm", "-journal")]:
|
||||
if os.path.exists(path):
|
||||
os.remove(path)
|
||||
purged.append(path)
|
||||
root = self._cli_root(ctx)
|
||||
brain = f"{root}/brain/{uuid}"
|
||||
if os.path.isdir(brain):
|
||||
shutil.rmtree(brain, ignore_errors=True)
|
||||
purged.append(brain)
|
||||
annotation = f"{root}/annotations/{uuid}.pbtxt"
|
||||
if os.path.exists(annotation):
|
||||
os.remove(annotation)
|
||||
purged.append(annotation)
|
||||
# The presence lock marks a conversation some process has open; only
|
||||
# remove it once nothing references the conversation any more.
|
||||
lock = f"{root}/presence/{uuid}.lock"
|
||||
if os.path.exists(lock):
|
||||
if self.conversation_in_use(uuid, ctx):
|
||||
print(f"WARN: presence lock kept, conversation {uuid} is still in use: {lock}", file=sys.stderr)
|
||||
else:
|
||||
os.remove(lock)
|
||||
purged.append(lock)
|
||||
return purged
|
||||
|
||||
def residual_artifacts(self, uuid: str, ctx: DiscoveryContext) -> list:
|
||||
"""Anything under the agy CLI tree still carrying this conversation id."""
|
||||
root = self._cli_root(ctx)
|
||||
if not os.path.isdir(root):
|
||||
return []
|
||||
found = []
|
||||
for dirpath, dirnames, filenames in os.walk(root):
|
||||
for name in dirnames + filenames:
|
||||
if uuid in name:
|
||||
found.append(os.path.join(dirpath, name))
|
||||
# Do not descend into a matched directory; it is reported as a whole.
|
||||
dirnames[:] = [d for d in dirnames if uuid not in d]
|
||||
return sorted(found)
|
||||
|
||||
def spawn_spec(self, binary: str, session_uuid: str = "", use_wrapper: bool = False) -> str:
|
||||
return f"{binary} --dangerously-skip-permissions"
|
||||
|
||||
|
||||
Reference in new issue
Block a user