Commit Graph
727 Commits
Author SHA1 Message Date
Godopu ff8b381520 merge: fix/issue-64-ro-connect (agy, codex and hermes read their databases read-only; v4.9.8) 2026-10-20 00:38:12 +00:00
GodopuandClaude Opus 5.5 38ea4f3b8e release(v4.9.8): agy, codex and hermes read their databases read-only (Issue #64) - archive the review reports, bump the lockstep version
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
2026-10-20 09:37:53 +09:00
Godopu b0eccc5301 fix(agents): open agy, codex and hermes databases read-only (Issue #64) 2026-10-19 23:12:55 +09:00
Godopu 3ce5d5fdc1 merge: fix/issue-60-linux (opencode 2.x Linux follow-up; v4.9.7) 2026-10-19 03:16:21 +00:00
GodopuandClaude Opus 5.5 cffe279eb0 release(v4.9.7): opencode 2.x Linux follow-up (Issue #60, PR #62) - archive the review reports, bump the lockstep version
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
2026-10-19 12:16:20 +09:00
GodopuandClaude Opus 5.5 6a37c0019b fix(opencode): Mac review of the Linux fixes - a clean db has no sidecars on Mac either, the placeholder needs its example, a home install must run, status and reconcile read the db read-only (Issue #60, PR #62)
- tests: macOS SQLite keeps -wal/-shm after the last close (persistent WAL);
  the `clean` state removes them after the checkpointing close
- the 2.x placeholder pattern requires the quoted example, so a typed
  `Ask anything…` is read as a draft
- auth_ok takes ~/.opencode/bin/opencode only as an executable file
- status.sh and reconcile.sh (drift C) open opencode.db with _ro_connect

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
2026-10-19 10:57:40 +09:00
GodopuandClaude Opus 5.5 6a4e385a78 test(opencode): the narrow 2.x capture ends at its last drawn line (Issue #60, review: git diff --check)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 13:38:58 +00:00
GodopuandClaude Opus 5.5 d17cd80bd9 fix(opencode): the auth check is the binary, and create takes the adapter's verdict (Issue #60, Linux item 3)
opencode 2.x needs no login: a fresh HOME runs a free default model and a
local provider has no key, while 2.x keeps no auth.json. auth_ok is now
"opencode on PATH or under <HOME>/.opencode/bin". `python -m lib_py.agents
auth-ok <agent>` exits with an adapter's verdict, and create's opencode
branch uses it (same 7 lines) instead of its own auth.json/key test and
`opencode --version`, which wrote a line to the real opencode log.
test_a4's opencode block now pins the binary rule (decision D1, required
by the brief's item 3 and by both reviewers). Other agents are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 13:38:58 +00:00
GodopuandClaude Opus 5.5 7803d47026 fix(opencode): a -wal left without its -shm is read, not ignored (Issue #60, Linux item 5, review)
_ro_connect read every database without both sidecars as immutable, which
skips a -wal's committed rows: a recovered DB+WAL with no -shm showed no
sessions (planner-reviewer-codex-01). That state - no writer runs without
a -shm - is now read from a private DB+WAL copy, where SQLite may rebuild
the index, loaded into memory; nothing beside the source is touched. The
query matrix gains the walonly state.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 13:36:41 +00:00
GodopuandClaude Opus 5.5 463817ee34 fix(stop): an unconfirmed /exit no longer claims a kill-chain fallback (Issue #60, Linux item 2)
An agent that exits on /exit never turns `working`, so send_keys_safe
returns 4 although the stop then ends cleanly. The line now says the
delivery is unconfirmed and that the stop waits for the session to exit;
the kill steps keep their own lines, printed only when they run. Exit
judgement and the kill chain are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 12:35:27 +00:00
GodopuandClaude Opus 5.5 614ab1420f fix(opencode): debug paths runs once per binary and home in a process (Issue #60, Linux item 6)
Every run appends a line to opencode's log, and one discover resolved the
database once per candidate. A successful answer is kept per (binary, HOME,
XDG_DATA_HOME) - the values the run sees; a failed run is not remembered.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 12:33:01 +00:00
GodopuandClaude Opus 5.5 ac5f1154c7 fix(opencode): queries open the database read-only without touching its sidecars (Issue #60, Linux item 5)
A read-write open checkpointed the WAL and deleted -wal/-shm on close; a
plain mode=ro open created missing ones and left them. _ro_connect uses the
sidecars only when both exist (a live writer keeps them) and reads the file
as immutable otherwise. verify_artifact, _has_session, discover,
_descendants and residual_artifacts (db_rows_naming takes a connect) use it;
the purge's own writes are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 12:31:44 +00:00
GodopuandClaude Opus 5.5 14d7a46181 fix(opencode): the 2.x home placeholder is not typed input, cut example included (Issue #60, Linux item 1)
An adapter can now name its placeholder as a pattern the box's first line
matches in full (input_placeholder_pattern); input_placeholder stays the
literal lib.sh greps for. opencode: `Ask anything… "<example>"`, the closing
quote optional because a box under ~65 columns cuts the example. Fixtures:
the 140-column herdr capture and a 60-column one with the cut example.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 12:29:54 +00:00
GodopuandClaude Opus 5.5 4d49abb371 fix(tests): u1e hands the wrapper its own python - PATH's python3 may lack paho (Issue #60, Linux item 4)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 12:23:35 +00:00
Godopu 1d7b7dab58 merge: fix/issue-60-opencode-v2 (support opencode 2.x only; v4.9.6) 2026-10-18 10:36:17 +00:00
GodopuandClaude Opus 5.5 cb2c84ccd7 release(v4.9.6): opencode 2.x only (Issue #60) - archive the review reports, bump the lockstep version
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
2026-10-18 19:35:48 +09:00
GodopuandClaude Opus 5.5 0e05b1b677 fix(opencode): tests drop XDG_DATA_HOME, status reads the adapter's db, the version probe runs in a home of its own (Issue #60, review 2)
- Review 8a485fa0 B1 / c9d06e85 / c4e96018 (blocking): the adapter now
  follows the caller's XDG_DATA_HOME for its own home, but the tests did not
  drop it: a sandbox that sets HOME resolved the runner's real data dir.
  XDG_DATA_HOME joins _agent_home_guard.DROPPED_VARS (dropped per test), and
  the session guard watches <XDG_DATA_HOME>/opencode when it is set.
  Checked with XDG_DATA_HOME set to a separate dir: the opencode modules
  pass and nothing is written there.
- status.sh asks the adapter for the db (`debug paths`, XDG-aware) instead
  of a fixed ~/.local/share/opencode (8a485fa0 N1).
- The opt-in test's `opencode --version` probe ran with the real HOME at
  import and appended to the real opencode log; it runs in a temporary home
  now (8a485fa0 N2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
2026-10-18 16:36:12 +09:00
GodopuandClaude Opus 5.5 cb5f439cce fix(opencode): a purge takes its child sessions' 1.x rows, the background service alone holds no session, XDG_DATA_HOME is followed (Issue #60, review)
- Review 614b6263 (codex, P2): `opencode session delete` removes the child
  sessions with their parent, but their 1.x rows stayed and the parent's
  residual was empty. The child sessions (session_v2 and a 1.x session
  table, any depth) are taken before the delete; the 1.x tables (message,
  part, todo, session_share, session) are cleaned for all of them, and the
  residual also reports a child still on record (a failed delete).
- The in-use check counted any process holding the shared opencode.db; the
  per-user 2.x background service (`serve --service`) holds it for every
  session, so every opencode purge was refused while it ran (it does on
  this Mac). It no longer counts; any other holder and a command line
  naming the session still do.
- The data dir follows the caller's XDG_DATA_HOME when ctx is the caller's
  own home (else <home>/.local/share), for debug paths, the fallback and the
  residual scan (review 614b6263 / f4cedbae N4).
- resident_children = ('opencode',): the --standalone server stays the TUI's
  idle child; what runs under it still counts (review 1abe0a90).
- Tests: child sessions on a migrated database, a failed delete, the service
  holder, XDG, resident children, drift C pinning the parent over a newer
  child session (review f4cedbae N2), and the real-binary test no longer
  depends on PATH (N1).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
2026-10-18 15:46:04 +09:00
GodopuandClaude Opus 5.5 6b4b96fa18 docs(opencode): 2.x only; the TUI takes no -m/--agent; MAM spawns --standalone (Issue #60)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
2026-10-18 14:58:29 +09:00
GodopuandClaude Opus 5.5 f0d1c000f9 test(opencode): the 2.x schema and CLI, a fake opencode, and an opt-in real-binary contract (Issue #60)
tests/_fake_opencode.py implements the two commands MAM calls (debug paths,
session delete) as measured on 2.0.32; unit tests never run a real opencode
(it would migrate the test database). test_real_opencode_2x_contract runs a
real 2.x opencode, when installed, in a home and tmp dir of its own with
--standalone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
2026-10-18 14:58:29 +09:00
GodopuandClaude Opus 5.5 a311c23303 fix(opencode): support opencode 2.x only - session_v2, debug paths, session delete, --standalone (Issue #60)
Measured on opencode 2.0.32 (macOS):
- the TUI rejects --agent ("Unrecognized flag"), so create and resume could
  not start opencode at all; the default agent is build. MAM now spawns
  `opencode --auto --standalone` (resume adds --session <id>): the server
  runs as the TUI's child and ends with it, and the per-user background
  service is neither used nor started;
- sessions live in session_v2 (a fresh 2.x database has no `session` table;
  a migrated one keeps the 1.x tables but no longer writes them). discover,
  verify_artifact, reconcile drift C and status read session_v2, and
  discover / drift C skip child (subagent) sessions;
- `db path` is gone (it prints the help and exits 0): the db comes from
  the `db` line of `opencode debug paths`, else the default path;
- `opencode session delete` removes a session with its child sessions from
  the 2.x tables (and leaves the 1.x ones): purge runs it with --standalone
  for a session in session_v2, still deletes the 1.x message/part/session
  rows, and residual also reports a session_v2 row left by a failed delete.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
2026-10-18 14:58:29 +09:00
Godopu 74333f87d0 merge: fix/issue-31 (a claude purge removes every path the session owns; v4.9.5) 2026-10-17 16:25:20 +00:00
GodopuandClaude Opus 5.5 6fd417a7b7 release(v4.9.5): a claude purge removes every path the session owns (Issue #31, PR #59) - archive the review reports, bump the lockstep version, load logroot eagerly
Review loop (--review-only, --all-reviewer, focused on this Mac:
macOS, /usr/bin/python3 3.9.6, bash 3.2): round 1 (@6f4f40a) agy and
grok PASS, claude and codex NOT PASS (a non-uuid id `memory` purged the
auto-memory dir, a linked dir below a root was followed, a NaN
startedAt counted as dead), sent as a PR comment and fixed by the
author in eleven commits; round 2 (@2a8d738) confirmed all three fixed
but 4/4 NOT PASS on one test holder (`sh -c "sleep 120" <uuid>` loses
the uuid on macOS /bin/sh), fixed in de6f3fc; round 3 (@de6f3fc) 4/4
PASS.

Full suite on macOS / Python 3.9.6 @de6f3fc: 1934 passed, 56 skipped,
1 error (the known #55 false positive: agy conversations of another
workspace). The real ~/.claude, /private/tmp/claude-<uid> and herdr
panes unchanged.

Also names lib_py.delegation.logroot in eager.CORE_MODULES (the v4.9.4
review's non-blocking note).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
2026-10-18 01:25:15 +09:00
GodopuandClaude Opus 5.5 de6f3fc81f test(issue31): the spelling test's holder keeps the uuid in its argv (Issue #31, Mac R2)
macOS /bin/sh (bash 3.2) execs the lone `sleep 120` of `sh -c "sleep 120" <uuid>`,
so the uuid left the process list and both [upper] and [mixed] failed on the Mac.
A Python holder keeps the uuid in argv, like _holder() in test_issue10_13_purge.py.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
2026-10-17 23:54:30 +09:00
GodopuandClaude Opus 5.5 2a8d73825b test(a4): the composite purge names its claude session by a real uuid (Issue #31, review)
claude now takes only a canonical uuid (81b6c2e), so the fixture id
'uuid-c' purged nothing. The three claude spellings in
test_purge_artifacts_composite become one uuid literal; the assertions
and the other adapters' parts are unchanged. Approved by the user.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 13:43:23 +00:00
GodopuandClaude Opus 5.5 81b6c2ea6b fix(agents): only a canonical uuid reaches any claude path (Issue #31, review)
The user asked for no path at all from an id that is not a uuid. bd09c6a
still took `<id>.jsonl` for one (the pre-#31 reach), which has_artifacts and
the residual counted while in-use always said free: `purge claude notes`
deleted notes.jsonl. Now purge, has_artifacts and residual return nothing
for such an id, as in-use already did.

This makes test_a4_adapter_contract.py::test_purge_artifacts_composite fail:
it purges the claude id 'uuid-c' and expects uuid-c.jsonl gone. Editing an
existing test needs the user's approval; the one-line data change
(a canonical uuid in place of 'uuid-c') is kept outside the branch, in job
90efa4ce's report dir. Reverting this commit restores the jsonl-only reach.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 04:09:32 +00:00
GodopuandClaude Opus 5.5 dd292c12cb fix(agents): a claude leftover behind a link still selects claude for its residual (Issue #31, review)
has_artifacts counted only the paths a purge may remove. When all that was
left lay behind a linked dir, `purge claude <uuid>` (or auto) found no
adapter and exited 5 with an empty residual, hiding the path the purge
had refused to follow. has_artifacts now counts every candidate; _inside
still decides what is removed, so the CLI exits 0, removes nothing and
lists the linked path as residual.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 04:07:49 +00:00
GodopuandClaude Opus 5.5 c0248b88be fix(agents): any spelling of a claude uuid is checked as claude's lowercase id (Issue #31, review)
_is_uuid took an uppercase or mixed-case uuid, and the paths built from it
are the live lowercase session's own files on macOS's default
case-insensitive APFS. The in-use checks compare exactly, though: session
files and command lines carry the lowercase id, so `purge claude <UPPER>`
found no holder and could remove a live session's files. _canonical now
lowercases a canonical uuid, and the paths, the session-file and job
matches, the in-use check and the residual all use it; a command line is
searched for both spellings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 04:06:37 +00:00
GodopuandClaude Opus 5.5 60779ba1f8 fix(agents): a startedAt too large for a float counts as live (Issue #31, review)
json.load reads a huge integer as an int, and math.isfinite raised
OverflowError on it outside any try: conversation_in_use and purge_artifacts
(which must never raise) threw, where 6f4f40a had taken it as live. The
conversion to float now comes first, and an overflow means live.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 04:05:13 +00:00
GodopuandClaude Opus 5.5 e156179822 fix(stop): the exit-4 refusal names where the holder may be (Issue #31, Mac review)
The refusal pointed at ~/.claude/sessions/ for every agent, whatever
CLAUDE_CONFIG_DIR said, and never mentioned a non-agent process naming the
uuid on its command line. The in-use CLI now prints, on stderr while the
conversation is in use, the adapter's in_use_hints: for every adapter
`ps -axww | grep <uuid>`, and for claude its real sessions/ dir first. stop
prints them under its refusal, and says "records preserved" instead of
"no state was modified": the gate runs after the kill chain, so the session
itself may already be down. SKILL.md's exit 4 row says the same; it is not
a code block, so no inventory hash moves.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 03:25:10 +00:00
GodopuandClaude Opus 5.5 af8ed397f6 fix(agents): compare a claude process's lstart in UTC (Issue #31, Mac review)
time.mktime read ps's local lstart, which is ambiguous in the hour a DST
change repeats: the start could come out an hour off and a live holder be
taken for a reused pid (or the reverse). ps now runs with TZ=UTC0, which BSD
ps and procps both honour, and calendar.timegm reads it. No /proc.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 03:23:17 +00:00
GodopuandClaude Opus 5.5 f943b0db30 fix(agents): a session file whose startedAt is no finite time is live (Issue #31, Mac review)
float("NaN") and a JSON NaN passed the old check, and every comparison with
NaN is false, so a live holder looked like a reused pid: the in-use gate let
the purge through and the session file was taken as stale. startedAt must
now be an int or float (not bool), finite and positive; anything else cannot
be told and counts as live. A dead pid is still stale whatever it says.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 03:21:50 +00:00
GodopuandClaude Opus 5.5 6e0361cf43 fix(agents): a claude purge never follows a linked dir below its root (Issue #31, Mac review)
A tmp-root entry <key> linking outside made `<key>/<uuid>` look like a plain
directory, and rmtree removed what lay behind the link; projects/<key>,
file-history/ and the other config dirs had no such check either. Each
candidate now keeps the root it was found under (config, projects or tmp),
and is purged only when every component between that root and the leaf is a
real directory and its parent resolves inside the resolved root. A root may
itself be a link (/tmp -> /private/tmp), a leaf link is still removed as the
link alone, and a candidate behind a link is reported as residual instead.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 03:20:55 +00:00
GodopuandClaude Opus 5.5 bd09c6a133 fix(agents): a claude purge takes directories only for a canonical uuid (Issue #31, Mac review)
projects/<key>/memory/ (Claude Code's auto memory) sits beside the session
dirs, and `purge claude memory` removed it whole. Only an 8-4-4-4-12 hex id
now reaches the session's directories, session files, jobs and tmp dirs. Any
other id keeps the pre-#31 reach, the `<id>.jsonl` file alone (test_a4 still
purges "uuid-c"); its residual is that file and nothing holds it in use.
The shared _plausible_id is unchanged for the other adapters.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 03:19:02 +00:00
GodopuandClaude Opus 5.5 26fb1c4130 test(issue31): keep every claude tmp root candidate inside the test
The adapter's fixed /tmp fallback is now a module constant. The new tests
point it, TMPDIR, TMP and TEMP at the test's own dirs, in the test process
and (through a sitecustomize on PYTHONPATH) in every python a test starts,
so no test lists the real /tmp/claude-<uid> any more (Mac review, PR #59).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 03:16:36 +00:00
GodopuandClaude Opus 5.5 6f4f40a4ad test(issue31): stop purges a session kept under CLAUDE_CONFIG_DIR
End to end through stop_session.sh with CLAUDE_CONFIG_DIR alone and with a
matching CLAUDE_PROJECT_DIR; plus the DiscoveryContext default. The
config-only stop case and the default check fail on 872d5f1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 16:29:16 +00:00
GodopuandClaude Opus 5.5 f0af98971e fix(agents): the claude projects root follows CLAUDE_CONFIG_DIR too (Issue #31, review)
stop resolves the uuid before it purges, through lib.sh's exported
CLAUDE_PROJECT_DIR and DiscoveryContext.claude_dir, both of which defaulted
to $HOME/.claude/projects. With CLAUDE_CONFIG_DIR alone the transcript under
<cfg>/projects was not found, so stop removed the row and purged nothing.
Both defaults are now ${CLAUDE_CONFIG_DIR:-<home>/.claude}/projects; an
explicit CLAUDE_PROJECT_DIR still wins.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 16:29:16 +00:00
GodopuandClaude Opus 5.5 872d5f12fb test(issue31): CLAUDE_CONFIG_DIR and partial-failure purges
Config-only and config+project overrides: a live session is refused and a
stopped one cleaned up. A key that cannot be removed keeps its session file;
a job dir that cannot be emptied keeps state.json; both are reported and
removed on retry. 5 of these fail on 8edb8d6.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 16:00:40 +00:00
GodopuandClaude Opus 5.5 57830cf00a docs(stop): the workflow and the state diagram say a purge removes the row (Issue #31)
SKILL.md lines 52 and 83 still said a purge leaves a `terminated` row. The
two blocks' inventory shas move with them (#42), and so does the
passthrough line of stop's heredoc SystemExit(1) (310 -> 327, after the
process gate). Line counts are unchanged, so no other block moves.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 16:00:40 +00:00
GodopuandClaude Opus 5.5 f542596975 fix(agents): a claude purge keeps ownership evidence until last (Issue #31, review)
A session file is what ties a pid's key file to the session, and a job's
state.json what ties the job dir: removing them first left the rest
unattributable after a partial failure (residual: none, and a retry could
not find it). Keys now go before their session file, which stays while any
key does; a job dir is emptied with state.json last and kept if anything
stays. residual lists a session file's key files (masked). A startedAt of 0
or less cannot tell a reused pid and counts as live; the sessions/ listdir
no longer raises.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 16:00:40 +00:00
GodopuandClaude Opus 5.5 8a4f651bdf fix(agents): claude follows CLAUDE_CONFIG_DIR (Issue #31, review)
CLAUDE_CONFIG_DIR moves claude's whole config root, sessions/ included, so a
live session started under it was not seen and a stopped one left
file-history and the rest behind. The config root is now CLAUDE_CONFIG_DIR,
else <home>/.claude; the purge and residual scans look at ctx.claude_dir and
the root's own projects/, each once. The test guard drops the variable for
every test like the other agent-home variables (test_issue55 l1 requires
every *_DIR the adapters read to be accounted for).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 16:00:40 +00:00
GodopuandClaude Opus 5.5 8edb8d6f0f test(issue31): purge, residual and the stop process gate
17 of the 25 cases fail on 26e2c43; the other 8 pin invariants (other
sessions, shared files, malformed ids, a prefix-twin job dir).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 15:16:06 +00:00
GodopuandClaude Opus 5.5 6328e67469 docs(stop): a purge removes the row; exit 4 covers a live agent (Issue #31)
The prose said a purge leaves a `terminated` row; the code removes it, and
the monitor never marks a stopped row. The step-5 list names what a claude
purge removes. The two code blocks (lines 52, 83) still say `terminated`:
changing them changes their inventory sha, which waits for approval.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 15:16:06 +00:00
GodopuandClaude Opus 5.5 b3461377ae 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>
2026-10-15 15:16:06 +00:00
GodopuandClaude Opus 5.5 ae98cf18c4 fix(stop): a purge waits for the agent process, not only the herdr session (Issue #31)
A closed herdr session is not an exited agent, and the `herdr already dead`
path ran no check at all, so stop could remove the files of a live claude
and then its row. New `python -m lib_py.agents in-use <agent> <uuid> [ws]
[--wait s]` gives the purge CLI's own verdict; stop asks it outside the
registry lock and, unless it answers free, exits 4 with nothing changed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 15:16:06 +00:00
GodopuandClaude Opus 5.5 48cda51d85 fix(stop): a purge reports its residual like orc_onboard (Issue #31)
stop called purge_artifacts only. It now prints `WARN residual: <path>` for
each leftover or `residual: none (agent: <agent>)`, the strings orc_onboard
prints. The row is still removed and the exit stays 0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 15:16:06 +00:00
GodopuandClaude Opus 5.5 366da3b3d6 fix(agents): claude reports what still carries the uuid (Issue #31)
claude had no residual_artifacts, so a purge always printed `residual: none`.
It now reports names holding the uuid under ~/.claude (projects excluded),
in projects two levels deep, in the tmp roots, plus the owned jobs dir and
session files. Shared files (history.jsonl, ~/.claude.json) are not
reported: they always mention every session. scan_names goes to base.py.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 15:16:06 +00:00
GodopuandClaude Opus 5.5 9ccd3c1835 fix(agents): claude purge removes every path the session owns (Issue #31)
The claude purge removed only <uuid>.jsonl. It now removes everything the
session alone owns: projects/<key>/<uuid>/, file-history/<uuid>/,
session-env/<uuid>/, jobs/<uuid[:8]>/ when its state.json names the session,
a stale sessions/<pid>.json with that pid's key file (name only, never read)
and <tmp>/claude-<uid>/*/<uuid>/. An id that is empty, all dots or holds
/, .. or * builds no path. has_artifacts finds leftovers without the transcript,
and conversation_in_use also sees a live claude through sessions/<pid>.json
(a `claude -c` names no uuid on its command line); a reused pid is told
apart by ps lstart against the file's startedAt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 15:16:06 +00:00
Godopu 26e2c43753 merge: fix/issue-57 (the audit log follows a moved registry; v4.9.4)
Closes #57. Review round 2 (@a7cb90e) 4/4 PASS; full suite on macOS / Python 3.9.6 green apart from the known #55 false positive.
2026-10-15 13:52:09 +00:00
GodopuandClaude Opus 5.5 7cf728e9f8 release(v4.9.4): the audit log follows a moved registry (Issue #57, PR #58) - archive the review reports and bump the lockstep version
Review loop (--review-only, --all-reviewer, focused on this Mac:
macOS, /usr/bin/python3 3.9.6, bash 3.2): round 1 (@63d8164) agy and
grok PASS, claude and codex NOT PASS (F1 paho via the /usr/bin/python3
fallback, F2 logs default path, R1 disk-fallback redispatch
interleaving, R2 symlinked registry), sent as a PR comment and fixed by
the author in four commits; round 2 (@a7cb90e) 4/4 PASS.

Full suite on macOS / Python 3.9.6 @a7cb90e: 1867 passed, 56 skipped,
1 error (the known #55 false positive: WAL/SHM of an agy conversation
running in another workspace). Real herdr panes and ~/.claude/projects
unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
2026-10-15 22:52:04 +09:00