# Review: Issue #17 workspace root @ d198dd5 - Role: Reviewer (grok) - Identity: loop `loop-20261008T133858Z-9e7f5b`, snapshot `/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261008T133858Z-9e7f5b/1`, base `6b00b6e06f55299cb60f156ccef09ede4bae5bdd` (main still `6b00b6e`), head `d198dd50aaf6119dc21f36d88704e64850e67413`, tree `114ec21d3fc7de8932f5e1d34f895edd24ad7c01`. One commit, `tests/test_issue17_item4_decisions.py` only, +36/−2. `git diff --check` clean. Snapshot porcelain empty after the runs. No version bump. - Verified read-only at the snapshot. Python 3.9.6 from the `issue17-wsroot` worktree `.venv`, bash 3.2.57. Inherited `HERDR_*`, `MAM_*`, and `MQTT_*` were unset. `.mam.env` was not exported. `started` for this dispatch is `dispatch_verified` with attempt-id 1. - Product code under `.agents/skills` is unchanged. `lib.sh` still installs the herdr shim when it is sourced (`lib.sh:143`, called at `:3088`). Aiming that write at a temp directory belongs in the test environment. ## What this commit does `_env` (`tests/test_issue17_item4_decisions.py:224-233`) drops an inherited `WORKSPACE_ROOT` and sets it to the helper's `tmp_path`. The comment matches `lib.sh:26`: with the variable unset, the library sets `WORKSPACE_ROOT` to the checkout that contains `lib.sh` and the source still rewrites that checkout's `.mam/shim/herdr`. At `6b00b6e` the same helper kept every inherited `WORKSPACE_ROOT` (`git show 6b00b6e:tests/test_issue17_item4_decisions.py`, the old `:224-229`). Sourcing the wrapper with that filter and `WORKSPACE_ROOT` pointed at `/tmp/0a8aprobe.DcRQYA/sentinel` created `.mam/shim/herdr` under the sentinel. The head filter, pointed at the test directory, left a second sentinel empty and wrote `.mam/shim/herdr` under that test directory. `test_c_helpers_write_nothing_to_an_inherited_workspace` (`:477-498`) is that check: a monkeypatched sentinel stays empty, the checkout shim's mtime stays put, `_run_both` still sees `ws=`, and the direct source sees the test directory. The checkout shim was absent before these runs and is still absent. `_human_submit` (`:692-696`) already set `WORKSPACE_ROOT` to its `tmp_path`. Callers that pass `WORKSPACE_ROOT` through `extra` still override the default (`:232`). ## Why this file was outside the common fixture `pytest_configure` (`tests/conftest.py:144-146`) drops `WORKSPACE_ROOT` only when its real path is some other checkout. A value that names this checkout stays. The autouse fixture (`:161-177`) sets `MAM_JOBS_DIR`, `DELEGATE_JOB_LOGS_DIR`, and `MAM_ENV_FILE`, and leaves `WORKSPACE_ROOT` alone. `mam_sandbox` (`:215`) does set it to the sandbox, and these helpers do not use that fixture. `_env` copies `os.environ` into the bash that sources the wrapper, so a root conftest kept is the directory `lib.sh` rewrites. ## Same defect left in place Each of these copies `os.environ` (or passes no `env`, so the child inherits it) and sources `lib.sh` or the wrapper without setting `WORKSPACE_ROOT` to a temp directory. A probe of the `test_version_consistency.py:134` shape, with `WORKSPACE_ROOT` on a sentinel, created `.mam/shim/herdr` there. | Location | What it does | |---|---| | `tests/test_version_consistency.py:29-31` and `:134-136` | Sources `lib.sh` to print `MAM_VERSION`. The second call copies `os.environ` and only replaces `MAM_VERSION`. | | `tests/test_b19_headless_reconcile_fixes.py:125-134` | Copies `os.environ` and sources `lib.sh`. The later `_init_herdr_isolation() { :; }` runs after `lib.sh:3088` has already written the shim. | | `tests/test_b8_send_keys_verification.py:11` and `:32` | The script sources `lib.sh`. `subprocess.run` passes no `env`. | | `tests/test_issue6_fail_closed.py:1241-1244` | Sources `.agents/skills/lib.sh` with the process environment and `cwd` set to the repo. | | `tests/test_orc_onboard.py:15-18`, `:33-42`, `:46-56`, `:60-65` | `SCRUBBED_ENV` copies `os.environ` at import. The find, verify, and dump helpers source `lib.sh` without assigning `WORKSPACE_ROOT`. | | `tests/test_issue21_worktree_prereqs.py:544-546` | `_mutate` sources that temp tree's `lib.sh` with the process environment. An inherited `WORKSPACE_ROOT` is where the shim is written. | Apply the same two assignments `_env` now makes: drop `WORKSPACE_ROOT` from the copied environment and set it to that test's temporary directory before the `source`. ## Surveyed, and already aimed at a temp directory These copy `os.environ` and source `lib.sh` or the wrapper, and they assign `WORKSPACE_ROOT` to the test directory (or to a sandbox the fixture already set): - `tests/test_issue33_budget.py:47` - `tests/test_issue18_liveness_contract.py:58` - `tests/test_issue14_delivery_ack.py:36` - `tests/test_issue26_envfile.py:76` - `tests/test_issue26_ints.py:124` - `tests/test_issue6_turn_handshake.py:28-29` (every call passes `cwd`, and the helper then sets `WORKSPACE_ROOT` to that `cwd`) - `tests/test_c1_tui_readiness.py:19` - `tests/test_layout.py:318` - `tests/test_issue21_phase2_loop_a.py:49` and `:59` - `tests/test_issue19_subscriber_daemon_lifecycle.py:53` — its only caller (`:138`) uses `mam_sandbox`, which has already set `WORKSPACE_ROOT` to that sandbox - `tests/test_issue34_job_tree.py:590` — same, the callers pass `mam_sandbox` `tests/test_issue20_state_isolation.py:150` and `:201` set `WORKSPACE_ROOT` on purpose and assert what that root receives. `tests/test_issue17_item4_decisions.py:172` runs `python -m lib_py.delegation.wrapper`, which does not install the shim. `:465` sources `lib_int.sh` only. ## Tests `--basetemp=/tmp/0a8aA.2zJF3l`. The process started with `WORKSPACE_ROOT` equal to that basetemp; `conftest.py:144-146` drops it because it is not this checkout, so the tests ran with the variable unset. `tests/test_issue17_item4_decisions.py`, `tests/test_issue33_budget.py`, `tests/test_issue5_phase1_delegation.py`, `tests/test_tier1_unit.py`: **443 passed** in 466.90 s. `--basetemp=/tmp/0a8aB.XgggUw`, outer `WORKSPACE_ROOT=/tmp/0a8asent.7l9EpB`. `tests/test_issue17_item4_decisions.py`: **290 passed** in 319.77 s. The outer sentinel was empty afterwards. `conftest.py:144-146` also drops that foreign root before collection, so the outer variable is not what `_env` sees. The check that reaches `_env` is `test_c_helpers_write_nothing_to_an_inherited_workspace`, which passed in both runs, together with the direct probe above. [VERDICT: NOT PASS]