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
36 lines
4.0 KiB
Markdown
36 lines
4.0 KiB
Markdown
# 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]
|