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
This commit is contained in:
1 parent
db7f4cab9c
commit
50c8da8269
32 files changed
+607
-26
No files matched your search
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"loop_id": "loop-20261013T010208Z-f90dd4",
|
||||
"base_sha": "325b056057fcdd717d2c81017fc5ef57183cb4d0",
|
||||
"head_sha": "db7f4cab9c60ff5db009cf3fc625e9a86a465ef6",
|
||||
"tree_sha": "f32cabd3a6c8d775c9223509967f1a810f0cf827",
|
||||
"review_commit": "db7f4cab9c60ff5db009cf3fc625e9a86a465ef6",
|
||||
"reviewer": "planner-reviewer-codex-01",
|
||||
"job_id": "b1696427",
|
||||
"verdict": "PASS",
|
||||
"transport": "herdr",
|
||||
"evidence": "review-tree",
|
||||
"isolation": "worktree",
|
||||
"verified_at": "2026-10-13T01:21:50Z"
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
# Job b1696427 — HERDR_SESSION isolation review
|
||||
|
||||
판정: PASS. 지정된 두 파일 변경에서 차단할 결함을 발견하지 않았다. 관련 테스트 **84건 모두 통과**했고, 별도 base/head 탐침에서 상속 세션 제거와 fixture 이후의 명시적 설정 보존을 확인했다.
|
||||
|
||||
## 검증 identity
|
||||
|
||||
- loop: `loop-20261013T010208Z-f90dd4`
|
||||
- base: `325b056057fcdd717d2c81017fc5ef57183cb4d0`
|
||||
- head: `db7f4cab9c60ff5db009cf3fc625e9a86a465ef6`
|
||||
- tree: `f32cabd3a6c8d775c9223509967f1a810f0cf827`
|
||||
- 검증 cwd: `/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261013T010208Z-f90dd4/1`
|
||||
- Python: `/Users/godopu16/PuKi/laa/canary_projects/multi-agent-mux/.venv/bin/python`
|
||||
|
||||
HEAD/tree가 지정 identity와 일치하고 `git status --short`는 비어 있었다. `git diff --check 325b056`도 통과했다. 이 커밋만 검토했으며 운영 코드·생성 shim 변경은 없다. 소스 수정, creator 작업 트리 실행, 커밋·push는 하지 않았다.
|
||||
|
||||
## 코드 검토
|
||||
|
||||
1. `tests/conftest.py:298–301`에서 기존 socket/pane/tab 제거 사이에 `monkeypatch.delenv("HERDR_SESSION", raising=False)`를 추가한 것은 적절하다. 값이 없는 실행도 허용하고, pytest monkeypatch의 기존 복원 수명 주기를 따른다. `.agents/skills/lib.sh:1425–1427`, `lib_py/pane_lock.py:49–50`, `lib_py/loop/watcher.py:64–66`은 이 값을 우선해서 caller server로 읽으므로 sandbox 시작 전에 상속값을 제거해야 pane 안/밖의 기본 분기가 같아진다.
|
||||
2. `tests/test_herdr_real_server_leak.py:73–88`은 새 변수를 가짜 pane 환경에 넣은 뒤 실제 `mam_sandbox` 이후 남지 않는지 확인한다. 외부 실행 환경을 미리 scrub했더라도 시험이 스스로 값을 주입하므로 추가된 제거 동작을 검증한다.
|
||||
3. 테스트가 의도적으로 지정하는 값은 보존된다. `test_issue23_24_startup_path.py:31–42`의 helper는 fixture 이후 subprocess 환경을 구성하고 명시적 `env`를 마지막에 적용한다. `:261–266`의 HERDR_SESSION 우선순위 시험을 포함한 모듈이 통과했다. `test_issue50_pane_lock.py:63–80`도 명시적인 환경 mapping으로 caller/lock 식별을 검사한다. 추가 탐침에서도 fixture 이후 설정한 값이 두 helper에 그대로 전달됐다.
|
||||
4. 확인한 라우팅·범위 변수 `HERDR_SESSION`, `HERDR_SESSION_NAME`, `HERDR_SERVER_NAME`, `HERDR_WORKSPACE_ID`, `HERDR_SOCKET_PATH`, `HERDR_PANE_ID`, `HERDR_TAB_ID`와 설정 경로 `HERDR_CONFIG_PATH`, `XDG_CONFIG_HOME`은 모두 `conftest.py:290–306`에서 제거된다. 실제 fixture setup에 이 9개를 주입한 독립 탐침에서도 head에는 하나도 남지 않았다. 검사한 repository의 caller/scope/config 경로에서 추가 누락 라우팅 변수는 찾지 못했다. 이는 알려진 경로의 검증이며 임의의 미래 herdr 환경변수까지 일괄 제거한다는 의미는 아니다.
|
||||
|
||||
`mam_sandbox`를 사용하지 않는 테스트의 환경 계약은 이 두 파일 변경으로 바뀌지 않는다. 예를 들어 실제 서버용 `test_issue50_dispatch_herdr.py`는 모든 HERDR_*를 별도로 제거하고, `test_issue45_restore.py`의 Rig도 HERDR_SESSION을 포함한 scope 변수를 자체 제거한다. 이 실제 서버 모듈은 이번 리뷰에서 실행하지 않았다.
|
||||
|
||||
## 실행 검증
|
||||
|
||||
안전 launcher `/tmp/b1696427-review/run.py`를 사용해 아래 관련 모듈만 실행했다.
|
||||
|
||||
```text
|
||||
env -u HERDR_SOCKET_PATH -u HERDR_PANE_ID -u HERDR_TAB_ID -u HERDR_WORKSPACE_ID -u HERDR_SESSION_NAME -u HERDR_SESSION -u WORKSPACE_ROOT -u MAM_ENV_FILE <Python> /tmp/b1696427-review/run.py tests/test_herdr_real_server_leak.py tests/test_issue50_pane_lock.py tests/test_issue23_24_startup_path.py
|
||||
```
|
||||
|
||||
- **84 passed in 195.48s**, exit 0. skip/failure 없음.
|
||||
- 로그: `/tmp/b1696427-review/tests.log`
|
||||
- basetemp: `/tmp/b1696427-mxmhd4h3/bt` — 검증 트리 밖이며 이름에 shim 없음.
|
||||
- `PYTHONDONTWRITEBYTECODE=1`, `-p no:cacheprovider`, 일회용 HOME, 지정 AGENT_PYTHON_BIN 사용.
|
||||
- launcher는 상속 HERDR_*/MAM_*/MQTT_*/SKS_* 및 제어·에이전트 경로 환경을 추가로 제거했다. 실제 설치 herdr에 도달하기 전에 기록 후 exit 97로 중단하는 fallback 디코이를 PATH에 두었다. **fallback 호출 기록 없음.** 테스트별 mock과 suite의 로컬 broker를 사용했다.
|
||||
- 전체 스위트, 실제 herdr, 운영 모니터·서버는 실행하지 않았다. `.mam.env` export/출력이나 실제 사용자 에이전트 홈 변경도 하지 않았다.
|
||||
|
||||
## 독립 base/head 탐침
|
||||
|
||||
산출물: `/tmp/b1696427-review/probe.py`, `/tmp/b1696427-review/probe.log`.
|
||||
|
||||
재현은 위와 같은 `env -u ...` 및 `PYTHONDONTWRITEBYTECODE=1`로 지정 Python에서 probe.py를 실행한다. 검증 트리의 git base와 head에서 `mam_sandbox` 함수 AST를 추출해 pytest decorator만 제거하고, 실제 함수 본문을 별도 `/tmp` 디렉터리에 실행했다. `pytest.MonkeyPatch`를 사용하고, 이 setup에서 시작하는 데몬이 없으므로 등록되는 reaper finalizer는 실행하지 않았다. 서버를 실행하는 코드는 호출하지 않았다.
|
||||
|
||||
절차와 결과:
|
||||
|
||||
1. fixture 전에 위 9개 변수에 안전한 sentinel 값을 주입한다.
|
||||
2. base fixture 실행 후 남은 변수는 `HERDR_SESSION` 하나이고 값은 `caller-sentinel`이었다. 실제 Python `pane_lock.caller_server`와 검증 트리에서 추출한 셸 `_herdr_caller_server` 모두 `caller-sentinel`을 반환했다.
|
||||
3. head fixture 실행 후 남은 변수는 없었다. 두 helper 모두 빈 값을 반환했다. 기대한 기본 호출자 분기 복원이 확인됐다.
|
||||
4. 각 fixture 실행 뒤 `HERDR_SESSION=chosen-by-test`를 설정하면 두 helper 모두 `chosen-by-test`를 반환했다. 명시적 테스트 설정은 제거되지 않는다.
|
||||
|
||||
탐침 exit 0, 모든 assertion 통과. 임시 root는 `/tmp/b1696427-probe-6o1gbryi`였다. 이전 리뷰의 결과를 현재 커밋 검증으로 대체하지 않고 이번 identity에서 새로 실행했다.
|
||||
|
||||
[VERDICT: PASS]
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"loop_id": "loop-20261013T001819Z-131fa6",
|
||||
"base_sha": "8b0b4a07dc76a4915895bdde6170dc8eed9b5f74",
|
||||
"head_sha": "325b056057fcdd717d2c81017fc5ef57183cb4d0",
|
||||
"tree_sha": "7905896f005159d596e3872d0ee2c3c12061f09a",
|
||||
"review_commit": "325b056057fcdd717d2c81017fc5ef57183cb4d0",
|
||||
"reviewer": "planner-reviewer-codex-01",
|
||||
"job_id": "efb52908",
|
||||
"verdict": "PASS",
|
||||
"transport": "herdr",
|
||||
"evidence": "review-tree",
|
||||
"isolation": "worktree",
|
||||
"verified_at": "2026-10-13T00:57:46Z"
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
# Job efb52908 — herdr leak fix review
|
||||
|
||||
판정: PASS. 지정된 2개 커밋/4개 파일에서 이번 변경을 차단할 결함은 발견하지 않았다. 관련 테스트 **105 passed, 1 deselected**이고, base/head 디코이 탐침으로 경로 선택 수정과 기존 래퍼 제외 동작을 확인했다. 아래 기존 해석기 차이와 운영상 한계는 이번 변경의 회귀와 구분한다.
|
||||
|
||||
## 검증 identity 및 범위
|
||||
|
||||
- loop: `loop-20261013T001819Z-131fa6`
|
||||
- base: `8b0b4a07dc76a4915895bdde6170dc8eed9b5f74`
|
||||
- head: `325b056057fcdd717d2c81017fc5ef57183cb4d0`
|
||||
- tree: `7905896f005159d596e3872d0ee2c3c12061f09a`
|
||||
- 검증 cwd: `/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261013T001819Z-131fa6/1`
|
||||
- Python: `/Users/godopu16/PuKi/laa/canary_projects/multi-agent-mux/.venv/bin/python`
|
||||
|
||||
검증 종료 시에도 HEAD/tree가 위 identity와 일치하고 `git status --short`는 비어 있었다. `git diff --check <base>`와 `/bin/bash -n .agents/skills/lib.sh` 모두 통과했다. 리뷰 소스 수정, creator 작업 트리 실행, 커밋·push는 하지 않았다.
|
||||
|
||||
## 변경 검토
|
||||
|
||||
### L1: 조상 디렉터리 이름 때문에 mock이 가려지는 문제
|
||||
|
||||
`.agents/skills/lib.sh:113–124`는 일반 `*-shim` 제외를 디렉터리 자체의 접미사로 제한한다. `:132`에서 PATH 디렉터리를 검사하고, `:134–136`에서는 심볼릭 링크 해석 후 후보 파일의 **dirname**을 검사한다. 따라서 파일 이름 `herdr` 때문에 접미사 검사가 무력화되지 않고, wrapper를 가리키는 링크도 기존처럼 제외된다. 생성 shim의 `:172–176`도 일반 접미사 조건을 같은 방향으로 좁힌다.
|
||||
|
||||
검증 트리의 base와 head에서 해당 함수 본문만 추출해 `/bin/bash`로 실행했다. PATH 후보는 모두 `/tmp`에 만든 디코이이며 실제 herdr는 후보에 없었다.
|
||||
|
||||
| 후보 위치 | base 결과 | head 결과 |
|
||||
|---|---|---|
|
||||
| `pytest-x-shim/case/bin/herdr` | 두 해석기 모두 후보를 건너뛰고 다음 디코이 선택 | 두 해석기 모두 첫 후보 선택 |
|
||||
| `herdr-shim/herdr` | 두 해석기 모두 제외 | 두 해석기 모두 제외 |
|
||||
| `.mam/shim/herdr` | 두 해석기 모두 제외 | 두 해석기 모두 제외 |
|
||||
| `multi-agent-herdr-shim/herdr` | 두 해석기 모두 제외 | 두 해석기 모두 제외 |
|
||||
| `.agents/skills/.bin/herdr` | lib 해석기는 제외; 생성 shim은 선택 | 동일: lib 해석기는 제외; 생성 shim은 선택 |
|
||||
|
||||
추가로 lib 해석기에서 일반 `front/herdr` 심볼릭 링크가 `wrapped-shim/herdr` 또는 `.agents/skills/.bin/herdr`를 가리키면 제외됨을 확인했다. 링크 대상이 `parent-shim/bin/herdr`이면 허용됐다. 조상 이름과 wrapper 자체의 이름을 구분하려는 변경에 부합한다.
|
||||
|
||||
### L2: pane 라우팅 환경 격리
|
||||
|
||||
`tests/conftest.py:290–303`에서 기존 세션 이름·workspace·config 격리에 socket/pane/tab 삭제가 추가됐다. `tests/test_herdr_real_server_leak.py:73–87`은 안전한 가짜 socket 값과 pane 변수를 먼저 주입하고 `mam_sandbox` 이후 남지 않는지 검증하며 통과했다. 바깥 실행 환경을 미리 정리했더라도 이 시험은 자체적으로 오염 환경을 다시 만들어 검사한다.
|
||||
|
||||
브리프에 기록된 실제 herdr의 socket 우선순위 실측과 일치하는 수정이다. 이번 리뷰에서는 운영 서버 접촉을 금지한 조건에 따라 실제 서버 라우팅을 재현하지 않았다. 따라서 socket 우선순위의 실서버 증거는 브리프의 실측이고, 본 리뷰의 독립 증거는 fixture 삭제 동작 및 디코이 호출 경로 검증이다.
|
||||
|
||||
### mam_sandbox 밖의 경로와 HERDR_SESSION
|
||||
|
||||
삭제 범위는 `mam_sandbox`를 사용하는 시험에 한정된다. 검토한 비-sandbox 경로에서 이번 사고와 같은 추가 실제 서버 변경 경로는 찾지 못했다.
|
||||
|
||||
- `tests/test_issue50_dispatch_herdr.py:73–85`의 실제 서버용 Box 환경은 모든 `HERDR_*`를 제거하고 일회용 HOME/서버를 지정한다.
|
||||
- `tests/test_issue45_restore.py:41–57`의 Rig는 socket/pane/tab/workspace 및 `HERDR_SESSION`, config 관련 값을 제거한다. 이 실서버 모듈들은 이번 리뷰에서 실행하지 않고 코드만 확인했다.
|
||||
- `tests/test_issue17_item4_decisions.py:224–233`은 별도 환경 구성에서 `HERDR_*` 전체를 제거한다. 다른 비-sandbox 단위 시험은 in-process stub, 추출한 shell 함수, 또는 명시적인 mock을 사용하는 경로인지 확인했다.
|
||||
- `mam_sandbox`는 `HERDR_SESSION` 자체를 삭제하지 않는다. 해당 값은 `lib.sh:1425–1427`의 caller 식별 및 `lib_py/pane_lock.py:45–65`의 lock 이름에 사용될 수 있다. lock 경로는 sandbox HOME 아래이며, socket·config 경로가 제거된 상태에서 이 변수만으로 운영 서버에 접속하는 재현은 얻지 않았다. 따라서 이를 이번 수정의 차단 결함으로 확대하지 않는다. 향후 공통 환경 정리 시 함께 다룰 수 있는 격리 보강 항목이다.
|
||||
|
||||
## 공유 생성 shim의 영향
|
||||
|
||||
이번 변경은 생성 heredoc의 한 조건을 의도적으로 바꾼다. `_init_herdr_isolation`은 `lib.sh:149–157`에서 제어 루트 아래 임시 shim을 만들고 `:1389–1390`에서 rename으로 교체한다. 별도 wrapper 내용 변경 외의 프로토콜 변경은 없다.
|
||||
|
||||
`test_issue23_24_startup_path.py:295–315`의 기준을 `525df2b`로 이동한 것은 이 의도적인 heredoc 변경을 반영하며 해당 테스트가 실제로 통과했다. 다만 이 테스트는 head와 그 새 기준의 동일성을 확인할 뿐, 현재 실행 중인 모든 체크아웃이 새 버전을 사용한다는 증명은 아니다. 오래된 코드와 새 코드가 동일 제어 루트를 공유하며 shim을 다시 생성하면 마지막 writer의 버전이 적용된다. 배포 시 같은 제어 루트의 생성 주체를 같은 버전으로 맞추는 것이 필요하다. 리뷰 중에는 운영 제어 루트의 shim을 읽거나 갱신하지 않았다.
|
||||
|
||||
## 비차단 기존 차이: 생성 shim의 .bin 제외 누락
|
||||
|
||||
`lib.sh:115`의 lib 해석기는 `.agents/skills/.bin`을 제외하지만, `:176`의 생성 shim 해석기는 그 별도 규칙을 가지고 있지 않다. 위 디코이 탐침에서 base와 head 모두 동일하게 확인했다. 그러므로 **두 해석기가 모든 wrapper 경로에 대해 동일한 제외 규칙을 갖는다**고 결론 내릴 수는 없다.
|
||||
|
||||
재현: `.agents/skills/.bin/herdr` 디코이를 PATH 첫 번째에, 다른 디렉터리의 디코이를 그 다음에 놓고 각 해석기를 호출한다. lib는 두 번째를 반환하고 생성 shim은 첫 번째를 반환한다. 원하는 완전한 일관성 기준에서는 생성 shim도 첫 번째를 제외해야 한다. 별도 보강 시 두 해석기의 명시적 wrapper 경로 규칙을 맞추고 이 경우를 회귀 테스트에 추가하는 방향이 적절하다. base부터 있던 차이이고 이번 접미사 축소로 새로 생긴 동작이 아니므로 본 변경의 PASS를 막지 않는다.
|
||||
|
||||
## 실행 결과와 재현
|
||||
|
||||
안전 launcher: `/tmp/efb52908-review/run.py`
|
||||
|
||||
```text
|
||||
env -u HERDR_SOCKET_PATH -u HERDR_PANE_ID -u HERDR_TAB_ID -u HERDR_WORKSPACE_ID -u HERDR_SESSION_NAME -u WORKSPACE_ROOT -u MAM_ENV_FILE <Python> /tmp/efb52908-review/run.py tests/test_herdr_real_server_leak.py tests/test_herdr_shim_contract.py tests/test_issue23_24_startup_path.py tests/test_issue9_server_env.py -k 'not test_h10_real_herdr_schema_match'
|
||||
```
|
||||
|
||||
- 결과: **105 passed, 1 deselected in 177.07s**, exit 0.
|
||||
- 실제 설치 herdr의 schema를 조회하는 `test_h10_real_herdr_schema_match`만 명시적으로 제외했다. 전체 프로젝트 스위트는 실행하지 않았다.
|
||||
- 로그: `/tmp/efb52908-review/tests.log`
|
||||
- basetemp: `/tmp/efb52908-bbxxt8p8/bt` (이름에 shim 없음).
|
||||
- launcher는 추가로 모든 상속 `HERDR_*`, `MAM_*`, `MQTT_*`, `SKS_*` 및 제어/에이전트 경로 변수를 제거하고 일회용 HOME, 지정 Python, `PYTHONDONTWRITEBYTECODE=1`, `-p no:cacheprovider`를 사용했다.
|
||||
- fallback PATH에 호출을 기록하고 exit 97로 종료하는 herdr 디코이를 설치했다. **fallback 호출 기록 없음.** 테스트별 mock이 가려져 설치 herdr까지 내려가는 상황을 허용하지 않았다.
|
||||
- broker는 기존 suite의 로컬 fixture를 사용했다. 운영 `.mam.env`를 export/출력하지 않았고 실제 사용자 홈·서버·모니터를 변경하지 않았다. agent-home 가드 오탐도 없었다.
|
||||
- 독립 경로 탐침: `/tmp/efb52908-review/probe.py`, 로그 `/tmp/efb52908-review/probe.log`. 검증 cwd에서 같은 `env -u ... <Python>`으로 실행 가능하다. 5개 경로 × 2개 해석기의 base/head 관측과 3개 링크 사례를 기록했다. 위 기존 .bin 차이를 제외한 기대 조건 assertion은 모두 통과했다. 실제 herdr를 실행하지 않았다.
|
||||
|
||||
소스 변경 없이 지정 범위의 검토를 마쳤으며 재계획이 필요한 결함은 발견하지 않았다.
|
||||
|
||||
[VERDICT: PASS]
|
||||
Reference in new issue
Block a user