Files
multi-agent-mux/.agents/reports/reviewer-agy-01/report-7c325532.md
T
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

44 lines
4.0 KiB
Markdown

# Pre-Merge Review Report (Round 3): PR #59 (`fix/issue-31`)
- **Job ID**: `7c325532`
- **Reviewer**: `herdr:reviewer-agy-01` (`agy`)
- **Commit Range**: `26e2c43753169671b600d03274901dbe203988dd` .. `de6f3fc81f8c33a9d2335320742dc5a47f566cda` (25 commits; Round 3 delta: `2a8d73825b3832376aeaf96b09548359dc3cb887..de6f3fc81f8c33a9d2335320742dc5a47f566cda`, 1 commit)
- **Verification Worktree**: `/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261017T145452Z-6c5aa6/1`
- **Host / Runtime**: macOS `arm64-apple-darwin25` (Darwin 25.3.0), `/usr/bin/python3` 3.9.6 & `.venv/bin/python` 3.9.6, `/bin/bash` 3.2.57
---
## 1. Round 3 Delta Verification (`2a8d738..de6f3fc`)
- **Commit `de6f3fc81f8c33a9d2335320742dc5a47f566cda`**:
- Replaces `subprocess.Popen(["sh", "-c", "sleep 120", conv])` at `tests/test_issue31_purge_residual.py:315` with:
```python
# Not `sh -c "sleep 120" <uuid>`: a shell execs its last simple command
# and the uuid would vanish from the process list (macOS /bin/sh).
named = subprocess.Popen([sys.executable, "-c", "import time; time.sleep(120)", conv])
```
- **Verification Checklist**:
1. **Lowercase UUID retained in `argv` on macOS**: The Python holder process does not `exec` a separate binary, so `conv` stays visible in `ps -axo pid=,command=` for the lifetime of `named`.
2. **Passes `[upper]` and `[mixed]` on macOS**: Both `test_any_spelling_of_the_uuid_is_the_lowercase_session[upper]` and `[mixed]` pass on Darwin (`67/67` tests in `tests/test_issue31_purge_residual.py` pass).
3. **Regression sensitivity preserved**: Reverting `for u in {canon, uuid}` to `for u in (uuid,)` in `ClaudeAgentAdapter.conversation_in_use` (in an isolated `/tmp` copy) causes both `[upper]` and `[mixed]` to fail immediately at `tests/test_issue31_purge_residual.py:320` (`AssertionError: a command line naming the lowercase id`).
4. **Process cleanup (`finally: named.kill(); named.wait()`)**: Because `named` is a single Python process with no forked child `sleep`, `named.kill()` and `named.wait()` terminate it cleanly without leaving orphaned processes.
---
## 2. Cumulative Review Summary (`26e2c43..de6f3fc`)
- **Canonical UUID & deletion scope safety**: `_canonical(uuid)` in `.agents/skills/lib_py/agents/adapters/claude.py` gates `_candidates`, `has_artifacts`, `conversation_in_use`, `purge_artifacts`, and `residual_artifacts`, preventing non-UUID names (`memory`, `notes`, `uuid-c`, etc.) from matching or deleting `projects/<key>/memory/` or any other directory.
- **Symlink boundary protection**: `_inside(root, path)` verifies via `os.lstat` that no intermediate directory component between `root` and `os.path.dirname(path)` is a symlink and that `realpath(dirname(path))` stays strictly inside `realpath(root)`, while `has_artifacts` counts `_candidates` so symlinked orphans still select `claude` and appear in `residual_artifacts`.
- **macOS `ps -o lstart=` & `startedAt` fail-safe liveness**: `_session_file_live` runs `ps -p <pid> -o lstart=` with `LC_ALL="C", TZ="UTC0"`, parses via `calendar.timegm`, and treats `bool`, non-`(int, float)`, `OverflowError`, `NaN`, `±inf`, and `<= 0` `startedAt` values as live when the PID exists.
- **`stop_session.sh` & CLI `in-use` gate**: `in_use_hints` and exit-4 error messages accurately report where live holders may be found and that registry records and conversation files are preserved.
- **Test suite execution**:
- `tests/test_issue31_purge_residual.py`: **67 passed**
- `tests/test_issue55_agent_homes.py`: **PASSED**
- `tests/test_issue42_skill_blocks.py`: **PASSED**
- `tests/test_a4_adapter_contract.py`: **PASSED**
- `tests/test_orc_onboard.py`: **PASSED**
- Total run in Round 3 verification worktree: **185 passed, 1 skipped** in 48.05s (`test_tier1_unit.py` also verified passing in Round 2 with no production changes since `2a8d738`).
- **Worktree hygiene**: Verification worktree `/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261017T145452Z-6c5aa6/1` is clean (`git status -s` empty, no `.mam` directory created, basetemp removed).
[VERDICT: PASS]