fix(agents): codex, grok and opencode report their residual (Issue #31)

Their purge is unchanged; what it leaves is now reported: codex names and
thread rows (state_*, thread_history_*; logs_* is not scanned), grok
memory-v2 observations, opencode event/todo rows. db_rows_naming opens the
DB read-only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
GodopuandClaude Opus 5.5 committed 2026-10-15 15:16:06 +00:00
1 parent ae98cf18c4
commit b3461377ae
4 files changed
+61 -3

No files matched your search

+12 -1
View File
@@ -1,6 +1,6 @@
import os, json, glob, sqlite3, subprocess
from typing import Optional, Any, List
from lib_py.agents.base import BaseAgentAdapter, DiscoveryContext
from lib_py.agents.base import BaseAgentAdapter, DiscoveryContext, scan_names, db_rows_naming
from lib_py.verify_session import workspace_key
class CodexAgentAdapter(BaseAgentAdapter):
@@ -158,6 +158,17 @@ class CodexAgentAdapter(BaseAgentAdapter):
pass
return purged
def residual_artifacts(self, uuid: str, ctx: DiscoveryContext) -> List[str]:
# Issue #31: names under CODEX_HOME plus thread rows. logs_*.sqlite is
# not scanned (no thread index: a full scan of a large file).
root = self._codex_home(ctx)
found = scan_names(root, uuid)
for db in sorted(glob.glob(f"{root}/state_*.sqlite")):
found += db_rows_naming(db, uuid, ("thread_id",), id_tables=(("threads", "id"),))
for db in sorted(glob.glob(f"{root}/thread_history_*.sqlite")):
found += db_rows_naming(db, uuid, ("thread_id",))
return found
def spawn_spec(self, binary: str, session_uuid: str = "", use_wrapper: bool = False) -> str:
return f"{binary} --dangerously-bypass-approvals-and-sandbox"
@@ -1,7 +1,7 @@
import os, json, glob, shutil
from typing import Optional, Any
from urllib.parse import quote
from lib_py.agents.base import BaseAgentAdapter, DiscoveryContext
from lib_py.agents.base import BaseAgentAdapter, DiscoveryContext, scan_names
from lib_py.verify_session import workspace_key
@@ -108,6 +108,11 @@ class GrokAgentAdapter(BaseAgentAdapter):
purged.append(self.artifact_path(uuid, ctx))
return purged
def residual_artifacts(self, uuid: str, ctx: DiscoveryContext) -> list:
# Issue #31: reported, not removed - memory-v2 observations are the
# shared store of grok's memory pipeline.
return scan_names(f"{ctx.home_dir}/.grok", uuid)
def spawn_spec(self, binary: str, session_uuid: str = "", use_wrapper: bool = False) -> str:
if session_uuid:
return f"{binary} --session-id {session_uuid} --permission-mode bypassPermissions"
@@ -1,6 +1,6 @@
import os, sys, sqlite3, shutil
from typing import Optional, Any, List
from lib_py.agents.base import BaseAgentAdapter, DiscoveryContext
from lib_py.agents.base import BaseAgentAdapter, DiscoveryContext, scan_names, db_rows_naming
from lib_py.verify_session import workspace_key
_PROVIDER_ENV_VARS = (
@@ -194,6 +194,13 @@ class OpenCodeAgentAdapter(BaseAgentAdapter):
sys.stderr.write(f"WARN: purge opencode db records failed: {e}\n")
return purged
def residual_artifacts(self, uuid: str, ctx: DiscoveryContext) -> list:
# Issue #31: the purge leaves event-sourced rows (event, todo, ...);
# deleting those is not known to be safe, so they are reported.
found = scan_names(f"{ctx.home_dir}/.local/share/opencode", uuid)
return found + db_rows_naming(self._resolve_db(ctx), uuid, ("session_id", "aggregate_id"),
id_tables=(("session", "id"),))
def spawn_spec(self, binary: str, session_uuid: str = "", use_wrapper: bool = False) -> str:
return f"{binary} --auto --agent build"