Issue #21 items 4, 5, 7 (worktree helpers, review identity, acceptance A1-A8), #20 test isolation, #27 .gitignore managed block, #28 host portability. VERSIONS.md carries the entry; the eight review reports of PR #29 (two rounds plus the codex re-review) are archived under .agents/reports/<session>/. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
5.1 KiB
PR #29 delta review — 2nd pass
Reviewer: planner-reviewer-codex-01. Job: f6b21a0d.
Reviewed the detached worktree multi-agent-mux-wt/pr-29 at 80a5614, comparing 46ea4cc..HEAD (commits 7a94ba2, 90a289d, 08db1da, and 80a5614). The three findings from the first review are closed by the delta. I found no additional merge-blocking defect in the reviewed changes.
R1/R2: hidden untracked submodule files
The removal guard now uses git status --porcelain --untracked-files=all --ignore-submodules=none for the worktree, and lib_py.worktree.submodule_findings() uses git status --porcelain --untracked-files=all inside every checked submodule. The identity runner's _dirty_submodules() uses the same explicit flag. This defeats status.showUntrackedFiles=no and remains independent of submodule.*.ignore and diff.ignoreSubmodules.
The source-tree snapshot still uses a temporary index and git add -A; that operation already sees untracked files independent of display settings, so no extra snapshot change is needed. The new regression cases cover hidden files before removal, files written while stopping, hidden files that appear during a review, and hidden files present before a review. The prior destructive probes were repeated against disposable fixtures: with the delta, removal returned exit 3 and preserved the untracked file; review identity refused before dispatch and produced no sidecar. R1 and R2 are therefore resolved.
R3: worktree virtual environments
worktree_prepare.sh now refuses an existing .venv symlink, creates an independent venv with the control root's .venv/bin/python, installs the delegate-job requirements plus root requirements.txt/requirements-dev.txt when present, and reports VENV=created. A usable existing environment is idempotently retained as VENV=kept. When the control interpreter is absent it warns and reports VENV=skipped; it does not invent a link. If dependency installation fails, the half-created venv is removed and the worktree remains for correction and retry. The tests cover creation, the kept path, link refusal, missing interpreter, and failed-install cleanup.
The design document and create/stop skill documentation now describe the independent environment, network requirement, link refusal, and cleanup semantics. The managed .gitignore block and shared Git info/exclude still ignore .venv and .pytest_cache; the new environment is not tracked. I found the implementation and documentation consistent.
Portability delta (#28)
The bash -c change in test_workspace_scope.py is appropriate because the test invokes the Bash source builtin. Help-output normalization collapses layout-only whitespace and the Python 3.9/3.14 option-group spelling while still comparing the actual normalized content. The deployment freshness markers skip only when the relevant nats-docker assets are absent. This checkout does not contain the optional nats-docker/docker-compose.yaml, so those asset-dependent cases skip here; PRIVATE_SERVER.md is present and its checks run. The test suite must still run those checks when a checkout has the assets. The process scanners now use POSIX ps -eo pid=,ppid=,args=, which is available on macOS and Linux and preserves the command text needed by the scanners. MAM_ENV_FILE is pinned to a deliberately absent per-test path, while tests that need broker configuration can override it.
Wall-clock test change
The close-delay allowance changed from timeout_s + 8 to timeout_s + 15. This is a test-only adjustment for observed suite load; it still rejects the original roughly 2× timeout failure mode (40 seconds against a 35-second limit in the test's 20-second scenario). The previously failing scenario now passes in an isolated rerun, and the remote acceptance test also passes. The wider allowance is a reasonable host-load calibration, though future runs should retain the measured close-delay evidence rather than relying on the assertion alone.
Verification
All tests were run in the requested detached worktree with its .venv/bin/python, PYTHONDONTWRITEBYTECODE=1, and pytest -p no:cacheprovider.
- Delta-focused suites (
test_issue21_phase2_loop_a.py,test_issue21_loop_b.py,test_issue21_acceptance.py,test_issue21_worktree_prereqs.py,test_issue5_phase1_delegation.py,test_workspace_scope.py,test_deploy_freshness.py,test_version_consistency.py): 209 passed in 323.16 s. Asset-dependent freshness tests skip because this checkout has nonats-dockerassets; this is the intended skip condition. - Isolated wall-clock close and remote acceptance rerun: 2 passed in 49.79 s.
bash -non all eight changed shell files: passed.git diff --check 1134d74...HEAD: passed.- Direct snapshots before/after testing found no new entries in either checkout's real
.mam/jobsor.mam/delegate_job_logs.
The known release prerequisite remains outside this delta: the orchestrator must perform the 4.7.0 version lockstep bump and release entry before merge. Main stayed at 1134d74; the review worktree stayed at 80a5614; no source, checkout, production registry, monitor, or session state was modified.
[VERDICT: PASS]