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
6.6 KiB
Review Report — PR #58 (Issue #57: Audit logs follow a moved registry)
- Reviewer:
agy(herdr:reviewer-agy-01) - Job ID:
d61d1344 - Branch / Range:
fix/issue-57(e32c9574644a9185813a4dc881812694d62b6204..63d816468e6d48d01bd96f31d8a25eeadfbaab60, 11 commits, 21 files) - Verification Worktree:
/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261014T152849Z-f1a415/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 #58 resolves Issue #57 by establishing a single source of truth (mqtt_common.get_logs_dir(registry_dir) and mqtt_common.sibling_logs_dir(registry_dir)) so that moving the job registry via --registry-dir or MAM_JOBS_DIR moves its sibling delegate_job_logs audit trail as well, unless DELEGATE_JOB_LOGS_DIR is explicitly set. It also fixes the job_subscriber._check_disk_fallback bug where the status.json dict was compared directly against status strings instead of extracting .get("status"), while guarding versioned records against stale audit statuses from prior attempts via transition_seq comparison. Furthermore, per §2-B (c57e766), control_plane.forwarded_keys() omits delegate_job_logs_dir from pane --env forwarding whenever it is the derivable sibling of mam_jobs_dir, allowing --registry-dir inside a forwarded worktree pane to relocate both the registry and its audit log cleanly.
All 21 modified files pass Python 3.9.6 AST/syntax checks and Bash 3.2 (set -u) syntax checks, and all 135 targeted tests across 5 test suites pass on macOS without leaving any artifacts in the verification worktree or real control plane.
2. macOS / Python 3.9 / Bash 3.2 Compatibility Verification
-
Python 3.9 Compatibility (
/usr/bin/python33.9.6):- All 13 modified/added Python files (
control_plane.py,engine.py,job_subscriber.py,mqtt_common.py,publish_event.py,registry.py,remote.py,runner.py, and the 5 test modules) parse cleanly under/usr/bin/python33.9.6 (ast.parse). - No Python 3.10+ runtime union syntax (
X | Y),match/case,tomllib, or 3.11-only stdlib APIs are used withoutfrom __future__ import annotations.
- All 13 modified/added Python files (
-
Bash 3.2 +
set -uSafety (/bin/bash3.2.57):- All 5 modified shell scripts (
lib.sh,worktree_prepare.sh,multi-agent-mux-delegate-job,reconcile.sh,status.sh) pass/bin/bash -n. - In
multi-agent-mux-delegate-job:LOGS_DIR_ABS=""is initialized at the top level before functions run underset -euo pipefail, andcmd_submitresolves it fail-closed (LOGS_DIR_ABS="$(_logs_dir_abs)" || { ... exit 1; }) and exportsDELEGATE_JOB_LOGS_DIR="$LOGS_DIR_ABS".cmd_logsuses scalar locals (local reg="$REGISTRY_DIR_DEFAULT" jid="" list=0) instead of potentially empty arrays, avoiding Bash 3.2's unbound-variable failure on empty array expansion underset -u.
- In
.agents/skills/lib.shandworktree_prepare.sh:${DELEGATE_JOB_LOGS_DIR:-}and${MAM_JOBS_DIR:+$(dirname "$MAM_JOBS_DIR")/delegate_job_logs}are safely guarded forset -u.
- All 5 modified shell scripts (
-
macOS Symlink Normalization (
/tmp->/private/tmp,/var->/private/var):control_plane._abs(p)normalizes paths viaos.path.realpath(os.path.expanduser(p)).- Both
from_env()(b["delegate_job_logs_dir"] = _abs(mqtt_common.sibling_logs_dir(b["mam_jobs_dir"]))) andforwarded_keys()(desc.get("delegate_job_logs_dir") == _abs(mqtt_common.sibling_logs_dir(desc["mam_jobs_dir"]))) apply_abs(), ensuring symlinked macOS temporary directories (tmp_pathunder/var/folders/...vs/private/var/folders/...) compare equal. tests/test_issue57_logs_follow_registry.pyconsistently usesos.path.realpathwhen comparing paths resolved by_logs_dir_absorcontrol_plane.
3. Functional & Architectural Review
- Resolver & Single Source of Truth (
mqtt_common.py):sibling_logs_dir(registry_dir)purely computesos.path.join(os.path.dirname(os.path.abspath(registry_dir)), "delegate_job_logs").get_logs_dir(registry_dir=None)honorsDELEGATE_JOB_LOGS_DIRwhen non-empty, and otherwise delegates tosibling_logs_dir(registry_dir or default_registry_dir()).- PEP 562 module
__getattr__("LOGS_DIR")remains intact for backwards compatibility.
- Engine, Registry, Subscriber, Publisher, Remote, Runner:
engine.pythreadsregistry_dirinto_flush(notes, registry_dir)and_append_conflict_refused(..., registry_dir), ensuring conflict refusals and post-commit audit mirrors write next to the active registry.registry.pythreadslogs = mqtt_common.get_logs_dir(registry_dir)throughregister_job, legacypick_pending(MAM_ENGINE_CAS=0),get_feedback, and CLIlogs.job_subscriber._check_disk_fallbackreadslogged = mqtt_common.read_logged_status(jid, mqtt_common.get_logs_dir(registry_dir)), checksstale = rec_seq is not None and (aud_seq is None or int(aud_seq) < int(rec_seq))(catching(TypeError, ValueError)asstale = True), and extractsdisk_status = logged.get("status")only when not stale.
- Control Plane & Session Forwarding (
control_plane.py,worktree_prepare.sh,status.sh):control_plane.from_env()derivesdelegate_job_logs_dirfrommam_jobs_dirwhenDELEGATE_JOB_LOGS_DIRis unset.control_plane.forwarded_keys()omitsdelegate_job_logs_dirwhen it equals_abs(mqtt_common.sibling_logs_dir(desc["mam_jobs_dir"])), so the row still records all 4 keys while the pane only receivesDELEGATE_JOB_LOGS_DIRif it was explicitly set to a non-sibling location.worktree_prepare.shonly forwardsDELEGATE_JOB_LOGS_DIRintorun_cmdwhen explicitly set in the caller's environment.status.shcheckssibling_logs_dir(r)for bothMAM_JOBS_DIRandcp.get("mam_jobs_dir").
4. Test Execution Summary
Executed in /var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261014T152849Z-f1a415/1 with HERDR_*, WORKSPACE_ROOT, MAM_ENV_FILE, MAM_JOBS_DIR, and DELEGATE_JOB_LOGS_DIR scrubbed, PYTHONDONTWRITEBYTECODE=1, -p no:cacheprovider, and --basetemp=/tmp/mam_verify_pr58_bt:
tests/test_issue57_logs_follow_registry.py: 12 passedtests/test_issue15_registry_isolation.py: 20 passedtests/test_issue21_worktree_prereqs.py: 27 passedtests/test_issue21_acceptance.py: 9 passedtests/test_tier1_unit.py: 67 passed
Total: 135 passed, 0 failed. Verification worktree git status -s is empty and no .mam directory was created.
[VERDICT: PASS]