release(v4.7.4): bump framework and eight skills to 4.7.4 in lockstep; archive PR #38 merge-side reviews

Issue #34: the loop waits for the creator job's sub-jobs, reviewers get
the sub-job table as evidence, a run with sub-jobs voids a round whose
source changed during review, and a pane caller reaches an agent of
another workspace on its own server. VERSIONS.md carries the entry; the
merge-side reports (round 1 @ed293dc and round 2 @e80186f with identity
sidecars, base ed293dc -> head e80186f, evidence review-tree) are archived
under .agents/reports/<session>/.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
This commit is contained in:
GodopuandClaude Fable 5.1 committed 2026-09-25 16:44:20 +09:00
1 parent e80186f560
commit 22586d2a01
28 files changed
+825 -26

No files matched your search

+31 -11
View File
@@ -6,8 +6,8 @@
## 📌 현재 버전 개요 (Current Release)
- **프레임워크 버전**: `v4.7.3`
- **최신 릴리스 일시**: 2026-09-24 (KST)
- **프레임워크 버전**: `v4.7.4`
- **최신 릴리스 일시**: 2026-09-25 (KST)
- **기준 브랜치**: `main`
- **핵심 아키텍처**:
- **Terminal 상태 단방향 불변성 (`engine.py`, Issue #6 Phase 1)**: `completed`, `error`, `cancelled` 터미널 상태 진입 후 후속 이벤트나 업데이트에 의한 덮어쓰기를 엄격히 차단(Terminal Immutability). `registry.py close` 서브커맨드 및 fail-closed 조기 종료 도입.
@@ -22,23 +22,43 @@
## 🧭 스킬 패키지 버전 매트릭스 (Skills Version Matrix)
모든 8개 스킬은 YAML frontmatter 메타데이터(`author`, `version`, `platforms`, `environments`) 표준화를 통해 `v4.7.3`로 동기화되어 배포됩니다.
모든 8개 스킬은 YAML frontmatter 메타데이터(`author`, `version`, `platforms`, `environments`) 표준화를 통해 `v4.7.4`로 동기화되어 배포됩니다.
| 스킬명 | 버전 | 역할 및 주요 책임 | 상태 |
| :--- | :---: | :--- | :---: |
| **`multi-agent-mux-create`** | `4.7.3` | 에이전트 세션 신규 생성 및 Herdr 컨테이너 격리 스폰 | ✅ 배포 |
| **`multi-agent-mux-stop`** | `4.7.3` | 대화 UUID 원자적 캡처 및 세션 안전 종료 (Graceful Stop) | ✅ 배포 |
| **`multi-agent-mux-resume`** | `4.7.3` | 온디스크 대화 컨텍스트 기반 Tier-1 초고속 세션 복원 | ✅ 배포 |
| **`multi-agent-mux-status`** | `4.7.3` | 실시간 Herdr 세션 및 레지스트리 드리프트 스냅샷 조회 | ✅ 배포 |
| **`multi-agent-mux-monitor`** | `4.7.3` | YAML ↔ 런타임 상태 간 자율 조정자 (Reconciler Loop) | ✅ 배포 |
| **`multi-agent-mux-delegate-job`** | `4.7.3` | MQTT 이벤트 채널 기반 비동기 단위 작업 위임 | ✅ 배포 |
| **`multi-agent-mux-loop`** | `4.7.3` | Planner-Creator-Reviewer 3자 자율 계획·실행·피어리뷰 루프 | ✅ 배포 |
| **`multi-agent-mux-orc-onboard`** | `4.7.3` | 오케스트레이터 UUID 격리 등록 및 서브 세션 오염 방지 | ✅ 배포 |
| **`multi-agent-mux-create`** | `4.7.4` | 에이전트 세션 신규 생성 및 Herdr 컨테이너 격리 스폰 | ✅ 배포 |
| **`multi-agent-mux-stop`** | `4.7.4` | 대화 UUID 원자적 캡처 및 세션 안전 종료 (Graceful Stop) | ✅ 배포 |
| **`multi-agent-mux-resume`** | `4.7.4` | 온디스크 대화 컨텍스트 기반 Tier-1 초고속 세션 복원 | ✅ 배포 |
| **`multi-agent-mux-status`** | `4.7.4` | 실시간 Herdr 세션 및 레지스트리 드리프트 스냅샷 조회 | ✅ 배포 |
| **`multi-agent-mux-monitor`** | `4.7.4` | YAML ↔ 런타임 상태 간 자율 조정자 (Reconciler Loop) | ✅ 배포 |
| **`multi-agent-mux-delegate-job`** | `4.7.4` | MQTT 이벤트 채널 기반 비동기 단위 작업 위임 | ✅ 배포 |
| **`multi-agent-mux-loop`** | `4.7.4` | Planner-Creator-Reviewer 3자 자율 계획·실행·피어리뷰 루프 | ✅ 배포 |
| **`multi-agent-mux-orc-onboard`** | `4.7.4` | 오케스트레이터 UUID 격리 등록 및 서브 세션 오염 방지 | ✅ 배포 |
---
## 📋 버전별 상세 변경 내역 (Changelog)
### 🚀 `v4.7.4` — Issue #34 루프가 creator 의 하위 위임 잡까지 기다리고 리뷰어에게 하위 잡 상태를 근거로 제공 (2026-09-25, PR #38)
> **패치 마일스톤 (PATCH Release)**: creator 가 작업 일부를 delegate-job 으로 다른 에이전트에게 맡기면, 그 하위 잡이 아직 돌고 있어도 루프가 리뷰로 넘어가 **미완성 산출물이 PASS** 되던 문제(Issue #34)를 고쳤다. 루프는 자신이 만든 잡만 감시했고 잡 레코드에는 부모·자식 관계가 없었다. 필드 하나(`parent_job`)와 옵션 둘(`--parent-job`, `--wait-open-jobs`)이 늘지만 잘못된 판정 경로를 고치는 수정이라 PATCH 로 올린다.
#### 🌟 주요 개선 사항
1. **잡이 부모를 기록 (`lib_py/delegation/registry.py`, delegate-job 래퍼)**: `submit --parent-job <id>` 가 이 잡이 어느 잡에서 위임됐는지 남긴다. 부모가 등록부에 없으면 등록을 거부한다(오타가 조용히 루트 잡이 되지 않도록). 기본값은 원격 러너가 주는 `MAM_JOB_ID` 이며 이 등록부에 없으면 경고만 하고 부모 없이 등록한다. `registry.py list --parent <id>`, `children_of`/`descendants_of`(너비 우선, 한 번 방문, 순환 안전, `depth`).
2. **에이전트에게 부모 ID 전달**: 로컬 에이전트는 pane 에 오래 떠 있어 잡마다 환경변수를 넣을 수 없으므로, 잡마다 새로 주입되는 안내문과 `brief.md` 에 "하위 위임 시 `--parent-job <이 잡 ID>` 를 붙여라" 를 적는다(`create_session.sh --submit-job` 도 같음). 실제 creator 에게 방법을 알려주지 않고 위임을 시켰을 때 스스로 붙였다.
3. **루프가 자손 잡까지 대기 (`lib_py/loop/runner.py: wait_for_job_tree / wait_for_descendants`)**: creator 잡(구현·수정·순응)이 끝난 뒤 자손 잡이 모두 종결될 때까지 기다린 다음 리뷰로 넘어간다. 자손은 폴링마다 다시 읽어 손자 잡도 잡는다. 상한은 둘: `MAM_CHILD_WAIT_S`(creator 잡 종결부터, 기본 3900 초; 각 하위 잡은 #33 의 3600 초 예산으로 닫힌다)와 `MAM_JOB_TREE_MAX`(기본 50, 넘으면 기다리지 않음). `--wait-open-jobs` 는 부모 없이 등록된 열린 잡까지 기다린다(무관한 잡이 루프를 붙잡을 수 있어 기본 꺼짐).
4. **리뷰어가 하위 잡 상태를 봄 (`_subjobs_block`)**: 리뷰 프롬프트 앞에 하위 잡 표(세션·역할·상태·종료 사유·깊이)를 넣고, 열린(OPEN)·미확인 종결(CLOSED-UNCONFIRMED: `deadline_timeout`/`agent_blocked` 로 오케스트레이터가 닫은 잡, 에이전트는 계속 일하고 있을 수 있음)·실패 하위 잡이 있으면 NOT PASS 를 내도록 규칙을 준다. `session_busy`/`target_not_found`/롤백은 NOT-DISPATCHED. 수정 라운드에서도 앞선 creator 잡의 하위 잡이 표에 남는다. 부모 미표기 열린 잡은 `[귀속되지 않은 열린 잡]` 으로 따로 보여준다. 하위 위임이 전혀 없으면 프롬프트는 바이트 단위로 이전과 같다.
5. **하위 잡이 있을 때 리뷰 중 소스 변경은 승인 무효 (`_fingerprint`)**: 하위 잡이 리뷰 도중 파일을 고칠 수 있으므로, `--worktree`/`--base` 없는 루프에도 identity 모드의 B7/B10 에 해당하는 가드를 둔다. 제어 평면(`.mam`, jobs, 감사 로그) 디렉터리는 지문에서 제외하고, **하위 잡이 있는 실행에서만** 켠다(하위 잡 없는 기존 루프의 동작 불변; 켜 두면 샌드박스 e2e 가 매 라운드 무효화됐다).
6. **같은 서버의 다른 워크스페이스 에이전트에게 위임 (`lib.sh: _herdr_scope_is_pane_inherited`)**: herdr pane 이 내보내는 `HERDR_WORKSPACE_ID` 가 이름 조회(`agent`/`has-session`/`kill-session`)의 스코프로 쓰여 다른 워크스페이스의 에이전트가 보이지 않았다(워크트리 creator 의 하위 위임이 기본적으로 걸림). pane 안의 호출자가 이름으로 대상을 찾을 때 그 ID 가 `HERDR_PANE_ID` 의 워크스페이스와 같으면 뗀다(살아 있는 에이전트 이름은 서버 단위로 유일). pane 밖의 명시 스코프·pane 과 어긋나는 스코프·pane/세션 생성 호출은 그대로. 대상이 보이지 않아 취소된 잡은 `session_busy` 가 아니라 `target_not_found` 로 기록된다.
7. **문서**: delegate-job/loop SKILL.md, MULTI_AGENT_RULES(ko).
#### ✅ 품질 검증
- **신규 테스트** (`tests/test_issue34_job_tree.py`, 598줄): 실제 래퍼로 하위 잡을 등록하고 실제 등록부를 읽는다 — 부모 검증·`descendants_of`·자손 대기·상한·하위 잡 표와 상태 분류·stale 가드·같은 서버 다른 워크스페이스 조회. 첫 루프 시점의 14건은 수정 전 코드(7a4a0c2)에서 모두 실패.
- **리뷰**: 작성 워크스페이스 5인 전체 루프 2회차 전원 PASS + 델타 전원 PASS(codex 1차: 수정 라운드에서 앞선 creator 잡의 하위 잡이 표에서 빠짐 → 3fdbb62; 오케스트레이터: stale 가드를 옵션 없는 루프에 무조건 켜자 `test_tier4_e2e.py` 시나리오 5 회귀 → 1d4f338; 실제 시험: 같은 서버 다른 워크스페이스 스코프 → ed293dc). 병합 워크스페이스에서 PR head 를 detached 워크트리에 받아 재검토: 1회차 @ed293dc claude PASS(비차단 K1–K4)·agy PASS, grok·codex NOT PASS — 래퍼가 투입 전에 `cancelled --detail target_not_found|session_busy` 로 닫은 하위 잡의 사유를 `get_feedback` 이 읽지 않아 표에 사유 없는 `cancelled` 로만 나옴(grok N1·codex R1), 원격 러너의 마감 문구 `deadline_timeout (remote runner)` 가 완전 일치 비교에 걸려 일반 실패로 집계됨(codex R2), 귀속되지 않은 열린 잡에 판정 규칙 문장이 없음(claude K1) → 8a9101e·e80186f 로 정정(`get_feedback(events=…)`, 사유의 첫 단어로 종류 판정, `STRAY_RULE`; 회귀 T13·T14·T6 은 정정을 되돌리면 실패). 델타 리뷰 @e80186f claude·agy·grok·codex **4인 전원 PASS**(identity 4건 모두 base ed293dc → head e80186f, evidence review-tree). codex 는 1회차에서 자손 502개 등록부의 `descendants_of` 조회가 약 0.01 초임을 실측. 리포트와 identity 사이드카는 `.agents/reports/<session>/`.
- **전체 스위트 (병합 워크스페이스, 자체 venv 가 있는 워크트리 @ed293dc)**: @ed293dc 1156 통과 / 3 skip / 실패 2(공개 브로커 `no CONNACK` 재시도로 11 초 타이밍 한계를 넘긴 flake 2건, 단독 재실행 통과; 1시간 1분). @e80186f 관련 스위트(job-tree·delegation 계약·transport·loop CLI·e2e·liveness·version) 125 + 54 통과.
- **비차단 후속**: `MAM_JOB_TREE_MAX` 초과 시 대기를 건너뛰고 리뷰로 가며 표에 50행 넘게 붙을 수 있음(K2); `target_not_found` 도 래퍼 rc 가 `session_busy` 와 같은 5 라 루프의 busy 1회 재시도가 없는 대상에도 돌아감(K3, rc 분리 권고); `descendants_of`/귀속되지 않은 잡 조회가 폴링(3 초)마다 등록부 전체를 읽음(K4, 등록부 정리 정책 전까지 정보); 귀속되지 않은 열린 잡 목록은 시간 기반 휴리스틱이라 다른 루프의 잡이 섞일 수 있음(codex).
- **범위 밖**: 멈춘 에이전트 감지(#30)와 잡 제한 시간 조절(#33). 하위 잡이 권한 확인 창에 멈추면 루프는 그 잡이 #33 의 예산으로 닫힐 때까지 기다린다.
### 🚀 `v4.7.3` — Issue #36 위임 프롬프트를 argv 가 아닌 파일로 전달, 위임 실패는 종료 코드 1 (2026-09-24, PR #37)
> **패치 마일스톤 (PATCH Release)**: 리뷰 루프가 diff 를 리뷰 프롬프트에 넣어 bash 에 **단일 argv 원소**로 넘기던 탓에, 프롬프트가 Linux 의 단일 인자 상한(`MAX_ARG_STRLEN` 131,072 바이트)을 넘으면 `OSError: [Errno 7]` 로 죽고 **종료 코드 0** 으로 끝나던 문제(Issue #36)를 고쳤다. 수집기 상한 `MAM_DIFF_MAX_BYTES`(기본 200000)가 커널 상한보다 높아 그 사이 크기는 걸러지지 않았고, 커밋 10여 개 규모의 브랜치(PR #35 가 실제로 133 KB)는 루프로 리뷰할 수 없었다. 옵션 하나(`--prompt-file`)가 늘지만 잘못된 전달 경로를 고치는 수정이라 PATCH 로 올린다.