Files
multi-agent-mux/.agents/reports/reviewer-grok-01/report-9cd9b3f0.md
T
GodopuandClaude Opus 5.5 50c8da8269 release(v4.9.1): tests no longer reach a real herdr server - archive the review reports and bump the lockstep version
Review loop (--review-only, --all-reviewer): round 1 (@325b056) 4/4 PASS,
round 2 (@db7f4ca, HERDR_SESSION) 4/4 PASS. Full suite at 325b056 on
macOS / Python 3.9 / bash 3.2 / herdr 0.9.3 from an agent pane:
1845 passed / 0 failed / 56 skipped (18 test_deploy_freshness skips: no
nats-docker submodule in the fresh worktree); the panes of the real
servers (default, multi-agent-mux) and ~/.claude/projects were unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
2026-10-13 10:33:04 +09:00

4.0 KiB
Raw Blame History

Review 9cd9b3f0 — the sandbox also drops HERDR_SESSION

Head db7f4cab9c60ff5db009cf3fc625e9a86a465ef6 (tree f32cabd3a6c8d775c9223509967f1a810f0cf827) is the one commit db7f4ca test(sandbox): mam_sandbox also drops HERDR_SESSION on base 325b056057fcdd717d2c81017fc5ef57183cb4d0. Two files, +5/−1. git diff --check is clean. Snapshot porcelain empty. Control-plane main is still 8b0b4a07dc76a4915895bdde6170dc8eed9b5f74, porcelain empty.

mam_sandbox deletes HERDR_SESSION next to HERDR_SOCKET_PATH (tests/conftest.py:298-299). L2's pane model now includes HERDR_SESSION=real (tests/test_herdr_real_server_leak.py:73-76) and asserts that name is gone with the others (:86-88).

What the variable does inside a sandbox

The herdr binary treats HERDR_SESSION as a session name: the string beside it is session name cannot be empty. A named session's socket is $HOME/.config/herdr/sessions/<name>/herdr.sock. mam_sandbox sets HOME to the sandbox, so that name resolves inside the sandbox. The route that reached the caller's real server was HERDR_SOCKET_PATH, which the previous commit already deletes.

_herdr_caller_server (lib.sh:1424-1427), pane_lock.caller_server (lib_py/pane_lock.py:44-50), and watcher.caller_server (lib_py/loop/watcher.py:50-66) return HERDR_SESSION whenever it is set, ahead of the socket. A test run inside a pane therefore took the in-pane branch, and the same test outside a pane took the other. Dropping the variable makes those helpers see a process outside a pane unless the test supplies the name itself.

Tests that supply the name

No test calls monkeypatch.setenv("HERDR_SESSION"). The tests that need a value build the child environment themselves:

  • tests/test_issue23_24_startup_path.py _run_lib (:36-40) pops HERDR_SESSION from the inherited environment and then applies the dict the test passes. test_s1g passes HERDR_SESSION=from-herdr and expects caller=from-herdr.
  • tests/test_issue34_job_tree.py _run_lib (:590-591) drops every HERDR_* name and then applies SAME_SERVER_PANE, which contains HERDR_SESSION=multi-agent-mux.
  • tests/test_issue50_pane_lock.py passes an explicit mapping into lock_path and into the pane_lock path subprocess. test_p1b builds that subprocess environment from the keys that do not start with HERDR_, then adds the socket it wants.

A direct call of mam_sandbox with HERDR_SESSION=probe-session left the name unset. A setenv after that call left HERDR_SESSION=set-by-test. The fixture setup runs before the test body, so a test that sets the name for itself keeps it. The one setenv of a HERDR_ name in a test body is HERDR_SERVER_NAME in tests/test_tier3_integration.py:31, and that line runs after the fixture.

What the sandbox still leaves

HERDR_ENV stays. In this pane its value is 1. The binary's text says Requires HERDR_ENV=1 beside the inception check, so this is a feature flag. HERDR_BIN_PATH stays, and its value names the herdr binary. HERDR_CLIENT_SOCKET_PATH sits beside HERDR_SOCKET_PATH in the binary's pane-export cluster. This process does not have that name, and the sandbox does not delete it.

What was run

Control-plane venv, Python 3.9.6, pytest 8.4.2, PYTHONDONTWRITEBYTECODE=1, -p no:cacheprovider, --basetemp=/tmp/m9cdbt. Inherited HERDR_SOCKET_PATH, HERDR_PANE_ID, HERDR_TAB_ID, HERDR_WORKSPACE_ID, HERDR_SESSION_NAME, HERDR_SESSION, HERDR_SERVER_NAME, HERDR_CONFIG_PATH, HERDR_ENV, HERDR_BIN_PATH, WORKSPACE_ROOT, MAM_ENV_FILE, HOME_DIR, CLAUDE_PROJECT_DIR, and CODEX_HOME were unset. The real herdr binary was not run.

tests/test_herdr_real_server_leak.py, tests/test_issue23_24_startup_path.py, and tests/test_issue50_pane_lock.py: 84 passed in 195.84s. That is the same 84 the orchestrator reported. The session guards on that run completed. The #55 agent-home guard did not fire.

User ~/.config/herdr/config.toml mtime stayed 1784456394. Snapshot porcelain stayed empty after the run.

[VERDICT: PASS]