[Roadmap] 운영 신뢰성 개선 — 생존·전달 판정을 프로토콜 중심으로, 루프 정족수·재검토 범위 축소, 셸 계층 축소, 위생 도구 #17

Open
opened 2026-09-13 01:52:14 +00:00 by Godopu · 6 comments
Owner

취지 (Why)

2026-09-12~13 하루 동안 이슈 #9·#14·#10·#11·#13·#15 를 실제 워크플로(오케스트레이터 Claude Code 세션 → 브랜치 수정 → --all-reviewer 루프 → 병합)로 처리하며 관측한 사실을 바탕으로, 프레임워크의 운영 신뢰성을 끌어올릴 방향을 하나의 로드맵으로 묶는다. 개별 결함이 아니라 설계 방향 결정이므로 epic 으로 두고, 각 항목은 착수 시 별도 이슈/브랜치로 뗀다.

목표 환경: 오케스트레이터와 다른 호스트에서 도는 원격 에이전트까지 하나의 루프로 다루는 것. 직접 배포한 네트워크 브로커(MQTT/NATS, nats-docker)는 그 백본이며 유지한다 — 로컬 메시징(파일·소켓)은 같은 머신에서만 성립하므로 대안이 아니다. 아래 항목들은 그 전제 위에서 판정·기본값·테스트를 바로잡는 것이다.

핵심 판단: 교차 리뷰 파이프라인은 실제로 결함을 잡는다(근거 ①). 그러나 지금은 파이프라인을 돌보는 데 드는 노력이 파이프라인이 절약해 주는 노력과 맞먹거나 넘는다(근거 ②~⑤).

관측 근거 (Evidence, 2026-09-12~13)

  1. 리뷰 루프가 잡아낸 실제 결함 — 오케스트레이터(저자)가 놓친 것: 쉼 ls 의 server_not_running 문자열 오판(살아 있는 세션 전부 terminated 될 위험, codex), 자기 세션 안에서 자기 대화를 purge 해도 거부되지 않는 N1(claude), presence lock 만 열어 둔 보유자를 놓치는 R1·고아 부속 파일 R2(codex), publish_event 가 브로커 ACK 뒤에 로컬 기록(grok).
  2. 루프 미수렴의 원인이 대부분 인프라: 루프 5회 중 3회가 코드가 아닌 전달 오판(#14)·구독자 idle 타임아웃·codex 무응답(#16 항목 8)으로 만장일치에 실패. 한 바퀴 1.5~3시간, 에이전트 4개 토큰.
  3. 생존·전달 판정은 휴리스틱의 적층: herdr agent_status(codex 는 항상 idle) → pane esc to interrupt 토큰 → pane 변화 → 디스크 heartbeat → lsof → ps 명령줄 스캔. #14 계열 수정마다 한 겹씩 늘었다(send_keys_safe, _inject_acknowledged, _agent_still_working, _recent_disk_heartbeat, conversation_in_use).
  4. 복잡도 대비 가시성 부족: cwd 기준 레지스트리 경로가 몇 주간 테스트 레코드 593건을 실제 .mam/jobs 에 흘렸고(#15), 브로커 비밀번호가 레코드에 평문 저장됐다(#12). 둘 다 단순 결함이지만 lib.sh 2,600줄 + heredoc 생성 쉼 + bash 안의 python heredoc + 3~4겹 호출 계층 때문에 발견이 늦었다.
  5. 문서-코드 드리프트: SKILL.md 가 "자기 세션이면 거부" 를 약속했으나 코드는 그렇지 않았다(N1). 검토 없이는 구조적으로 재발한다.
  6. 안전하지 않은 브로커 기본값과 네트워크 의존 테스트: 코드 기본값이 공개 HiveMQ(mqtt_common.py host="broker.hivemq.com")라 .mam.env 가 없는 환경 — 예: pytest 샌드박스 — 에서는 조용히 공개 브로커로 발행한다. 래퍼 테스트(T1-1 등)는 실제 네트워크 브로커 연결에 의존해 CI 에서 돌릴 수 없다. (운영은 직접 배포한 브로커를 쓰므로 아키텍처 문제가 아니라 기본값·테스트 문제.)
  7. 위생 도구 부재: .mam/jobs 881건, delegate_job_logs 1,898개, *.subscriber.out 247개가 쌓여도 정리 명령이 없다.

원격 통합 전제 (Remote-agent premise) → #18

#14 계열 수정은 오케스트레이터 디스크(events.log, 레지스트리)와 로컬 herdr pane 을 전제한 안전장치다. 원격 에이전트는 둘 다 공유하지 않으므로 와이어(구독자)가 유일한 신호가 되고, 오늘 구독자가 idle 120초에 살아 있는 job 을 닫은 사례가 원격에서는 그대로 재현된다. 이 전제와 그 해법(heartbeat 의무·응답 없음 판정·started 기반 전달 확인·와이어 내구성·TUI 스크래핑 격리)은 우선순위가 높아 #18 로 분리했다.

로드맵 (Checklist)

  • 1. 생존·전달 판정을 프로토콜 계약으로 완결 → #18 (완료 2026-09-14, v4.5.0; 수용 기준 5 의 원격 리뷰어 루프 수렴은 원격 호스트 환경에서 확인 필요) — started/progress/completed 를 의무·주기·타임아웃 규칙이 있는 계약으로 격상하고 TUI 스크래핑을 주입·다이얼로그·진단 정보로만 한정. 원격 에이전트 통합의 선결 조건. (#16 항목 2·3·4·8 흡수)
  • 2. 루프 판정 규칙 완화 — 만장일치 → 정족수(예: 3/4, 반대 의견은 후속 이슈로 자동 기록) 또는 실패(크래시·타임아웃)한 리뷰어만 재시도. 리뷰어 하나의 인프라 문제로 전체 루프가 --max-loop 를 소진하지 않게.
  • 3. 반복 시 재검토 범위 축소 — NOT PASS 교정 후 반복에서는 변경된 커밋(git diff <이전 검토 HEAD>...HEAD)만 정밀 검토하고 나머지는 회귀 확인으로. 브리프에 이전 검토 HEAD 와 판정을 자동으로 넣기.
  • 4. 셸 계층 축소 — lib.sh 의 쉼 생성·전달/생존 판정·pane 파싱을 lib_py 로 옮기고 bash 는 얇은 인자 전달로. 판정 로직이 단위 테스트 대상이 되게.
  • 5. 안전한 브로커 기본값과 위생 도구 — 공개 브로커 기본값 제거(MQTT_BROKER 미설정 시 fail-closed, 배포한 브로커는 .mam.env 로 명시); 테스트는 로컬 브로커(docker mosquitto/NATS) 또는 in-process fake 로 전환해 CI 가능하게; registry.py prune(테스트 접두사·고아 subscriber.out·오래된 terminal 레코드), delegate_job_logs 보존 기간. (#15 후속, A-2 의 "공개 브로커 + HMAC off" 항목 흡수)
  • 6. 문서-코드 계약 검사 — SKILL.md 의 exit 코드·옵션 표를 스크립트 --help/실제 종료 코드와 비교하는 정적 테스트(이미 help-*.txt 캡처 방식이 있음)를 8개 스킬로 확장.
  • 7. 릴리스 의식 경량화 — 패치급 수정(오타 등)은 락스텝 버전 bump 없이 병합 가능하게 하거나, bump 를 병합 시점에 한 번만 하는 규칙.

우선순위 제안

1 (= #18, 원격 통합 선결) · 2 (루프 수렴 시간에 직결) > 3 > 5 > 6·7 > 4 (가장 큰 공사, #18 이 자리 잡은 뒤).

관련 이슈

  • #18 생존·전달 판정의 프로토콜 계약 (항목 1 의 독립 이슈)
  • #16 전달 확인·생존 판정 빈틈 묶음 (→ #18)
  • #15 테스트 레지스트리 누수 (해결 브랜치 fix/issue-10-11-13-15) (→ 항목 5 후속)
  • #14 (closed) send_keys_safe 전달 오판, #9 (closed) 서버 env 상속 — 이번 로드맵의 출발점. #14 는 같은 호스트에서는 해결됐고, 위 "원격 통합 전제"는 그 수정이 만든 새 전제이지 #14 의 미해결분이 아니다.
  • IMPROVEMENTS.md A-2 공개 브로커 + HMAC off (→ 항목 5)

환경 정보 (Environment)

  • 관측 기준: main bd3df89(v4.4.2) + 브랜치 fix/issue-10-11-13-15(v4.4.3) / fix/issue-12-8-7
  • 실행 환경: macOS (Darwin 25.6.0), herdr 0.9.0, 오케스트레이터 = Claude Code 세션, 리뷰어 = claude·agy·grok·codex, 브로커 = 직접 배포(nats-docker)
## 취지 (Why) 2026-09-12~13 하루 동안 이슈 #9·#14·#10·#11·#13·#15 를 실제 워크플로(오케스트레이터 Claude Code 세션 → 브랜치 수정 → `--all-reviewer` 루프 → 병합)로 처리하며 관측한 사실을 바탕으로, 프레임워크의 **운영 신뢰성**을 끌어올릴 방향을 하나의 로드맵으로 묶는다. 개별 결함이 아니라 설계 방향 결정이므로 epic 으로 두고, 각 항목은 착수 시 별도 이슈/브랜치로 뗀다. **목표 환경**: 오케스트레이터와 다른 호스트에서 도는 **원격 에이전트**까지 하나의 루프로 다루는 것. 직접 배포한 네트워크 브로커(MQTT/NATS, `nats-docker`)는 그 백본이며 유지한다 — 로컬 메시징(파일·소켓)은 같은 머신에서만 성립하므로 대안이 아니다. 아래 항목들은 그 전제 위에서 판정·기본값·테스트를 바로잡는 것이다. **핵심 판단**: 교차 리뷰 파이프라인은 실제로 결함을 잡는다(근거 ①). 그러나 지금은 파이프라인을 돌보는 데 드는 노력이 파이프라인이 절약해 주는 노력과 맞먹거나 넘는다(근거 ②~⑤). ## 관측 근거 (Evidence, 2026-09-12~13) 1. **리뷰 루프가 잡아낸 실제 결함** — 오케스트레이터(저자)가 놓친 것: 쉼 `ls` 의 `server_not_running` 문자열 오판(살아 있는 세션 전부 terminated 될 위험, codex), 자기 세션 안에서 자기 대화를 purge 해도 거부되지 않는 N1(claude), presence lock 만 열어 둔 보유자를 놓치는 R1·고아 부속 파일 R2(codex), `publish_event` 가 브로커 ACK 뒤에 로컬 기록(grok). 2. **루프 미수렴의 원인이 대부분 인프라**: 루프 5회 중 3회가 코드가 아닌 전달 오판(#14)·구독자 idle 타임아웃·codex 무응답(#16 항목 8)으로 만장일치에 실패. 한 바퀴 1.5~3시간, 에이전트 4개 토큰. 3. **생존·전달 판정은 휴리스틱의 적층**: herdr `agent_status`(codex 는 항상 idle) → pane `esc to interrupt` 토큰 → pane 변화 → 디스크 heartbeat → `lsof` → `ps` 명령줄 스캔. #14 계열 수정마다 한 겹씩 늘었다(`send_keys_safe`, `_inject_acknowledged`, `_agent_still_working`, `_recent_disk_heartbeat`, `conversation_in_use`). 4. **복잡도 대비 가시성 부족**: cwd 기준 레지스트리 경로가 몇 주간 테스트 레코드 593건을 실제 `.mam/jobs` 에 흘렸고(#15), 브로커 비밀번호가 레코드에 평문 저장됐다(#12). 둘 다 단순 결함이지만 `lib.sh` 2,600줄 + heredoc 생성 쉼 + bash 안의 python heredoc + 3~4겹 호출 계층 때문에 발견이 늦었다. 5. **문서-코드 드리프트**: SKILL.md 가 "자기 세션이면 거부" 를 약속했으나 코드는 그렇지 않았다(N1). 검토 없이는 구조적으로 재발한다. 6. **안전하지 않은 브로커 기본값과 네트워크 의존 테스트**: 코드 기본값이 공개 HiveMQ(`mqtt_common.py` `host="broker.hivemq.com"`)라 `.mam.env` 가 없는 환경 — 예: pytest 샌드박스 — 에서는 조용히 공개 브로커로 발행한다. 래퍼 테스트(T1-1 등)는 실제 네트워크 브로커 연결에 의존해 CI 에서 돌릴 수 없다. (운영은 직접 배포한 브로커를 쓰므로 아키텍처 문제가 아니라 **기본값·테스트** 문제.) 7. **위생 도구 부재**: `.mam/jobs` 881건, `delegate_job_logs` 1,898개, `*.subscriber.out` 247개가 쌓여도 정리 명령이 없다. ## 원격 통합 전제 (Remote-agent premise) → #18 #14 계열 수정은 오케스트레이터 **디스크**(`events.log`, 레지스트리)와 **로컬 herdr pane** 을 전제한 안전장치다. 원격 에이전트는 둘 다 공유하지 않으므로 와이어(구독자)가 유일한 신호가 되고, 오늘 구독자가 idle 120초에 살아 있는 job 을 닫은 사례가 원격에서는 그대로 재현된다. 이 전제와 그 해법(heartbeat 의무·응답 없음 판정·`started` 기반 전달 확인·와이어 내구성·TUI 스크래핑 격리)은 우선순위가 높아 **#18 로 분리**했다. ## 로드맵 (Checklist) - [x] **1. 생존·전달 판정을 프로토콜 계약으로 완결 → #18** (완료 2026-09-14, v4.5.0; 수용 기준 5 의 원격 리뷰어 루프 수렴은 원격 호스트 환경에서 확인 필요) — `started`/`progress`/`completed` 를 의무·주기·타임아웃 규칙이 있는 계약으로 격상하고 TUI 스크래핑을 주입·다이얼로그·진단 정보로만 한정. 원격 에이전트 통합의 선결 조건. (#16 항목 2·3·4·8 흡수) - [ ] **2. 루프 판정 규칙 완화** — 만장일치 → 정족수(예: 3/4, 반대 의견은 후속 이슈로 자동 기록) 또는 실패(크래시·타임아웃)한 리뷰어만 재시도. 리뷰어 하나의 인프라 문제로 전체 루프가 `--max-loop` 를 소진하지 않게. - [ ] **3. 반복 시 재검토 범위 축소** — NOT PASS 교정 후 반복에서는 변경된 커밋(`git diff <이전 검토 HEAD>...HEAD`)만 정밀 검토하고 나머지는 회귀 확인으로. 브리프에 이전 검토 HEAD 와 판정을 자동으로 넣기. - [ ] **4. 셸 계층 축소** — `lib.sh` 의 쉼 생성·전달/생존 판정·pane 파싱을 `lib_py` 로 옮기고 bash 는 얇은 인자 전달로. 판정 로직이 단위 테스트 대상이 되게. - [ ] **5. 안전한 브로커 기본값과 위생 도구** — 공개 브로커 기본값 제거(`MQTT_BROKER` 미설정 시 fail-closed, 배포한 브로커는 `.mam.env` 로 명시); 테스트는 로컬 브로커(docker mosquitto/NATS) 또는 in-process fake 로 전환해 CI 가능하게; `registry.py prune`(테스트 접두사·고아 `subscriber.out`·오래된 terminal 레코드), `delegate_job_logs` 보존 기간. (#15 후속, A-2 의 "공개 브로커 + HMAC off" 항목 흡수) - [ ] **6. 문서-코드 계약 검사** — SKILL.md 의 exit 코드·옵션 표를 스크립트 `--help`/실제 종료 코드와 비교하는 정적 테스트(이미 `help-*.txt` 캡처 방식이 있음)를 8개 스킬로 확장. - [ ] **7. 릴리스 의식 경량화** — 패치급 수정(오타 등)은 락스텝 버전 bump 없이 병합 가능하게 하거나, bump 를 병합 시점에 한 번만 하는 규칙. ## 우선순위 제안 1 (= #18, 원격 통합 선결) · 2 (루프 수렴 시간에 직결) > 3 > 5 > 6·7 > 4 (가장 큰 공사, #18 이 자리 잡은 뒤). ## 관련 이슈 - #18 생존·전달 판정의 프로토콜 계약 (항목 1 의 독립 이슈) - #16 전달 확인·생존 판정 빈틈 묶음 (→ #18) - #15 테스트 레지스트리 누수 (해결 브랜치 `fix/issue-10-11-13-15`) (→ 항목 5 후속) - #14 (closed) send_keys_safe 전달 오판, #9 (closed) 서버 env 상속 — 이번 로드맵의 출발점. #14 는 같은 호스트에서는 해결됐고, 위 "원격 통합 전제"는 그 수정이 만든 새 전제이지 #14 의 미해결분이 아니다. - `IMPROVEMENTS.md` A-2 공개 브로커 + HMAC off (→ 항목 5) ## 환경 정보 (Environment) - 관측 기준: main `bd3df89`(v4.4.2) + 브랜치 `fix/issue-10-11-13-15`(v4.4.3) / `fix/issue-12-8-7` - 실행 환경: macOS (Darwin 25.6.0), herdr 0.9.0, 오케스트레이터 = Claude Code 세션, 리뷰어 = claude·agy·grok·codex, 브로커 = 직접 배포(`nats-docker`)
Author
Owner

항목 1(생존·전달 판정의 프로토콜 계약화)은 #18 로 완료되어 v4.5.0 에 병합됐습니다(main 5611859). #16 항목 2·3·4 는 pane 변화·busy 토큰·herdr 상태 판정이 제거되면서 대상 코드가 사라졌고, 항목 8(codex 무응답)은 started 기반 전달 확인과 T=180 으로 해소됐습니다. 남은 유의점: 수용 기준 5 중 원격 리뷰어를 포함한 --all-reviewer 루프 수렴은 단일 잡 원격 시뮬레이션까지만 검증됐으므로 실제 원격 호스트에서 확인이 필요합니다. 항목 4(셸 계층 축소)는 이제 착수 가능합니다.

항목 1(생존·전달 판정의 프로토콜 계약화)은 #18 로 완료되어 v4.5.0 에 병합됐습니다(main `5611859`). #16 항목 2·3·4 는 pane 변화·busy 토큰·herdr 상태 판정이 제거되면서 대상 코드가 사라졌고, 항목 8(codex 무응답)은 `started` 기반 전달 확인과 T=180 으로 해소됐습니다. 남은 유의점: 수용 기준 5 중 원격 리뷰어를 포함한 `--all-reviewer` 루프 수렴은 단일 잡 원격 시뮬레이션까지만 검증됐으므로 실제 원격 호스트에서 확인이 필요합니다. 항목 4(셸 계층 축소)는 이제 착수 가능합니다.
Author
Owner

항목 4(셸 계층 축소)의 경계 기준 — 병합 워크스페이스 합의 (2026-09-25, v4.7.4 기준)

PR #29·#32·#35·#37·#38 을 병합하며 겪은 바로는, 결함의 대부분이 bash 층에서 났고(#36 단일 argv 상한, #26 source 로 설정 실행, #24 export 가 환경값을 덮음, #28 bash 3.2/dash 이식성, set -u·빈 배열·인용), 한 결함을 bash 와 Python 양쪽에서 고쳐야 하는 일이 반복됐다(#36: 래퍼·lib.sh·옛 셸 러너 + 등록부·러너, #23: lib.sh 공유 빌더 + Python 판정, #34: 래퍼 플래그 + 등록부 필드). 전면 재작성(Rust 등)은 층을 하나 더 늘리고 리뷰 왕복을 느리게 하므로 지금은 택하지 않는다. 대신 경계를 옮긴다.

기준 한 줄: 결정을 내리는 코드는 Python, 외부 프로세스를 만지는 코드는 bash. 애매하면 Python.

Python(코어 API)에 두는 것

  • 등록부·이벤트 발행/구독·heartbeat·원격 전송(이미 Python)
  • 래퍼의 종결 처리(finalize_unfinished)와 타임아웃 판정·라벨(#33), 전달 확인(started 판정), 부모 잡·브리프 생성
  • 살아 있지만 멈춘 상태의 판정(#30, herdr 상태 이벤트 구독)
  • .mam.env 파싱(#26) — bash source 제거
  • 루프 러너(이미 Python). 옛 셸 루프 러너(MAM_LOOP_PY=0)는 새 기능을 넣지 말고 제거 시점을 정한다

bash(실행부)에 남기는 것

  • herdr tmux 호환 쉼과 서버 해석(mam_herdr, _herdr_call_is_cross_server 등 — h-시리즈 계약 테스트가 고정)
  • pane 키·프롬프트 주입(send_keys_safe), 세션·프로세스 기동, 사용자 셸 환경 초기화
  • 결정하지 않고 시키는 대로 외부 프로세스를 만지는 것만

효과: 언어는 둘이지만 결함이 나는 층은 하나로 줄고, 남는 bash 는 계약이 고정된 몇백 줄이라 나중에 다른 언어(예: Rust 바이너리)로 옮길 때 옮길 양이 작다.

순서: 항목 4 가 래퍼의 종결 처리를 Python 으로 옮긴 뒤 #33(벽시계 예산·라벨·연장)과 #30(멈춤 판정)을 그 위에 얹는다. 두 이슈에도 같은 내용을 남긴다.

## 항목 4(셸 계층 축소)의 경계 기준 — 병합 워크스페이스 합의 (2026-09-25, v4.7.4 기준) PR #29·#32·#35·#37·#38 을 병합하며 겪은 바로는, 결함의 대부분이 bash 층에서 났고(#36 단일 argv 상한, #26 `source` 로 설정 실행, #24 `export` 가 환경값을 덮음, #28 bash 3.2/dash 이식성, `set -u`·빈 배열·인용), 한 결함을 bash 와 Python 양쪽에서 고쳐야 하는 일이 반복됐다(#36: 래퍼·`lib.sh`·옛 셸 러너 + 등록부·러너, #23: `lib.sh` 공유 빌더 + Python 판정, #34: 래퍼 플래그 + 등록부 필드). 전면 재작성(Rust 등)은 층을 하나 더 늘리고 리뷰 왕복을 느리게 하므로 지금은 택하지 않는다. 대신 경계를 옮긴다. **기준 한 줄**: 결정을 내리는 코드는 Python, 외부 프로세스를 만지는 코드는 bash. 애매하면 Python. **Python(코어 API)에 두는 것** - 등록부·이벤트 발행/구독·heartbeat·원격 전송(이미 Python) - 래퍼의 종결 처리(`finalize_unfinished`)와 타임아웃 판정·라벨(#33), 전달 확인(`started` 판정), 부모 잡·브리프 생성 - 살아 있지만 멈춘 상태의 판정(#30, herdr 상태 이벤트 구독) - `.mam.env` 파싱(#26) — bash `source` 제거 - 루프 러너(이미 Python). 옛 셸 루프 러너(`MAM_LOOP_PY=0`)는 새 기능을 넣지 말고 제거 시점을 정한다 **bash(실행부)에 남기는 것** - herdr tmux 호환 쉼과 서버 해석(`mam_herdr`, `_herdr_call_is_cross_server` 등 — h-시리즈 계약 테스트가 고정) - pane 키·프롬프트 주입(`send_keys_safe`), 세션·프로세스 기동, 사용자 셸 환경 초기화 - 결정하지 않고 시키는 대로 외부 프로세스를 만지는 것만 **효과**: 언어는 둘이지만 결함이 나는 층은 하나로 줄고, 남는 bash 는 계약이 고정된 몇백 줄이라 나중에 다른 언어(예: Rust 바이너리)로 옮길 때 옮길 양이 작다. **순서**: 항목 4 가 래퍼의 종결 처리를 Python 으로 옮긴 뒤 #33(벽시계 예산·라벨·연장)과 #30(멈춤 판정)을 그 위에 얹는다. 두 이슈에도 같은 내용을 남긴다.
Author
Owner

항목 4 — Python 으로 옮길 bash 판정 목록 (PR #41·#43 리뷰 합의, 2026-10-02)

v4.8.0(PR #41)·v4.8.1(PR #43) 리뷰에서 네 리뷰어(claude·agy·grok·codex)가 "이 PR 이 항목 4 를 미룬 것은 타당하나, 새로 생긴 bash 판정은 항목 4 의 이전 목록에 올린다"는 조건으로 합의했습니다. 흩어져 있던 목록을 여기에 모읍니다.

래퍼 종결 처리 (PR #41 합의 D)

  1. FINALIZE_CLOCK 선택과 디스크 유예·브로커 재관측의 종료 결정(wall_clock_timeout / deadline_timeout 라벨 고르기).
  2. 감시 여부 판정(remote / human / MAM_STALL_WATCH)과 start_stall_watch·stop_stall_watch 의 수명 관리.
  3. 구독자 rc → close 요청·라벨 매핑(_map_sub_rc), cmd_wait 의 rc 정규화.

입력 정제 (PR #43 claude R5)
4. lib.sh mam_int·mam_int_knob 과 래퍼 parse_opts 의 정수 플래그 검증. 판정이 아니라 형식 변환이라 경계 위반은 아니지만, 래퍼 인자 처리가 Python 으로 갈 때 함께 옮긴다. 지금은 runner.py _positive_int 와 같은 규칙을 테스트(tests/test_issue26_ints.py)로 묶어 두었다.

bash 에 남길 것: spawn / wait / kill, 키 주입, 신호 정리, 얇은 외부 CLI 호환.

이미 옮겨진 것: .mam.env 파싱(#26, v4.8.1 — lib_py/delegation/envfile.py).

관련: #42(고정된 워크플로우를 Python 진입점으로, SKILL.md 는 최소 지침만)는 "문서 → 코드" 방향이고, 이 항목은 "bash → Python" 방향이라 같은 목록을 공유합니다. #40(세션 ID 자동 확정)의 트리거는 1·3 을 옮긴 Python 완료 처리기에 붙입니다.

## 항목 4 — Python 으로 옮길 bash 판정 목록 (PR #41·#43 리뷰 합의, 2026-10-02) v4.8.0(PR #41)·v4.8.1(PR #43) 리뷰에서 네 리뷰어(claude·agy·grok·codex)가 "이 PR 이 항목 4 를 미룬 것은 타당하나, 새로 생긴 bash 판정은 항목 4 의 이전 목록에 올린다"는 조건으로 합의했습니다. 흩어져 있던 목록을 여기에 모읍니다. **래퍼 종결 처리 (PR #41 합의 D)** 1. `FINALIZE_CLOCK` 선택과 디스크 유예·브로커 재관측의 종료 결정(`wall_clock_timeout` / `deadline_timeout` 라벨 고르기). 2. 감시 여부 판정(remote / human / `MAM_STALL_WATCH`)과 `start_stall_watch`·`stop_stall_watch` 의 수명 관리. 3. 구독자 rc → close 요청·라벨 매핑(`_map_sub_rc`), `cmd_wait` 의 rc 정규화. **입력 정제 (PR #43 claude R5)** 4. `lib.sh` `mam_int`·`mam_int_knob` 과 래퍼 `parse_opts` 의 정수 플래그 검증. 판정이 아니라 형식 변환이라 경계 위반은 아니지만, 래퍼 인자 처리가 Python 으로 갈 때 함께 옮긴다. 지금은 `runner.py` `_positive_int` 와 같은 규칙을 테스트(`tests/test_issue26_ints.py`)로 묶어 두었다. **bash 에 남길 것**: spawn / wait / kill, 키 주입, 신호 정리, 얇은 외부 CLI 호환. **이미 옮겨진 것**: `.mam.env` 파싱(#26, v4.8.1 — `lib_py/delegation/envfile.py`). 관련: #42(고정된 워크플로우를 Python 진입점으로, SKILL.md 는 최소 지침만)는 "문서 → 코드" 방향이고, 이 항목은 "bash → Python" 방향이라 같은 목록을 공유합니다. #40(세션 ID 자동 확정)의 트리거는 1·3 을 옮긴 Python 완료 처리기에 붙입니다.
Author
Owner

항목 4 (delegate-job 래퍼의 판정을 Python 으로) 는 PR #51 로 병합했습니다 (v4.8.6, 56d0bfd). 나머지 항목이 있어 이 이슈는 열어 둡니다. 후속 메모는 PR #51 마지막 코멘트에 있습니다.

항목 4 (delegate-job 래퍼의 판정을 Python 으로) 는 PR #51 로 병합했습니다 (v4.8.6, 56d0bfd). 나머지 항목이 있어 이 이슈는 열어 둡니다. 후속 메모는 PR #51 마지막 코멘트에 있습니다.
Author
Owner

PR #51 리뷰의 후속(N1·N2·N3, herdr 0.9.3 테스트)을 PR #52 로 병합했습니다 (v4.8.7, 6b00b6e). 그 과정에서 herdr 0.9.3 에서 #45 B(resume 이 복원된 빈 셸 닫기)가 깨져 있던 것도 고쳤습니다. 나머지 항목이 있어 이 이슈는 열어 둡니다.

PR #51 리뷰의 후속(N1·N2·N3, herdr 0.9.3 테스트)을 PR #52 로 병합했습니다 (v4.8.7, 6b00b6e). 그 과정에서 herdr 0.9.3 에서 #45 B(resume 이 복원된 빈 셸 닫기)가 깨져 있던 것도 고쳤습니다. 나머지 항목이 있어 이 이슈는 열어 둡니다.
Author
Owner

v4.8.7 리뷰의 비차단 지적(테스트가 상속된 WORKSPACE_ROOT 의 shim 을 덮어씀)을 PR #53 으로 병합했습니다 (v4.8.8, 97c2946). 같은 결함이 있던 테스트 모듈 13 곳을 함께 고쳤습니다. 나머지 항목이 있어 이 이슈는 열어 둡니다.

v4.8.7 리뷰의 비차단 지적(테스트가 상속된 WORKSPACE_ROOT 의 shim 을 덮어씀)을 PR #53 으로 병합했습니다 (v4.8.8, 97c2946). 같은 결함이 있던 테스트 모듈 13 곳을 함께 고쳤습니다. 나머지 항목이 있어 이 이슈는 열어 둡니다.
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: tmpl/multi-agent-mux#17