Files
multi-agent-mux/.agents/reports/reviewer-agy-01/report-d61d1344.md
T
GodopuandClaude Opus 5.5 7cf728e9f8 release(v4.9.4): the audit log follows a moved registry (Issue #57, PR #58) - archive the review reports and bump the lockstep version
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
2026-10-15 22:52:04 +09:00

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/python3 3.9.6, .venv/bin/python 3.9.6, /bin/bash 3.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

  1. Python 3.9 Compatibility (/usr/bin/python3 3.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/python3 3.9.6 (ast.parse).
    • No Python 3.10+ runtime union syntax (X | Y), match/case, tomllib, or 3.11-only stdlib APIs are used without from __future__ import annotations.
  2. Bash 3.2 + set -u Safety (/bin/bash 3.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 under set -euo pipefail, and cmd_submit resolves it fail-closed (LOGS_DIR_ABS="$(_logs_dir_abs)" || { ... exit 1; }) and exports DELEGATE_JOB_LOGS_DIR="$LOGS_DIR_ABS".
      • cmd_logs uses 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 under set -u.
    • In .agents/skills/lib.sh and worktree_prepare.sh:
      • ${DELEGATE_JOB_LOGS_DIR:-} and ${MAM_JOBS_DIR:+$(dirname "$MAM_JOBS_DIR")/delegate_job_logs} are safely guarded for set -u.
  3. macOS Symlink Normalization (/tmp -> /private/tmp, /var -> /private/var):

    • control_plane._abs(p) normalizes paths via os.path.realpath(os.path.expanduser(p)).
    • Both from_env() (b["delegate_job_logs_dir"] = _abs(mqtt_common.sibling_logs_dir(b["mam_jobs_dir"]))) and forwarded_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_path under /var/folders/... vs /private/var/folders/...) compare equal.
    • tests/test_issue57_logs_follow_registry.py consistently uses os.path.realpath when comparing paths resolved by _logs_dir_abs or control_plane.

3. Functional & Architectural Review

  • Resolver & Single Source of Truth (mqtt_common.py):
    • sibling_logs_dir(registry_dir) purely computes os.path.join(os.path.dirname(os.path.abspath(registry_dir)), "delegate_job_logs").
    • get_logs_dir(registry_dir=None) honors DELEGATE_JOB_LOGS_DIR when non-empty, and otherwise delegates to sibling_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.py threads registry_dir into _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.py threads logs = mqtt_common.get_logs_dir(registry_dir) through register_job, legacy pick_pending (MAM_ENGINE_CAS=0), get_feedback, and CLI logs.
    • job_subscriber._check_disk_fallback reads logged = mqtt_common.read_logged_status(jid, mqtt_common.get_logs_dir(registry_dir)), checks stale = rec_seq is not None and (aud_seq is None or int(aud_seq) < int(rec_seq)) (catching (TypeError, ValueError) as stale = True), and extracts disk_status = logged.get("status") only when not stale.
  • Control Plane & Session Forwarding (control_plane.py, worktree_prepare.sh, status.sh):
    • control_plane.from_env() derives delegate_job_logs_dir from mam_jobs_dir when DELEGATE_JOB_LOGS_DIR is unset.
    • control_plane.forwarded_keys() omits delegate_job_logs_dir when it equals _abs(mqtt_common.sibling_logs_dir(desc["mam_jobs_dir"])), so the row still records all 4 keys while the pane only receives DELEGATE_JOB_LOGS_DIR if it was explicitly set to a non-sibling location.
    • worktree_prepare.sh only forwards DELEGATE_JOB_LOGS_DIR into run_cmd when explicitly set in the caller's environment.
    • status.sh checks sibling_logs_dir(r) for both MAM_JOBS_DIR and cp.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 passed
  • tests/test_issue15_registry_isolation.py: 20 passed
  • tests/test_issue21_worktree_prereqs.py: 27 passed
  • tests/test_issue21_acceptance.py: 9 passed
  • tests/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]