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
6.3 KiB
Review Report — PR #59 (Issue #31: Complete Claude purge, residual reporting, and live-process stop gate)
- Reviewer:
agy(herdr:reviewer-agy-01) - Job ID:
2fff60bd - Branch / Range:
fix/issue-31(26e2c43753169671b600d03274901dbe203988dd..6f4f40a4adb2115d5997dffd31fb6473f05cab68, 13 commits, 12 files) - Verification Worktree:
/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261016T003524Z-a51548/1 - Platform: macOS Darwin (
arm64-apple-darwin25,/usr/bin/python33.9.6,.venv/bin/python3.9.6,/bin/bash3.2.57)
1. Executive Summary
PR #59 resolves Issue #31 by unifying the Claude adapter's owned-path resolution (_owned_paths) across purge_artifacts, has_artifacts, and residual_artifacts, covering:
projects/<key>/<uuid>.jsonlandprojects/<key>/<uuid>/(across bothctx.claude_dirand<config_dir>/projects),file-history/<uuid>/andsession-env/<uuid>/,jobs/<uuid[:8]>/(only whenstate.jsonhassessionId == uuid, removingstate.jsonlast so partial failure preserves ownership evidence),sessions/<pid>.<64hex>.key(masked in output as<pid>.*.key) andsessions/<pid>.jsonfor dead or PID-reused processes (removing keys before the.jsonfile so ownership evidence survives partial failure),<tmp>/claude-<uid>/<key>/<uuid>/acrossCLAUDE_CODE_TMPDIR,TMPDIR/TMP/TEMP, and/tmp.
It also adds residual_artifacts for claude, codex, grok, and opencode; wires stop_session.sh to report residuals after --purge-conversation and to check python -m lib_py.agents in-use <agent> <uuid> <cwd> --wait 5 before purging (exiting 4 without mutating state if a live agent process still holds the conversation); supports CLAUDE_CONFIG_DIR across lib.sh, DiscoveryContext, claude.py, and _agent_home_guard.py; and updates multi-agent-mux-stop/SKILL.md + tests/data/skill_code_blocks.json to reflect that --purge-conversation removes the session row rather than leaving status: terminated.
All 12 modified files pass Python 3.9.6 AST compilation and Bash 3.2 (set -u) syntax checks, all 11 regression test cases fail against base 26e2c43 and pass on head 6f4f40a, and 217 tests across 6 test suites pass on macOS.
2. macOS Environment & Deletion-Scope Safety Verification
-
BSD
ps -o lstart=Format, Locale (LC_ALL=C), andstartedAt + 2Comparison on macOS:- Verified BSD
ps -p <pid> -o lstart=on this Mac underLC_ALL=C: outputs'Fri Oct 16 09:48:41 2026 \n'. " ".join(out.split())normalizes multi-space padding (including single-digit days like'Oct 2') and trailing whitespace beforetime.strptime(..., "%a %b %d %H:%M:%S %Y").- Inspected 4 live
~/.claude/sessions/<pid>.jsonfiles on this Mac (read-only):startedAt / 1000.0 - lstartranged from+0.694 sto+2.430 s, solstart <= started + 2holds for all live processes and rejects reused PIDs started after the session file was written. - Fail-safe behavior: invalid/non-positive PIDs,
started <= 0, missingstartedAt, orps/parse errors all returnTrue(treated as live, refusing purge).
- Verified BSD
-
macOS Temp Root Resolution (
TMPDIRvs/tmp->/private/tmp) & Real Layout Agreement:- On this Mac,
TMPDIRis/var/folders/q_/.../T/(which has noclaude-501), while Claude Code's actual scratchpad directory is/private/tmp/claude-501/<workspace_key>/<uuid>/(accessed via/tmp/claude-501symlink). _tmp_roots()checksCLAUDE_CODE_TMPDIR(both<override>/claude-<uid>and<override>when already namedclaude-<uid>),TMPDIR/TMP/TEMP, and/tmp/claude-<uid>, deduplicating viaos.path.realpath(c). This ensures/private/tmp/claude-<uid>is always discovered on macOS even whenTMPDIRpoints to/var/folders/.../T/.- Read-only inspection of
~/.claudeon this Mac confirmed exact structural agreement forprojects/<key>/,file-history/<uuid>/,session-env/<uuid>/,sessions/<pid>.json+<pid>.<64hex>.key, andjobs/<uuid[:8]>/state.json(while shared files likejobs/pins.jsonandhistory.jsonlare untouched).
- On this Mac,
-
Deletion Scope Isolation, Malformed UUID Rejection, and Symlink Safety:
_plausible_id(uuid)rejects"",".","..","*", and any string containing"/","..", or"*"before constructing any path or scanning any directory._owned_jobchecksjson.load(open(job/state.json)).get("sessionId") == uuid, leaving another session'sjobs/<uuid[:8]>/(andjobs/pins.json) untouched._key_filesmatchesrf"{stem}\.[0-9a-f]{{64}}\.key"only for asessions/<pid>.jsonwhosesessionId == uuid, never reading key contents and never touching lone keys or other sessions' PIDs._removechecksif os.path.islink(path) or not os.path.isdir(path): os.remove(path)beforeshutil.rmtree(path, ignore_errors=True), andscan_namesusesos.walk(root)(followlinks=False), ensuring symlinks are never traversed outside the target scope.
-
Stop Exit 4 Contract, Residual Reporting, and Documentation Lockstep:
stop_session.shruns"$(_delegate_py_bin)" -m lib_py.agents in-use "$AGENT" "$PURGE_UUID" "$TARGET_CWD" --wait 5beforeatomic_dump_yaml; if non-zero, it publishes acancelledjob event and exits4with all records and files preserved.tests/data/skill_code_blocks.jsonhashes (301c347ff881,a973676cb2d1) and line number (stop_session.sh:327) matchmulti-agent-mux-stop/SKILL.mdandstop_session.sh(test_issue42_skill_blocks.pypasses).
3. Test Suite Execution Summary
Executed in /var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261016T003524Z-a51548/1 with HERDR_*, WORKSPACE_ROOT, MAM_ENV_FILE, MAM_JOBS_DIR, DELEGATE_JOB_LOGS_DIR, and CLAUDE_CONFIG_DIR scrubbed, PYTHONDONTWRITEBYTECODE=1, -p no:cacheprovider, and --basetemp=/tmp/mam_verify_pr59_bt:
tests/test_issue31_purge_residual.py: 32 passed (11 core regression cases verified to fail on base26e2c43)tests/test_issue55_agent_homes.py: 11 passedtests/test_issue42_skill_blocks.py: 15 passedtests/test_a4_adapter_contract.py: 55 passedtests/test_orc_onboard.py: 37 passed, 1 skippedtests/test_tier1_unit.py: 67 passed
Total: 217 passed, 1 skipped, 0 failed. Verification worktree git status -s is empty and no .mam directory was created.
[VERDICT: PASS]