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
4.8 KiB
Review b1d3a736 — PR #59 third pass, Issue #31
Reviewed only the snapshot /var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261017T145452Z-6c5aa6/1 (loop-20261017T145452Z-6c5aa6). Head de6f3fc81f8c33a9d2335320742dc5a47f566cda, tree ffc291e6fc93822070f2b9f1d17009e83f176fcf, base 26e2c43753169671b600d03274901dbe203988dd is an ancestor. Versus base: 25 commits. Versus the second-pass head 2a8d73825b3832376aeaf96b09548359dc3cb887 there is one commit, de6f3fc, and it changes one file: tests/test_issue31_purge_residual.py, +3/−1. git diff --check is clean. Snapshot porcelain is empty and the snapshot has no .mam. Control-plane main is still 26e2c43753169671b600d03274901dbe203988dd, porcelain empty. No product file was edited.
Host tools: /usr/bin/python3 3.9.6, the control-plane venv the same 3.9.6, /bin/bash 3.2.57. The second pass on 2a8d738 already measured the three Mac findings (canonical uuid, symlink boundary, non-finite startedAt) and the UTC lstart parse. This commit does not touch that product code. conversation_in_use still folds any spelling to the lowercase uuid and searches both that spelling and the one that was asked (claude.py:350-354).
The holder keeps the uuid
de6f3fc replaces the stand-in at tests/test_issue31_purge_residual.py:317. The old line was subprocess.Popen(["sh", "-c", "sleep 120", conv]). macOS /bin/sh (bash 3.2) replaces a one-command -c script with sleep, and the uuid left the process list, so both spelling cases failed at the command-line assert. The new line is the same shape as _holder in tests/test_issue10_13_purge.py:116:
named = subprocess.Popen([sys.executable, "-c", "import time; time.sleep(120)", conv])
sys is the import already at the top of the file. The try / finally around it is unchanged: named.kill() and named.wait() are still tests/test_issue31_purge_residual.py:321-323.
A temp-home probe started that exact command with the control-plane interpreter (73-character path) and a fresh lowercase uuid. ps -eo pid=,ppid=,args=, the same invocation conversation_in_use uses, showed a 196-character argument string containing the uuid. The same string was complete with COLUMNS=80 and with COLUMNS=10000 (COLUMNS was unset in the probe process). The holder was still alive. conversation_in_use of the uppercase spelling and of the lowercase spelling were both true.
Tests
Pytest used the control-plane venv, PYTHONDONTWRITEBYTECODE=1, -p no:cacheprovider, and --basetemp /tmp/mamb1-b1d3a736-pybase. Inherited HERDR_*, MAM_*, MQTT_*, SKS_*, WORKSPACE_ROOT, DELEGATE_JOB_LOGS_DIR, HOME_DIR, CLAUDE_PROJECT_DIR, CLAUDE_CONFIG_DIR, CLAUDE_CODE_TMPDIR, CODEX_HOME, and PYTHONPATH were dropped.
On the snapshot, 149 tests ran in 42.05 s: 148 passed, 1 skipped, 1 error. Modules: tests/test_issue31_purge_residual.py, tests/test_a4_adapter_contract.py, tests/test_issue42_skill_blocks.py, tests/test_issue55_agent_homes.py. The skip is test_claude_skills_link_resolves_to_agents_skills (tests/test_issue42_skill_blocks.py:266), because .claude/skills is absent in this worktree. Both test_any_spelling_of_the_uuid_is_the_lowercase_session cases passed, along with the rest of the issue-31 file.
The error is the session-scoped issue-55 guard at teardown of test_r1_adapter_discover_writes_nothing_into_a_panes_claude_project_dir (tests/conftest.py:1603). It reported 14 new entries, all *.db-shm or *.db-wal sidecars for 7 ids under the agy conversations directory. The guard left them in place. This is the known false positive from an agy conversation in another workspace, and it is not a verdict basis.
Regression of the spelling fold. A separate clone of this snapshot had one edit: the command-line search in conversation_in_use looked up the asked spelling only, while session files still used the lowercase id. The session-file asserts and the CLI exit 4 still passed. Both spelling cases then failed at tests/test_issue31_purge_residual.py:320 (a command line naming the lowercase id), in 1.62 s. The new holder is what makes that assert see a live lowercase argv, so dropping the lowercase search fails the test. The clone was discarded. The snapshot was not modified (porcelain still empty after that run).
The three non-blocking notes from the second pass are unchanged, because this commit is the test line only: a linked projects/<key> is reported as residual, a lowercase query does not see an uppercase argv, and purge_artifacts itself has no in-use gate. The purge CLI and stop_session.sh still ask conversation_in_use first.
After the report, snapshot porcelain is still empty, the snapshot still has no .mam, and control-plane porcelain is still empty at 26e2c43. The herdr config mtime is still 1784456394.
[VERDICT: PASS]