Issues #23 and #24: cross-server herdr scope, agent-agnostic start-up dialogs, onboarding delivery judged by the agent's own started event, verified rollback. VERSIONS.md carries the entry; the merge-side reports (round 1: claude/agy/grok; round 2 on05b0ea4: all four, with identity sidecars, basef4ba205-> head05b0ea4, evidence review-tree) are archived under .agents/reports/<session>/. The round-1 codex report was lost to the host sleeping mid-review; its two probes are recorded in the changelog. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
8.6 KiB
🔍 Review Report — PR #35 델타 리뷰 2회차 (job df626811)
- Reviewer:
planner-reviewer-claude-01(role: planner,reviewer) · 2026-09-24 - 대상 델타:
f4ba205..05b0ea4(1커밋05b0ea4, 6파일+76/−5,git diff --check클린), basemain 1e78dae(v4.7.1). - 검증 경로:
/var/folders/.../T/mam-review/loop-20260923T220355Z-76dd1d/1. identity 확인:HEAD = 05b0ea47…a465,HEAD^{tree} = 8f5e8b04…22f3— 브리프와 일치. - 1회차 내 판정: PASS (job
adc0ff3c). 이번에는 codex 탐침 2건의 정정이 실제로 닫혔는지와 부작용을 본다. - 안전 규칙 준수: 검증 경로·소스 워크트리·본 체크아웃(
main 1e78dae) 모두 수정·커밋·checkout 없음. 함수 추출 실험과 되돌린 사본 실행은 scratchpad 에서만, pytest 는AGENT_PYTHON_BIN+--basetemp=<검증 경로 밖>. 실제 herdr·세션·.mam·데몬 조작 없음, push·merge·PR 상태 변경 없음.
결론 요약
두 정정은 탐침을 닫고, 1회차 판정을 뒤집을 요소는 없다. P2 의 continue 는 S5/S5b 의 쿨다운 계약을 그대로 유지하면서 같은 화면의 다음 다이얼로그를 보게 하고, P1 의 AUTO_TRUST="${MAM_AUTO_TRUST:-1}" 는 "플래그 > 환경 > 기본 1" 의 우선순위를 문서대로 만든다. 비차단 관찰 2건(G1·G2).
1. P2 — _mam_dialog_pick 의 continue (항목 1)
lib.sh:2954-2958. 함수만 추출해 codex 어댑터의 다이얼로그 2개(신뢰 창 idx0 → Enter, 업데이트 안내 idx1 → 2)와 두 창이 함께 있는 화면으로 7가지 상태를 돌렸다(cooldown 5 s):
| # | 상태 | 결과 | 의미 |
|---|---|---|---|
| 1 | 기록 없음, 자동 신뢰 on | send|0|Enter |
신뢰 창이 먼저(어댑터 순서) |
| 2 | 신뢰 창을 1 s 전에 보냄(쿨다운 중), on | send|1|2 |
P2 정정: 쿨다운 중인 창을 건너뛰고 안내에 답한다. 옛 코드는 여기서 exit 1 로 아무것도 안 했다 |
| 3 | 기록 없음, 자동 신뢰 off | skip|0| |
신뢰 창은 사람 몫, skip 기록 |
| 4 | skip 1 s 뒤, off | send|1|2 |
P2 정정: skip 의 쿨다운이 안내를 가리지 않는다 |
| 5 | 두 창 모두 쿨다운 중 | 없음(rc 1) | S5 유지: 쿨다운 안에서는 재전송 없음 |
| 6 | 두 창 모두 쿨다운 만료(+5 s) | send|0|Enter |
S5b 유지: 만료 후 1회 재시도, 다시 신뢰 창부터 |
| 7 | off, 만료 | skip|0| |
경고가 쿨다운마다 1회 |
키 순서·횟수: 핸들러는 한 폴링에 하나만 고르므로(_mam_dialog_pick 은 첫 actionable 항목에서 종료), 두 창이 한 화면에 있으면 1회차 폴링에 Enter, 다음 폴링(1 s 뒤)에 2 순으로 각 1회 간다. S5f 가 ["Enter", "2"] 를, S6c 가 ["2"] + 경고를 그대로 고정한다. 쿨다운은 인덱스별(state[idx])이라 서로 간섭하지 않는다.
2. P1 — AUTO_TRUST="${MAM_AUTO_TRUST:-1}" (항목 2)
create_session.sh:72,87-88,96 과 resume_session.sh:33,42-43,57 이 같은 3단 구조(초기값 ← 환경, 플래그 arm 이 덮어씀, 마지막에 export)다. 세 줄을 그대로 옮긴 하네스로 8가지를 돌렸다:
환경 MAM_AUTO_TRUST |
플래그 | 핸들러가 받는 값 | 판정 |
|---|---|---|---|
| 없음 | – | 1 (on) |
기본 |
0 |
– | 0 (off) |
P1 정정: 문서의 환경변수 형식이 이제 닿는다(옛 코드는 1 로 덮어썼다) |
0 |
--auto-trust |
1 (on) |
플래그 > 환경 |
1 |
--no-auto-trust |
0 (off) |
플래그 > 환경 |
| 없음 | --no-auto-trust |
0 (off) |
|
yes / false |
– | 그대로 전달 → 핸들러 != "0" 규칙으로 on |
_mam_dialog_pick 도 같은 규칙(MAM_DLG_TRUST != "0")이라 두 층이 일치한다 |
''(빈 문자열) |
– | :-1 이 빈 값을 미설정으로 봐 1 (on) |
핸들러의 ${MAM_AUTO_TRUST:-1} 와 같은 해석 |
즉 "0 만 off, 나머지는 전부 on" 이 스크립트·핸들러·picker 세 층에서 동일하다(lib.sh:2986, picker 의 != "0"). create SKILL.md :119-120 이 환경변수 형식과 "플래그 우선"을 명시한다. G1 (비차단): false/no 가 on 으로 해석되는 것은 일관되지만 직관에 반한다 — 문서에 "0 만 끈다" 를 한 마디 적어 두면 좋다. resume SKILL.md 는 :107 에서 MAM_AUTO_TRUST=0 형식은 적지만 "플래그가 환경보다 우선" 은 create 쪽에만 있다(G2, 사소).
3. 테스트 (항목 1·3)
3-1. 수정 없이는 실패하는가 — 확인함
검증 경로 사본에서 lib.sh·create_session.sh·resume_session.sh 세 파일만 f4ba205 판으로 되돌리고 새 회귀와 이웃 시험을 -k "s6c or s5f or r3b or c3 or test_s5_ or s5b or test_s6_" 로 돌렸다:
4 failed, 7 passed, 70 deselected in 153.65s
FAILED test_s6c_a_skipped_trust_dialog_does_not_hide_the_notice_below_it ← P2
FAILED test_s5f_a_dialog_inside_its_cooldown_does_not_block_the_next_one ← P2
FAILED test_r3b_…_on_resume[0-flag0-0] (환경변수만, 플래그 없음) ← P1
FAILED test_c3_…_on_create[0-flag0-0] (환경변수만, 플래그 없음) ← P1
실패 4건이 정확히 두 탐침의 재현 사례다. 통과한 7건 — R3b/C3 의 "플래그가 환경을 이긴다" 4사례(플래그는 옛 코드에서도 동작했다), S5·S5b(쿨다운 계약), S6(신뢰 창 skip + 안내 응답, 한 화면에 하나씩) — 은 정정 전후로 변하지 않아야 하는 계약이고, 실제로 변하지 않았다. 즉 continue 가 S5/S5b 를 깨지 않았다는 것이 되돌린 사본과 PR 트리 양쪽에서 성립한다(PR 트리 쪽은 §3-2).
3-2. PR 트리(검증 경로)에서의 실행
tests/test_issue23_24_startup_path.py tests/test_issue24_resume_dialogs.py tests/test_c1_tui_readiness.py tests/test_b19_headless_reconcile_fixes.py
→ 120 passed in 535.40s (0:08:55) failed 0 · skipped 0
같은 -k 부분집합(새 회귀 4 + 이웃 7) 단독 → 11 passed in 148.21s
- 다이얼로그 핸들러를 건드리는 4파일 전부 통과.
c1·b19의 "프레임당 1회"·Yes, try it가드도 유지된다. - 실제
.mam/jobs전후 차이 0. 검증 경로 tracked 파일 변화 없음(HEAD05b0ea4), 본 체크아웃main 1e78dae. - 시간: 이 호스트에서 다른 스위트 2개가 동시에 돌고 있어 resume 시험 6건이 각 37~41 s 였다(1회차 F6 그대로; R3b 3사례가 더해져 +2 분).
4. 병합 차단 여부 (항목 3)
1회차 PASS 를 뒤집을 요소는 없다. 델타는 세 줄의 소스 변경(lib.sh:2958 continue, create_session.sh:72·resume_session.sh:33 의 환경 기본값)과 문서 한 줄, 회귀 4건이며, 두 탐침의 재현 사례만 정확히 실패→통과로 바뀌었다. 버전 락스텝 bump 부재(4.7.1, 오케스트레이터가 4.7.2 로 처리 예정) 외에 병합을 막을 결함은 없다.
| # | 비차단 관찰 | 근거 |
|---|---|---|
| G1 | MAM_AUTO_TRUST 는 0 만 끈다(false/no 는 on). 세 층(스크립트·핸들러·picker)이 일치하므로 결함은 아니지만 문서에 한 마디 있으면 좋다 |
create_session.sh:72, lib.sh:2986, _mam_dialog_pick 의 != "0" |
| G2 | "플래그가 환경보다 우선" 은 create SKILL.md(:119-120)에만 있고 resume SKILL.md(:107)에는 환경변수 형식만 있다 |
사소 |
1회차 F1(codex 수락 키와 브리프 서술의 차이)은 이 델타의 범위 밖이며 그대로 열려 있다.
5. 교차검증 가이드
RP=/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20260923T220355Z-76dd1d/1
PY=/Users/godopu16/PuKi/laa/canary_projects/multi-agent-mux/.venv/bin/python
git -C "$RP" rev-parse HEAD 'HEAD^{tree}' # 05b0ea4… / 8f5e8b0…
# picker 단독: 신뢰 창 쿨다운 중에도 안내에 답하는지
eval "$(sed -n '/^_mam_dialog_pick() {/,/^}/p' "$RP/.agents/skills/lib.sh")"
D='[["Do you trust the contents of this directory|1\\. Yes, continue",["Enter"],"trust"],["1\\. Update now|Skip until next version",["2"],"notice"]]'
S=$'Do you trust the contents of this directory?\n > 1. Yes, continue\nUpdate available\n 1. Update now\n 2. Skip\n 3. Skip until next version'
_mam_dialog_pick "$S" "$D" 1 "0:1000" 1001 5 # send|1|2 (정정 전: 출력 없음)
_mam_dialog_pick "$S" "$D" 1 "0:1000 1:1000" 1002 5 || echo nothing # S5 유지
# 되돌린 사본에서 회귀가 실패하는지: lib.sh/create/resume 를 f4ba205 판으로 교체 → -k "s6c or s5f or r3b or c3 ..." → 4 failed / 7 passed
[VERDICT: PASS]