release(v4.14.0): multi-agent-mux-reset skill purges and recreates resident agents; registrations refuse during a reset; lsof holders in purge hints; codex purges its capability dir (Issue #78) - archive the review reports, bump the lockstep version

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
This commit is contained in:
GodopuandClaude Opus 5.5 committed 2026-10-30 11:43:21 +09:00
1 parent b49314c3d0
commit d400add841
24 files changed
+491 -32

No files matched your search

+43 -13
View File
@@ -6,8 +6,8 @@
## 📌 현재 버전 개요 (Current Release)
- **프레임워크 버전**: `v4.13.0`
- **최신 릴리스 일시**: 2026-10-29 (KST)
- **프레임워크 버전**: `v4.14.0`
- **최신 릴리스 일시**: 2026-10-30 (KST)
- **기준 브랜치**: `main`
- **핵심 아키텍처**:
- **Terminal 상태 단방향 불변성 (`engine.py`, Issue #6 Phase 1)**: `completed`, `error`, `cancelled` 터미널 상태 진입 후 후속 이벤트나 업데이트에 의한 덮어쓰기를 엄격히 차단(Terminal Immutability). `registry.py close` 서브커맨드 및 fail-closed 조기 종료 도입.
@@ -18,30 +18,60 @@
- **워크트리 운영 모델 2단계 (Issue #21 항목 4·5·7)**: 워크트리 준비·해체 헬퍼(변경 전 판정, untracked 포함, 검증된 단일 `--force`), 리뷰 identity(라운드별 스냅샷·stale 재리뷰·승격 직전 재확인·`identity.json`), 수용 사례 A1–A8.
- **잡 예산·라벨·멈춤 알림 (Issue #33·#30)**: 위임 잡 예산은 `--job-timeout`/`MAM_JOB_TIMEOUT_S`, 벽시계 초과는 `wall_clock_timeout`(무응답 `deadline_timeout` 과 구분), `lib_py/stall_watch.py` 가 `blocked`/`idle` 을 `progress stalled:*` 로 알리기만 한다(종결 근거는 #18 의 프로토콜 이벤트뿐).
- **설정 파일 로더 하나 (Issue #26)**: `.mam.env` 는 `lib_py/delegation/envfile.py` 한 곳이 읽는다(셸 해석 없음, 환경변수 우선, 읽을 수 없는 파일은 오류). bash 산술에 들어가는 정수 설정값은 `mam_int` 로 10진수.
- **4-Way 버전 락스텝**: `lib.sh`(`MAM_VERSION`) ↔ `lib_py/loop/eager.py`(`FRAMEWORK_VERSION`) ↔ `VERSIONS.md` ↔ 9개 `SKILL.md`.
- **4-Way 버전 락스텝**: `lib.sh`(`MAM_VERSION`) ↔ `lib_py/loop/eager.py`(`FRAMEWORK_VERSION`) ↔ `VERSIONS.md` ↔ 10개 `SKILL.md`.
---
## 🧭 스킬 패키지 버전 매트릭스 (Skills Version Matrix)
모든 9개 스킬은 YAML frontmatter 메타데이터(`author`, `version`, `platforms`, `environments`) 표준화를 통해 `v4.13.0`로 동기화되어 배포됩니다.
모든 10개 스킬은 YAML frontmatter 메타데이터(`author`, `version`, `platforms`, `environments`) 표준화를 통해 `v4.14.0`로 동기화되어 배포됩니다.
| 스킬명 | 버전 | 역할 및 주요 책임 | 상태 |
| :--- | :---: | :--- | :---: |
| **`multi-agent-mux-create`** | `4.13.0` | 에이전트 세션 신규 생성 및 Herdr 컨테이너 격리 스폰 | ✅ 배포 |
| **`multi-agent-mux-stop`** | `4.13.0` | 대화 UUID 원자적 캡처 및 세션 안전 종료 (Graceful Stop) | ✅ 배포 |
| **`multi-agent-mux-resume`** | `4.13.0` | 온디스크 대화 컨텍스트 기반 Tier-1 초고속 세션 복원 | ✅ 배포 |
| **`multi-agent-mux-status`** | `4.13.0` | 실시간 Herdr 세션 및 레지스트리 드리프트 스냅샷 조회 | ✅ 배포 |
| **`multi-agent-mux-monitor`** | `4.13.0` | YAML ↔ 런타임 상태 간 자율 조정자 (Reconciler Loop) | ✅ 배포 |
| **`multi-agent-mux-delegate-job`** | `4.13.0` | MQTT 이벤트 채널 기반 비동기 단위 작업 위임 | ✅ 배포 |
| **`multi-agent-mux-loop`** | `4.13.0` | Planner-Creator-Reviewer 3자 자율 계획·실행·피어리뷰 루프 | ✅ 배포 |
| **`multi-agent-mux-orc-onboard`** | `4.13.0` | 오케스트레이터 UUID 격리 등록 및 서브 세션 오염 방지 | ✅ 배포 |
| **`multi-agent-mux-update`** | `4.13.0` | 설치된 작업 공간의 제자리 업데이트·되돌리기와 업데이트 중 입장 차단 | ✅ 배포 |
| **`multi-agent-mux-create`** | `4.14.0` | 에이전트 세션 신규 생성 및 Herdr 컨테이너 격리 스폰 | ✅ 배포 |
| **`multi-agent-mux-stop`** | `4.14.0` | 대화 UUID 원자적 캡처 및 세션 안전 종료 (Graceful Stop) | ✅ 배포 |
| **`multi-agent-mux-resume`** | `4.14.0` | 온디스크 대화 컨텍스트 기반 Tier-1 초고속 세션 복원 | ✅ 배포 |
| **`multi-agent-mux-status`** | `4.14.0` | 실시간 Herdr 세션 및 레지스트리 드리프트 스냅샷 조회 | ✅ 배포 |
| **`multi-agent-mux-monitor`** | `4.14.0` | YAML ↔ 런타임 상태 간 자율 조정자 (Reconciler Loop) | ✅ 배포 |
| **`multi-agent-mux-delegate-job`** | `4.14.0` | MQTT 이벤트 채널 기반 비동기 단위 작업 위임 | ✅ 배포 |
| **`multi-agent-mux-loop`** | `4.14.0` | Planner-Creator-Reviewer 3자 자율 계획·실행·피어리뷰 루프 | ✅ 배포 |
| **`multi-agent-mux-orc-onboard`** | `4.14.0` | 오케스트레이터 UUID 격리 등록 및 서브 세션 오염 방지 | ✅ 배포 |
| **`multi-agent-mux-update`** | `4.14.0` | 설치된 작업 공간의 제자리 업데이트·되돌리기와 업데이트 중 입장 차단 | ✅ 배포 |
| **`multi-agent-mux-reset`** | `4.14.0` | 제어 루트의 상주 에이전트를 하나씩 purge 하고 같은 사양으로 다시 만들기 | ✅ 배포 |
---
## 📋 버전별 상세 변경 내역 (Changelog)
### 🚀 `v4.14.0` — reset 스킬로 상주 에이전트의 대화를 지우고 같은 사양으로 다시 만든다 (Issue #78) (2026-10-30)
> **마이너 (MINOR Release)**: 제어 루트의 running 에이전트를 하나씩 stop·purge 하고 같은 이름·에이전트·역할·herdr 서버·작업 공간 라벨로 다시 만드는 새 `multi-agent-mux-reset` 스킬을 더했다. reset 중에는 잡 등록이 거부된다. purge 거부 안내가 대화 파일을 쥔 프로세스를 보여 주고, codex purge 가 `tui-thread-reference-capabilities/<uuid>` 도 지운다. 새 스킬과 기존 명령의 동작(reset 중 등록 거부)이 늘어 MINOR 로 올린다. PR #82.
#### ⚠️ 호환성
- 새 스킬 `multi-agent-mux-reset`(`scripts/reset.sh --yes [--dry-run]`). 터미널이 아니면 `--yes` 가 필요하다(없으면 exit 3). 종료 코드는 0·1·2·3·4(건너뛴 에이전트 있음)·5(새 대화 ID 미기록), 신호로 끊기면 130·143·129.
- reset 이 도는 동안 그 작업 공간이 읽는 잡 레지스트리(`.mam/jobs`, `MAM_JOBS_DIR`, 행의 `control_plane.mam_jobs_dir`)에 `.reset-in-progress` 를 두고, 그 레지스트리로의 등록(`delegate-job submit`, `registry.py register`, 등록 API)은 거부된다. reset 자신의 create 온보딩만 통과한다. 표식이 없으면 등록 경로는 전과 같다.
- purge 가 사용 중이라 거부될 때(exit 4) `in_use_hints` 가 `lsof` 로 찾은 프로세스(pid, 명령줄)를 함께 출력한다. 그 프로세스는 종료하지 않는다.
- codex purge 가 `tui-thread-reference-capabilities/<uuid>` 도 지운다.
- `.claude/skills/multi-agent-mux-reset` 링크는 추적되지 않으므로 설치본이 아닌 체크아웃에서는 손으로 만든다.
#### 🌟 주요 개선 사항
1. **reset 스킬 (`multi-agent-mux-reset/scripts/reset.sh`, `lib_py/reset.py`)**:
- 대상: `status: running` 이고 `pane.cwd` 가 제어 루트인 행. 다른 상태·워크트리 행·오케스트레이터는 이유와 함께 건너뛴다.
- 사전 확인(무엇도 바꾸기 전): 열린 잡, live 루프·업데이트 표식, 행의 agent·role 누락, 대화 ID 가 없는 claude·grok, 깨진 사양 파일, 호출자 자신이 대상.
- 잠금: 업데이트 입장 잠금을 배타로 잡고 `.mam/loop-guard-active` 와 `.mam/reset-in-progress` 를 건 뒤 놓는다. 이어 읽는 레지스트리마다 그 잠금 아래에서 표식을 둔다. 다른 작업 공간의 live reset 이 같은 레지스트리를 쥐고 있으면 아무것도 바꾸지 않고 거부한다.
- 순서: 사양 파일(`.mam/reset-spec.json`)을 원자적으로 쓴 뒤 에이전트마다 ⓪ 행·열린 잡 재확인 ① stop ② 기록된 ID 와 같은지, ID 가 나중에 생기는 에이전트는 그 폴더의 대화로 검증되는지 ③ purge ④ create(온보딩). 중간에 멈추면 다시 실행해 사양 파일에서 이어 가고, 이미 다시 만든 에이전트는 다시 purge 하지 않는다.
- 결과 표: 에이전트마다 새 대화 ID 가 기록됐는지, 이전 ID 와 다른지.
2. **등록 경계 (`lib_py/delegation/registry.py`, `remote.py`, `lib.sh` `mam_reset_admit`)**: `register_job` 이 레지스트리 잠금 아래에서 reset 표식을 읽고 거부한다. 원격 runner 는 거부를 dispatch 거부로 처리한다.
3. **purge 안내와 codex (`lib_py/agents/base.py`, `adapters/{agy,codex,opencode}.py`)**: `in_use_hints` 의 `lsof` holder, codex 의 capability 디렉터리 삭제.
4. **패키징·문서**: `deploy/install.sh`·`remove.sh`·`gitea-ci.yml`, README 두 개, 스킬 코드 블록 인벤토리, 버전 매트릭스와 `test_version_consistency.py` 의 스킬 목록(10개).
#### ✅ 품질 검증
- **회귀**: `tests/test_issue78_reset.py`, `tests/test_issue78_hints_codex.py`. 신호(SIGINT·SIGTERM·SIGHUP) 중단, 재실행, 공개 등록 CLI 경합, 다른 폴더의 codex 대화 보호, 레지스트리 표식을 포함한다.
- **리뷰 (`--all-reviewer`, 리뷰 전용 루프)**: 첫 루프(@f90a705) 1회차 4명 모두 NOT PASS, 2회차 3/4 PASS. codex 가 `registry.py register` 로 reset 입장 경계를 우회하는 경합과, ID 문자열 일치만으로 다른 폴더의 codex 대화를 지우는 경우를 재현했다. creator 의 수정 잡이 예산을 넘겨 루프가 멈췄고, 수정은 548c685 로 커밋됐다. 두 번째 루프(@548c685) 1·2회차 3/4 PASS, codex 의 지적으로 레지스트리 표식을 물리 경로 기준으로 모든 레지스트리에 두고(568385c), 다른 live reset 의 표식을 가져가지 않게 했다(b49314c). 3회차(@b49314c) claude·grok·codex PASS, agy 는 프롬프트 전달 실패로 따로 리뷰해 PASS — **4/4 PASS @b49314c**. 리포트는 `.agents/reports/<session>/` 에 있다.
- **전체 스위트 (macOS, Python 3.9.6, @b49314c)**: 2336 passed, 56 skipped, 2 failed (115분). 실패 둘은 SIGINT·SIGHUP 중단 테스트로, 스위트를 `nohup … &` 로 띄워 두 신호가 무시된 채 상속된 탓이다. 그렇게 띄우지 않고 다시 돌린 신호 테스트 3개는 모두 통과했다. 실제 `~/.claude`·`/private/tmp/claude-<uid>`·herdr 서버 pane 목록·opencode 의 data·state·config·본 체크아웃의 `.mam` 에 이 실행이 남긴 것은 없었고, 본 체크아웃의 모니터는 그대로 떠 있었다.
- **작성자 확인**: Linux(@f90a705 이전) 2330 passed, 2 failed(#80 의 flake). creator 의 macOS 실행(@548c685) 2333 passed, 56 skipped, 실패 0.
- **알려진 비차단**: 레지스트리 표식은 stopped·terminated 행의 `mam_jobs_dir` 까지 만들고, 만들 수 없는 경로가 있으면 reset 이 거부된다(어느 행인지 말하지 않는다). 표식을 위해 만든 빈 디렉터리와 `.lock` 은 남는다. 두 reset 이 공유 레지스트리를 다른 순서로 잡으면 둘 다 거부될 수 있다(아무것도 바뀌지 않음). 터미널에서는 `--yes` 없이 `[y/N]` 에 y 로 답해도 진행한다.
### 🚀 `v4.13.0` — worktree creator 도 기본으로 온보딩하고, create 의 --no-onboard 는 ID 가 나중에 생기는 에이전트에 경고한다 (Issue #68) (2026-10-29)
> **마이너 (MINOR Release)**: `worktree_prepare.sh --creator-agent` 가 온보딩 없이 creator 를 만들어, agy·codex·hermes·opencode 는 첫 대화 전까지 레지스트리에 대화 ID 가 없었다. 이제 worktree creator 도 기본으로 온보딩한다. create 의 `--no-onboard` 는 남기고, ID 가 첫 턴 뒤에야 생기는 에이전트에 쓰면 경고한다. 공개 스크립트의 기본 동작이 바뀌어 MINOR 로 올린다. PR #79.