merge: docs/readme-refresh (README rewritten against the code, README.ko.md in step; v4.9.2)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
This commit is contained in:
commit
42e2a7ea9b
24 files changed
+603
-358
No files matched your search
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"loop_id": "loop-20261013T025132Z-60f239",
|
||||
"base_sha": "ae2813773c973daedd2275cb55ad340a682c3fae",
|
||||
"head_sha": "62da8056680fca939a2aff924037ed48b5f74afa",
|
||||
"tree_sha": "f549246ffbe2d5e58cb7e33c212a383cd429dce5",
|
||||
"review_commit": "62da8056680fca939a2aff924037ed48b5f74afa",
|
||||
"reviewer": "planner-reviewer-claude-01",
|
||||
"job_id": "8b2392ce",
|
||||
"verdict": "PASS",
|
||||
"transport": "herdr",
|
||||
"evidence": "review-tree",
|
||||
"isolation": "worktree",
|
||||
"verified_at": "2026-10-13T02:56:58Z"
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
# README.md / README.ko.md 4차 리뷰 — 커밋 62da805 (job 8b2392ce)
|
||||
|
||||
- 리뷰어: planner-reviewer-claude-01 (Reviewer)
|
||||
- 리뷰 identity: loop-20261013T025132Z-60f239 / base ae281377 .. head 62da8056 (커밋 1개, 두 README 각 2줄) / tree f549246f
|
||||
- 검증 경로: `/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261013T025132Z-60f239/1` — HEAD·tree 일치, `git status --porcelain` 0 줄(시작·종료). 본 체크아웃 HEAD 2ccf439(main) 변동 없음.
|
||||
- 방법: 바뀐 두 문장만 코드와 대조. `generate-env.sh`·설치기는 실행하지 않았고, 테스트도 돌리지 않았다(픽스처 집계는 `pytest --co` 에 수집 전용 플러그인을 얹어 `fixturenames` 만 셌다; `env -i`, basetemp 는 scratchpad). 실제 서버·세션·`.mam`·`.mam.env`·에이전트 홈 미접촉.
|
||||
|
||||
## 1. 두 문장의 코드 대조
|
||||
|
||||
| 문장 (README.md / README.ko.md 같은 줄) | 근거 | 판정 |
|
||||
|---|---|---|
|
||||
| **:41** `generate-env.sh` 는 `.mam.env` 가 없을 때 `.mam.env.example` 로 만들고, `--force` 는 `.mam.env.bak` 을 남기고 덮어씀 | `deploy/generate-env.sh:54-64`: `[ -f "$DST" ] && [ "$FORCE" != "1" ]` → "no-op … (use --force to overwrite)" `exit 0`; `[ -f "$DST" ] && [ "$FORCE" = "1" ]` → `cp -p "$DST" "$DST.bak"`; 그 뒤 `cp "$SRC" "$DST"`. 머리 주석(`:5-7`)과도 일치 | ✓ |
|
||||
| **:175** 모든 테스트는 임시 잡 레지스트리·감사 로그; 약 3분의 1 이 임시 HOME 샌드박스 픽스처, 그보다 적은 수가 mock herdr | 이 head 에서 수집 1901 개 중 `fixturenames` 에 `mam_sandbox` 포함 **575 (30 %)**, `mock_herdr` 포함 **186 (9 %)**(`mock_agents` 125). grok 집계(1708 중 573/196)와 모수만 다르고 비율은 같다. "약 3분의 1" 과 "그보다 적은 수" 모두 맞음. 전체 테스트의 임시 레지스트리·로그는 `conftest.py:170-181` 의 autouse 픽스처(3차에서 확인) | ✓ |
|
||||
|
||||
## 2. 두 언어의 일치
|
||||
- 두 문장 모두 영문·한국어가 같은 조건·같은 수치를 말한다(없을 때 생성 / `--force` 는 `.bak` 남기고 덮어씀; 약 3분의 1 / 그보다 적은 수).
|
||||
- 구조(head): 제목 18/18, 표 행 17/17, 코드 블록 7/7(번역 주석 블록 외 동일), 숫자 집합 동일, 백틱 토큰 차이는 `MULTI_AGENT_RULES.md` ↔ `.ko.md` 뿐.
|
||||
|
||||
## 결론
|
||||
grok 21063f28 의 두 지적이 코드와 맞게 고쳐졌고 두 언어가 같다. 앞 라운드에서 내가 남겼던 `generate-env.sh` 메모도 이 커밋으로 해소됐다. 남은 지적 없음.
|
||||
|
||||
[VERDICT: PASS]
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"loop_id": "loop-20261013T025132Z-60f239",
|
||||
"base_sha": "ae2813773c973daedd2275cb55ad340a682c3fae",
|
||||
"head_sha": "62da8056680fca939a2aff924037ed48b5f74afa",
|
||||
"tree_sha": "f549246ffbe2d5e58cb7e33c212a383cd429dce5",
|
||||
"review_commit": "62da8056680fca939a2aff924037ed48b5f74afa",
|
||||
"reviewer": "planner-reviewer-codex-01",
|
||||
"job_id": "a2716e3b",
|
||||
"verdict": "PASS",
|
||||
"transport": "herdr",
|
||||
"evidence": "review-tree",
|
||||
"isolation": "worktree",
|
||||
"verified_at": "2026-10-13T02:56:58Z"
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
# README 4차 리뷰 — a2716e3b
|
||||
|
||||
판정: PASS. 지정된 두 문장의 수정에서 차단할 사실 오류나 영문·한국어 의미 불일치를 발견하지 못했습니다.
|
||||
|
||||
## 리뷰 identity 및 범위
|
||||
|
||||
- loop: `loop-20261013T025132Z-60f239`
|
||||
- base: `ae2813773c973daedd2275cb55ad340a682c3fae`
|
||||
- head: `62da8056680fca939a2aff924037ed48b5f74afa`
|
||||
- tree: `f549246ffbe2d5e58cb7e33c212a383cd429dce5`
|
||||
- 검증 경로: `/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261013T025132Z-60f239/1`
|
||||
- HEAD/tree가 브리프와 일치하고 작업 트리가 clean임을 확인했습니다. 이번 커밋만 검토했으며, 두 README에서 각각 41행과 175행만 변경된 것을 확인했습니다.
|
||||
|
||||
## 검토 결과
|
||||
|
||||
### 1. generate-env.sh 설명 — PASS
|
||||
|
||||
`README.md:41`, `README.ko.md:41`은 대상 파일이 없을 때 생성하고, `--force`로 기존 파일을 덮어쓸 때 `.mam.env.bak`을 남긴다고 동일하게 설명합니다.
|
||||
|
||||
- `deploy/generate-env.sh:17–18`: 템플릿과 대상 경로를 `.mam.env.example`, `.mam.env`로 지정합니다.
|
||||
- 54–56행: 대상이 있고 `--force`가 없으면 성공 코드로 종료하며 변경하지 않습니다.
|
||||
- 59–61행: 대상이 있고 `--force`가 있으면 `cp -p "$DST" "$DST.bak"`으로 백업합니다.
|
||||
- 64행: 템플릿을 대상으로 복사합니다.
|
||||
|
||||
머리 주석 5–7행뿐 아니라 실제 분기를 확인했습니다. 별도 옵션인 `--migrate-legacy`는 이번 문구의 기본 생성/force 설명과 충돌하지 않습니다. 스크립트는 실행하지 않았습니다.
|
||||
|
||||
### 2. 테스트 격리 범위 — PASS
|
||||
|
||||
`README.md:175`, `README.ko.md:175`은 모든 테스트의 임시 잡 경로와 일부 테스트가 쓰는 임시 HOME/mock herdr를 구별합니다.
|
||||
|
||||
- `tests/conftest.py:170–181`: autouse `_isolate_mam_state_dirs`가 테스트별 임시 잡 레지스트리와 감사 로그 경로를 설정합니다.
|
||||
- 195–207행: autouse 에이전트 환경 정리 자체는 HOME을 바꾸지 않는다고 명시합니다.
|
||||
- 228–269행: 선택적 `mam_sandbox`가 HOME과 레지스트리를 임시 경로로 설정합니다.
|
||||
- 312–315행: 별도 `mock_herdr` 픽스처가 `mam_sandbox`에 의존하여 mock 실행 파일을 제공합니다. 샌드박스 사용 자체가 mock 사용을 의미하지 않습니다.
|
||||
|
||||
브리프에 제시된 수집 항목 집계는 1708개 중 샌드박스 573개(33.55%), mock 196개(11.48%)이므로 새 표현과 맞습니다. 이 정확한 pytest 수집 수는 재수집하지 않았습니다. 독립적인 AST 정적 확인에서는 테스트 함수 정의 1272개 중 명시적 인자/데코레이터 및 픽스처 의존 경로로 `mam_sandbox` 485개, `mock_herdr` 168개를 확인했습니다. 이 수치는 매개변수화된 pytest 항목 수가 아니며, 클래스/모듈 수준의 간접 지정까지 완전 재현한 집계도 아닙니다. “대부분”이라는 이전 과장을 제거하고 mock 사용 범위를 더 좁힌 수정 방향을 뒷받침하는 보조 확인으로만 사용했습니다.
|
||||
|
||||
## 검증 및 제한
|
||||
|
||||
- `git diff --check ae28137..HEAD`: 성공.
|
||||
- 양 문서의 변경 행이 정확히 `[41, 175]`이며 줄 수가 유지됨을 정적 검사로 확인했습니다. 나머지 문장·명령·다이어그램은 이번 커밋에서 바뀌지 않았습니다.
|
||||
- 두 변경 문장의 조건과 수량 표현이 EN/KO에서 일치합니다.
|
||||
- 테스트, 설치기, 환경 생성 스크립트, 실제 herdr/에이전트/monitor는 실행하지 않았습니다. 지정 리뷰 트리의 파일만 읽었고 소스·문서·실제 설정 파일을 수정하지 않았습니다. pytest 전체 통과 또는 정확한 수집 수 재현을 주장하지 않습니다.
|
||||
|
||||
[VERDICT: PASS]
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"loop_id": "loop-20261013T025132Z-60f239",
|
||||
"base_sha": "ae2813773c973daedd2275cb55ad340a682c3fae",
|
||||
"head_sha": "62da8056680fca939a2aff924037ed48b5f74afa",
|
||||
"tree_sha": "f549246ffbe2d5e58cb7e33c212a383cd429dce5",
|
||||
"review_commit": "62da8056680fca939a2aff924037ed48b5f74afa",
|
||||
"reviewer": "reviewer-agy-01",
|
||||
"job_id": "f3b2d22c",
|
||||
"verdict": "PASS",
|
||||
"transport": "herdr",
|
||||
"evidence": "review-tree",
|
||||
"isolation": "worktree",
|
||||
"verified_at": "2026-10-13T02:56:58Z"
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
# Code Review Report (4th Round): `docs/readme-refresh` (README.md & README.ko.md Targeted Refinement)
|
||||
|
||||
- **Job ID**: `f3b2d22c`
|
||||
- **Reviewer**: `agy` (Session: `herdr:reviewer-agy-01`, Role: `Reviewer`)
|
||||
- **Date**: 2026-10-13
|
||||
- **Target Branch**: `docs/readme-refresh`
|
||||
- **Base Commit**: `ae2813773c973daedd2275cb55ad340a682c3fae`
|
||||
- **Head Commit**: `62da8056680fca939a2aff924037ed48b5f74afa`
|
||||
- **Verification Path**: `/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261013T025132Z-60f239/1`
|
||||
- **Verification Environment**: macOS (Darwin 24.3.0, arm64), Python 3.9.6
|
||||
|
||||
---
|
||||
|
||||
## 1. Executive Summary
|
||||
|
||||
This 4th-round review evaluated commit [`62da8056680fca939a2aff924037ed48b5f74afa`](file:///var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261013T025132Z-60f239/1), which addresses 3rd-round reviewer feedback (grok `21063f28`) regarding two targeted descriptions across [`README.md`](file:///var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261013T025132Z-60f239/1/README.md) and [`README.ko.md`](file:///var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261013T025132Z-60f239/1/README.ko.md):
|
||||
1. Clarification that [`deploy/generate-env.sh`](file:///var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261013T025132Z-60f239/1/deploy/generate-env.sh) creates `.mam.env` only when missing, and `--force` backs up `.mam.env` to `.mam.env.bak` before overwriting.
|
||||
2. Accurate quantification of test isolation fixtures: all tests get temporary job registry and audit-log directories, while roughly one-third use sandbox temporary HOME fixtures, and an even smaller subset use mock herdr.
|
||||
|
||||
Both changes have been verified against the codebase and found factually accurate. Bilingual parity between English and Korean is fully preserved.
|
||||
|
||||
**Verdict: PASS**.
|
||||
|
||||
---
|
||||
|
||||
## 2. Technical Item Verification
|
||||
|
||||
### 2.1 `deploy/generate-env.sh` Behavior
|
||||
- **Code Inspection** ([`deploy/generate-env.sh:54-64`](file:///var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261013T025132Z-60f239/1/deploy/generate-env.sh#L54-L64)):
|
||||
- If `.mam.env` exists and `--force` is not passed, the script exits immediately with no-op:
|
||||
```bash
|
||||
if [ -f "$DST" ] && [ "$FORCE" != "1" ]; then
|
||||
echo "no-op: $DST already exists (use --force to overwrite)"
|
||||
exit 0
|
||||
fi
|
||||
```
|
||||
- If `.mam.env` exists and `--force` is passed, it creates a backup copy at `.mam.env.bak` before overwriting:
|
||||
```bash
|
||||
if [ -f "$DST" ] && [ "$FORCE" = "1" ]; then
|
||||
cp -p "$DST" "$DST.bak"
|
||||
echo "backed up existing .mam.env -> $DST.bak"
|
||||
fi
|
||||
cp "$SRC" "$DST"
|
||||
```
|
||||
- **Documentation Verification**:
|
||||
- *EN*: `deploy/generate-env.sh creates .mam.env from .mam.env.example when it is missing (--force overwrites it, keeping a .mam.env.bak).`
|
||||
- *KO*: `deploy/generate-env.sh 는 .mam.env 가 없을 때 .mam.env.example 로 만듭니다(--force 는 .mam.env.bak 을 남기고 덮어씁니다).`
|
||||
- **Evaluation**: Accurately reflects the conditional creation and backup semantics of `generate-env.sh`.
|
||||
|
||||
### 2.2 Test Isolation Scoping & Proportions
|
||||
- **Code Inspection** ([`tests/conftest.py`](file:///var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261013T025132Z-60f239/1/tests/conftest.py)):
|
||||
- `_isolate_mam_state_dirs` is `autouse=True`, executing for 100% of tests.
|
||||
- Of 1,272 test functions defined across `tests/`, 418 (~32.8%, roughly one-third) declare sandbox fixtures (`mam_sandbox`, `temp_home`), and only 158 declare `mock_herdr`.
|
||||
- **Documentation Verification**:
|
||||
- *EN*: `Every test gets a temporary job registry and audit-log directory. About a third also use the sandbox fixtures, which set a temporary HOME (and, for fewer, a mock herdr):`
|
||||
- *KO*: `모든 테스트는 임시 잡 레지스트리와 감사 로그 디렉터리를 씁니다. 약 3분의 1 은 임시 HOME 을 설정하는 샌드박스 픽스처도 쓰고, 그보다 적은 수는 mock herdr 도 씁니다.`
|
||||
- **Evaluation**: The replacement of "most" with "about a third" (and fewer for mock herdr) accurately aligns the documentation with actual test fixture distribution.
|
||||
|
||||
---
|
||||
|
||||
## 3. Bilingual Alignment & Integrity
|
||||
- Both updated lines in [`README.md`](file:///var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261013T025132Z-60f239/1/README.md) and [`README.ko.md`](file:///var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20261013T025132Z-60f239/1/README.ko.md) maintain exact semantic, technical, and structural parity.
|
||||
- Markdown formatting, links, and code backticks remain intact and consistent.
|
||||
|
||||
---
|
||||
|
||||
[VERDICT: PASS]
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"loop_id": "loop-20261013T025132Z-60f239",
|
||||
"base_sha": "ae2813773c973daedd2275cb55ad340a682c3fae",
|
||||
"head_sha": "62da8056680fca939a2aff924037ed48b5f74afa",
|
||||
"tree_sha": "f549246ffbe2d5e58cb7e33c212a383cd429dce5",
|
||||
"review_commit": "62da8056680fca939a2aff924037ed48b5f74afa",
|
||||
"reviewer": "reviewer-grok-01",
|
||||
"job_id": "2311b972",
|
||||
"verdict": "PASS",
|
||||
"transport": "herdr",
|
||||
"evidence": "review-tree",
|
||||
"isolation": "worktree",
|
||||
"verified_at": "2026-10-13T02:56:58Z"
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
# Review 2311b972 — test share and generate-env.sh
|
||||
|
||||
Head `62da8056680fca939a2aff924037ed48b5f74afa` (tree `f549246ffbe2d5e58cb7e33c212a383cd429dce5`) is the one commit `62da805 docs(readme): round-3 review fixes (21063f28)` on base `ae2813773c973daedd2275cb55ad340a682c3fae`. Two files, `README.md` and `README.ko.md`, two lines each, +4/−4. `git diff --check` is clean. Snapshot porcelain empty. Control-plane main is still `2ccf43911cda78fd0655c3770eec90cd22ec2d1b`, porcelain empty.
|
||||
|
||||
## The two sentences match
|
||||
|
||||
`README.md:175` says every test gets a temporary job registry and audit-log directory, about a third also use the sandbox fixtures that set a temporary HOME, and fewer of those use a mock herdr. That is the count from the previous review of this same test tree: weighting the parametrize lists written out in the source, 573 of 1708 (34%) reach a temporary HOME and 196 of 1708 (11%) reach `mock_herdr`. The autouse fixture still points every test's registry and audit log at a temporary directory (`tests/conftest.py:170-186`). `README.ko.md:175` says the same fraction and the same split.
|
||||
|
||||
`README.md:41` says `deploy/generate-env.sh` creates `.mam.env` from `.mam.env.example` when `.mam.env` is missing, and that `--force` overwrites it while keeping a `.mam.env.bak`. The script copies the example when the destination is absent (`deploy/generate-env.sh:54-64`). When the destination exists and `--force` is absent, it exits 0 without writing (`:54-57`). With `--force` and an existing file, it copies that file to `$DST.bak`, which is `.mam.env.bak`, and then copies the example over it (`:59-64`). `README.ko.md:41` says the same.
|
||||
|
||||
The script was not executed. No herdr server was started. The suite was not run.
|
||||
|
||||
User `~/.config/herdr/config.toml` mtime stayed `1784456394`.
|
||||
|
||||
[VERDICT: PASS]
|
||||
@@ -29,7 +29,7 @@ export WORKSPACE_ROOT
|
||||
# Framework semantic version. Single runtime source of truth; kept in lockstep
|
||||
# with VERSIONS.md and the 8 SKILL.md frontmatters by tests/test_version_consistency.py.
|
||||
# NOTE: unlike other MAM_* variables this one is intentionally NOT env-overridable.
|
||||
MAM_VERSION="4.9.1"
|
||||
MAM_VERSION="4.9.2"
|
||||
export MAM_VERSION
|
||||
AGENT_SESSIONS_YAML="${AGENT_SESSIONS_YAML:-$WORKSPACE_ROOT/.mam/agent-sessions.yaml}"
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import sys
|
||||
from typing import List, Sequence
|
||||
|
||||
# Framework version locked with framework constants
|
||||
FRAMEWORK_VERSION = "4.9.1"
|
||||
FRAMEWORK_VERSION = "4.9.2"
|
||||
|
||||
CORE_MODULES: Sequence[str] = (
|
||||
# Standard library modules
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: multi-agent-mux-create
|
||||
description: "Create a new agent session (claude, antigravity/agy) in a dedicated herdr session for context-preserving long-running work. Always creates a herdr session — never backgrounds with nohup/disown. Writes the new session to .mam/agent-sessions.yaml. Use when you want to start a fresh agent (no prior UUID) for a new project workspace."
|
||||
version: 4.9.1
|
||||
version: 4.9.2
|
||||
author: godopu
|
||||
license: MIT
|
||||
platforms: [linux, macos]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: multi-agent-mux-delegate-job
|
||||
description: "Delegate a unit of work to any autonomous agent (claude-code, hermes, agy, grok-build, codex, or a human) and observe it asynchronously over an MQTT event channel. Supported roles include orchestrator, worker, and reviewer."
|
||||
version: 4.9.1
|
||||
version: 4.9.2
|
||||
author: godopu
|
||||
license: MIT
|
||||
platforms: [linux, macos, windows]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: multi-agent-mux-loop
|
||||
description: "Run an autonomous planning-execution-review loop using multiple agents (Planner, Creator, Reviewers) in the workspace. Automatically orchestrates plan discussion, code changes, and peer reviews until a unanimous PASS is achieved or the maximum iteration limit is reached."
|
||||
version: 4.9.1
|
||||
version: 4.9.2
|
||||
author: godopu
|
||||
license: MIT
|
||||
platforms: [linux, macos]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: multi-agent-mux-monitor
|
||||
description: "Run a long-lived reconciler that watches .mam/agent-sessions.yaml against the actual herdr/agent runtime state and reconciles them. Use when you want live visibility into which agent sessions are running, which are dead, which have stale YAML entries, and which have new session ids that haven't been recorded yet. Runs as a persistent loop (`reconcile.sh --subscribe`) that keeps going until it times out, idles out, or is interrupted."
|
||||
version: 4.9.1
|
||||
version: 4.9.2
|
||||
author: godopu
|
||||
license: MIT
|
||||
platforms: [linux, macos]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: multi-agent-mux-orc-onboard
|
||||
description: "Register current or specified orchestrator session UUID into agent-sessions.yaml orchestrator_uuids list to prevent sub-agent discovery capture."
|
||||
version: 4.9.1
|
||||
version: 4.9.2
|
||||
author: godopu
|
||||
license: MIT
|
||||
platforms: [linux, macos]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: multi-agent-mux-resume
|
||||
description: "Resume an existing agent (claude, antigravity/agy) conversation by UUID into a herdr session. Reads .mam/agent-sessions.yaml for the saved session/conversation id, spawns (or reuses) a herdr session of the matching name, and runs `claude -r <id>` or `agy --conversation <id>` inside. Use when you want to reattach to a previous session's context, or revive a session whose herdr died but the agent's conversation is still on disk."
|
||||
version: 4.9.1
|
||||
version: 4.9.2
|
||||
author: godopu
|
||||
license: MIT
|
||||
platforms: [linux, macos]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: multi-agent-mux-status
|
||||
description: "Read-only instant snapshot of all agent herdr sessions — name, YAML status, herdr alive, pane cmd/cwd, resume UUID on disk, and any drift. No mutation. Reuses reconcile.sh --dry-run for the diff logic. Use when you want to know 'what's running RIGHT NOW' without spinning up the monitor loop."
|
||||
version: 4.9.1
|
||||
version: 4.9.2
|
||||
author: godopu
|
||||
license: MIT
|
||||
platforms: [linux, macos]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: multi-agent-mux-stop
|
||||
description: "Stop an agent herdr session (claude, antigravity/agy) and update .mam/agent-sessions.yaml. Default stops gracefully and marks status=stopped with conversation preserved for resume. Does NOT delete on-disk conversation artifacts (jsonl/db) — those are preserved unless --purge-conversation is passed. Use when ending a work session, switching to a different one, or cleaning up before a fresh start."
|
||||
version: 4.9.1
|
||||
version: 4.9.2
|
||||
author: godopu
|
||||
license: MIT
|
||||
platforms: [linux, macos]
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
본 문서는 `herdr_agent_orchestration` 오케스트레이션 및 메시징 백플레인 워크플로우를 새로운 프로젝트에 도입하여 이식하고, 새로운 개발자/에이전트가 초기 가동을 시작할 때 수행해야 하는 환경 설정 및 구축 절차를 안내합니다.
|
||||
|
||||
[](VERSIONS.md)
|
||||
[](VERSIONS.md)
|
||||
|
||||
새로운 에이전트는 이 안내서에 기술된 절차를 순차적으로 실행하여 초기 환경을 안정적으로 설정할 수 있습니다.
|
||||
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
This document guides you through the setup and initialization procedures required to adopt the `herdr_agent_orchestration` orchestration and messaging backplane workflow in a new project, enabling a new developer or agent to get up and running quickly.
|
||||
|
||||
[](VERSIONS.md)
|
||||
[](VERSIONS.md)
|
||||
|
||||
A new agent can follow the steps in this guide sequentially to establish a stable and reliable initial environment.
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# Messaging System Technical Analysis & Architecture Report
|
||||
|
||||
Applies to: MAM v4.9.1
|
||||
Applies to: MAM v4.9.2
|
||||
|
||||
This report provides a comprehensive, deep-dive analysis of the messaging system implemented in the `multi-agent-mux-delegate-job` skill. It covers the MQTT broker architecture, event protocols, job lifecycles, codebase internals, cross-system integration, and a list of known limitations along with production recommendations.
|
||||
|
||||
|
||||
+192
-169
@@ -1,219 +1,242 @@
|
||||
# herdr-agent-orchestration (다중 에이전트 Herdr 오케스트레이션 및 메시징 백플레인)
|
||||
|
||||
Herdr와 MQTT 브로커를 기반으로 구축된 고신뢰성 **다중 에이전트 오케스트레이션 및 메시징 백플레인** 프레임워크입니다. `claude`, `agy`, `hermes`, `grok`, `opencode`, `codex` 등 다중 LLM 백엔드 에이전트 전반에 걸쳐 장시간 수행되는 작업(코드 생성, 리팩토링, 보안 검토 등)을 조정, 격리 및 감사할 수 있도록 설계되었습니다.
|
||||
[herdr](https://herdr.dev)와 MQTT 위에 만든 **다중 에이전트 오케스트레이션·메시징 백플레인**입니다. 장시간 실행되는 코딩 에이전트(`claude`, `agy`, `hermes`, `grok`, `opencode`, `codex`)를 격리된 herdr pane 에서 돌리고, 작업을 추적되는 잡으로 위임하며, 모든 리뷰어가 통과시킬 때까지 planner / creator / reviewer 루프를 돌립니다.
|
||||
|
||||
[](VERSIONS.md)
|
||||
[](VERSIONS.md)
|
||||
|
||||
---
|
||||
|
||||
## 🚀 개요
|
||||
|
||||
최근의 에이전트 워크플로우는 세션 타임아웃, 프로세스 격리 부재, 터미널 뷰포트 잘림(스크롤백 한계로 인한 디버그 로그 유실), 복잡한 동시성 경쟁 등의 문제를 자주 겪습니다.
|
||||
긴 에이전트 작업은 정해진 방식으로 깨집니다. 터미널과 함께 세션이 죽고, 한 pane 에 잡 두 개가 들어가고, 오케스트레이터는 바쁜 에이전트와 죽은 에이전트를 구분하지 못하고, 리뷰는 읽은 뒤에 바뀐 코드를 승인합니다. Multi-Agent Mux(MAM)는 이를 다음으로 막습니다.
|
||||
|
||||
**herdr-agent-orchestration**은 다음과 같은 솔루션을 통해 이를 해결합니다:
|
||||
1. **Herdr 기반 프로세스 격리:** 개별적으로 격리된 herdr 환경 내부에 에이전트 CLI 세션을 띄워, 백그라운드에서 끊김 없이 장시간 작업이 영속되도록 보장합니다. 백그라운드 데몬 서버는 독립된 OS 세션/프로세스 그룹(`start_new_session=True`)으로 분리되어 부모 셸의 시그널 브로드캐스트로부터 안전하게 격리됩니다.
|
||||
2. **비동기 이벤트 기반 아키텍처:** MQTT 브로커를 메시징 백플레인으로 활용하여, 에이전트 간 상태 전이 단계(`started`, `progress`, `completed`, `error`)를 긴밀하게 제어 및 조정합니다.
|
||||
3. **Multi-Agent Mux (MAM):** 파일 기반의 어드바이저리 락(`fcntl`) 및 SQLite WAL 데이터베이스(`.mam/agent-sessions.db`)를 결합하여, 동시성 작업 선점 경쟁을 방지하고 에이전트 세션의 라이프사이클을 드리프트 없이 관리합니다.
|
||||
4. **리뷰어 기반 고신뢰 검증 루프:** Worker 에이전트가 구현한 코드 변경 사항에 대해 상이한 강점을 지닌 전문 검증 에이전트(Claude, Hermes, Grok, OpenCode, Codex 등)들로부터 최종 `PASS` 판정을 획득한 뒤 머지하도록 교차 검증 루프를 자동화합니다.
|
||||
1. **격리되고 재개 가능한 에이전트 세션.** 에이전트마다 자기 herdr pane 에서 돌고, 보통 워크스페이스 전용 herdr 서버를 씁니다. 세션은 대화 ID 와 함께 `.mam/agent-sessions.yaml`(SQLite 백업)에 기록되므로, 멈춘 에이전트를 나중에 같은 대화로 재개할 수 있습니다.
|
||||
2. **화면이 아니라 이벤트로 판정하는 잡.** 위임 잡은 레지스트리 레코드와 MQTT 이벤트 흐름(`started`, `progress`, `completed`, `error`)입니다. 에이전트는 정해진 시간 안에 프롬프트 수신을 알리고, 일하는 동안 heartbeat 를 보내야 합니다. 잡을 닫는 것은 프로토콜 이벤트나 시간 초과뿐이며, 터미널을 읽어 판정하지 않습니다.
|
||||
3. **세션당 한 번에 잡 하나.** 프롬프트를 넣기 전에 디스패처가 레지스트리로 그 세션의 앞선 잡(온보딩 포함)이 끝나기를 기다립니다. pane 배치는 herdr 서버마다 직렬화되어, 동시에 실행한 `create` 가 같은 pane 을 차지하지 않습니다.
|
||||
4. **근거를 고정한 리뷰 루프.** `multi-agent-mux-loop` 는 변경을 선택한 리뷰어에게 보내고, 그 전원의 `PASS` 를 요구합니다. 리뷰어는 `--reviewer` 로 지정하거나 `--all-reviewer` 로 실행 중인 리뷰어 전원을 고르며, 둘 다 없으면 creator 가 스스로 리뷰합니다. `--worktree`/`--base` 를 쓰면 리뷰 라운드마다 소스 스냅샷에 묶이며, 라운드 중 소스가 바뀌면 그 승인은 버리고 다시 리뷰합니다.
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ 핵심 스킬 및 구조
|
||||
## 📦 설치 및 설정
|
||||
|
||||
모든 오케스트레이션 스킬들은 `.agents/skills/` 디렉터리 하위에 정의되어 있습니다:
|
||||
아무 워크스페이스 디렉터리에서 MAM 을 설치합니다:
|
||||
|
||||
* **`multi-agent-mux-create`**: 격리된 herdr 세션을 생성하고 특정 에이전트 CLI를 백그라운드에서 구동합니다. 프로세스 PID 캡처, 메타데이터 레지스트리 업데이트 및 에이전트 인증 검증을 처리합니다.
|
||||
* **`multi-agent-mux-stop`**: 에이전트 CLI 세션을 정상 종료 키 입력(`/exit` 또는 `Exit`)을 통해 안전하게 닫고, 격리된 대화 히스토리 및 데이터베이스 로그를 삭제(purge)하는 클린업 작업을 수행합니다.
|
||||
* **`multi-agent-mux-resume`**: 디스크 또는 캐시에서 특정 워크스페이스의 세션 UUID를 조회하여 기존 대화 상태(`claude -r <uuid>`, `agy --conversation <uuid>`, `hermes --resume <uuid>`, `grok --resume <uuid>`, `opencode --session <uuid>`, `codex resume <uuid>`) 그대로 세션을 복구하고 재개합니다.
|
||||
* **`multi-agent-mux-status`**: 활성화된 모든 세션의 실시간 작동 상태를 쿼리하여 PID 정합성, 실행 명령 포맷, herdr 실제 상태와 데이터베이스 간의 동기화 드리프트를 감지합니다.
|
||||
* **`multi-agent-mux-monitor`**: 백그라운드 Reconcile 프로세스로 실행되어, 실시간 herdr 세션 변화를 모니터링하고 `.mam/agent-sessions.yaml` 메타데이터 파일에 상태를 동기화합니다.
|
||||
* **`multi-agent-mux-delegate-job`**: 태스크를 비동기식 독립 잡으로 위임 및 관리하는 핵심 모듈입니다 (본체 구현은 `.agents/skills/lib_py/delegation/`에 위치하며, `scripts/*.py`는 하위 호환 shim):
|
||||
* `registry.py`: 파일 락(`fcntl`)을 활용해 경쟁 조건 없이 잡을 원자적으로 등록 및 점유(claim)합니다.
|
||||
* `job_subscriber.py`: MQTT 백플레인 채널을 구독하여 실시간 상태 이벤트를 수집하고 이를 감사 로그(audit trail)에 기록합니다.
|
||||
* `publish_event.py`: 실행 상태 전환 및 세부 에러 내용을 워크스페이스 스크립트에서 백플레인으로 발행합니다.
|
||||
* `mqtt_common.py`: 브로커 접속 규칙, 크레덴셜 인증 및 HMAC 서명 기능을 공통 관리합니다.
|
||||
* **`multi-agent-mux-loop`**: Planner, Creator, Reviewer 3자 간의 자율적인 계획-실행-교차검증 반복 순환 루프를 구동합니다 (Python 루프 런타임 `lib_py.loop`, eager-import 불변 런타임, strict verdict parser 기반).
|
||||
* **`multi-agent-mux-orc-onboard`**: 오케스트레이터 UUID를 레지스트리에 격리 등록하여 서브 에이전트 자동 탐색 오염을 방지합니다.
|
||||
|
||||
---
|
||||
|
||||
## 📐 전체 아키텍처 구성 (Big-Picture Architecture)
|
||||
|
||||
이 시스템은 크게 두 가지 계층(Layer)을 통해 다중 워크스페이스에서 작동하는 LLM 에이전트들을 조율합니다:
|
||||
|
||||
1. **Layer A — Herdr 오케스트레이션 (lib.sh + status/resume/stop/create)**: 워크스페이스별 에이전트 세션을 독립된 herdr 인스턴스로 분리 실행하고, `.mam/agent-sessions.yaml` 및 SQLite 데이터베이스(`.mam/agent-sessions.db`)를 통해 에이전트 세션 메타데이터의 단일 참조 지점(Single Source of Truth)을 유지합니다.
|
||||
2. **Layer B — 비동기 잡 위임 (delegate-job)**: 에이전트에 특정 태스크를 전송하고 비동기 이벤트 채널(MQTT)을 통해 진행 상황과 완료 여부를 모니터링합니다.
|
||||
|
||||
두 레이어는 파일 I/O 처리를 위한 하나의 핵심 관문인 `lib.sh::atomic_dump_yaml`을 공유합니다. 모든 YAML/DB 쓰기 작업은 SQLite 데이터베이스 트랜잭션 락과 데이터 스키마 유효성 검증을 거칩니다.
|
||||
|
||||
### 데이터 흐름 개요 (Data Flow)
|
||||
|
||||
```text
|
||||
+-----------+ register_job +-------------------+
|
||||
| delegator | ---------------> | .mam/jobs/<id>.json| <-- 실시간 잡 정보
|
||||
+-----------+ +---------+---------+
|
||||
|
|
||||
| atomic rename + fsync
|
||||
v
|
||||
+-----------------+
|
||||
| audit log | <-- 추가 전용
|
||||
| .mam/delegate_ | events.ndjson
|
||||
| job_logs/<id>/ |
|
||||
+--------+--------+
|
||||
^
|
||||
| (최선 노력 미러링)
|
||||
|
|
||||
+-----------+ publish_event +-----+-----+ +---------+
|
||||
| agent | ---------------> | MQTT broker | <--- | monitor |
|
||||
| (claude) | +-------------+ +----+----+
|
||||
+-----------+ |
|
||||
^ v
|
||||
| 구독자(subscriber) atomic_dump_yaml
|
||||
| (job_subscriber.py) (.mam/agent-sessions.yaml)
|
||||
| ^
|
||||
+-------- 위임 대기 영역 -----------------+ |
|
||||
+---+---+
|
||||
| reconcil|
|
||||
| e.sh |
|
||||
+--------+
|
||||
```bash
|
||||
curl -fsSL https://git.godopu.com/tmpl/multi-agent-mux/raw/branch/main/deploy/install.sh | bash
|
||||
```
|
||||
|
||||
### 🔒 Herdr 서버 격리 (Herdr Server Isolation)
|
||||
로컬 클론에서는:
|
||||
|
||||
에이전트 세션 간의 충돌 및 시스템 전역 herdr 프로세스와의 혼선을 막기 위해 독립된 서버 소켓 환경을 보장합니다:
|
||||
* **워크스페이스별 심(Shim):** `_init_herdr_isolation` 및 `_resolve_real_herdr_path` 함수가 `/tmp/multi-agent-herdr-shim/<HERDR_SERVER_NAME>/herdr` 경로에 독립된 심 디렉터리를 구성하고, 일반 herdr 명령 실행 시 자동으로 `herdr -L <server>` 형태의 독립 소켓 서버를 사용하게 만듭니다.
|
||||
* **PATH 환경변수 변조:** 자식 프로세스를 생성할 때 `PATH` 변수 맨 앞에 심 디렉터리 경로를 삽입합니다. 이로 인해 에이전트의 내부 셸에서 수행되는 모든 `herdr` 명령어는 해당 격리 서버 소켓으로 강제 제약됩니다.
|
||||
* **환경 복구:** `HERDR_SERVER_NAME`을 `default`로 설정하는 경우 PATH 오버라이드가 정리되고 기본 전역 herdr 서버를 사용하게 됩니다.
|
||||
```bash
|
||||
bash deploy/install.sh
|
||||
```
|
||||
|
||||
### 🛡️ 동시성 설계 및 쓰기 직렬화
|
||||
`install.sh` 는 여러 번 실행해도 안전합니다. 하는 일은 다음과 같습니다.
|
||||
- herdr 와 Python 3.9+ 가 설치돼 있는지, 시스템 `python3` 에 PyYAML 이 있는지 확인합니다.
|
||||
- `.agents/` 와 `.mam.env.example` 을 워크스페이스에 복사합니다.
|
||||
- `.venv` 를 만들고 `paho-mqtt`·PyYAML 을 설치합니다.
|
||||
- `MQTT_BROKER=localhost` 로 된 초기 `.mam.env` 를 씁니다. 이미 있는 `.mam.env` 는 그대로 둡니다. 예전 `.env` 만 있으면 그것을 `.mam.env` 로 복사하고 원본은 남깁니다.
|
||||
- `.venv`, `.mam/`, `.mam.env` 를 `.gitignore` 에 추가합니다.
|
||||
|
||||
여러 에이전트가 동시에 실행될 때의 레이스 컨디션을 방지하기 위해 락 기반의 실행 패턴을 고수합니다:
|
||||
* **SQLite 데이터베이스 락 (`BEGIN IMMEDIATE`):** `agent-sessions.yaml` 또는 SQLite 레지스트리에 쓰기 연산을 진행할 때, 반드시 `lib.sh` 내부의 `atomic_dump_yaml` 함수를 거쳐 SQLite 데이터베이스 `.mam/agent-sessions.db`에 `BEGIN IMMEDIATE` 트랜잭션 락을 획득하도록 직렬화합니다.
|
||||
* **이중 인터프리터 분리 구조:** 라이브러리 간 의존성 충돌과 실행 도구의 안정성을 보장하기 위해 환경을 이원화했습니다. MQTT 및 비동기 작업 통신에는 가상환경 `.venv` (paho-mqtt 필요)의 Python을 사용하고, YAML 직렬화 쓰기 및 유효성 검증을 담당하는 `atomic_dump_yaml`은 시스템 전역 `python3` (시스템 PyYAML 필요)을 호출합니다.
|
||||
* **NFS 및 네트워크 파일시스템 대응:** 네트워크 디바이스(NFS, CIFS, SSHFS)에서는 파일 락(`flock`) 및 SQLite WAL 기능이 오작동할 수 있습니다. `lib.sh`는 쓰기 대상 파일시스템 경로의 마운트 타입을 체크하여, 네트워크 파일시스템 감지 시 경고 로그를 출력하고 SQLite의 저널 모드를 `WAL`에서 `DELETE`로 자동 전환해 동시성 안전을 강화합니다.
|
||||
`.mam.env` 의 `MQTT_BROKER` 를 직접 운영하는 브로커로 바꾸십시오(사설 브로커는 [MESSAGING.md](MESSAGING.md) 참고). `MQTT_BROKER` 가 아예 설정되지 않으면 코드는 공개 브로커 `broker.hivemq.com` 을 씁니다. 시험용으로는 괜찮지만 실제 작업용은 아닙니다. `deploy/generate-env.sh` 는 `.mam.env` 가 없을 때 `.mam.env.example` 로 만듭니다(`--force` 는 `.mam.env.bak` 을 남기고 덮어씁니다). 업데이트와 제거는 `deploy/update.sh`, `deploy/remove.sh` 입니다. `deploy/install_mam.sh` 는 로컬 클론에서 다른 디렉터리로 복사해 설치하는 별도 설치기입니다.
|
||||
|
||||
---
|
||||
|
||||
## 📐 아키텍처 및 조정 루프 (Review Loop)
|
||||
## 🛠️ 핵심 스킬
|
||||
|
||||
Project Manager(PM), Worker, Reviewer 역할 간의 협업 구조는 엄격한 교차 검증 루프를 따릅니다:
|
||||
모든 스킬은 `.agents/skills/` 아래에 있고, 각 `SKILL.md` 가 옵션과 종료 코드를 설명합니다.
|
||||
|
||||
| 스킬 | 하는 일 |
|
||||
|---|---|
|
||||
| **`multi-agent-mux-create`** | 에이전트를 herdr pane 에서 시작하고 세션을 등록합니다. `--onboard` 는 온보딩 잡이 끝날 때까지 기다립니다(실패하면 종료 코드 44, 시간 안에 끝나지 않으면 45; 세션은 남김). `scripts/worktree_prepare.sh` 는 creator 용 이슈 워크트리를 준비합니다. |
|
||||
| **`multi-agent-mux-stop`** | 세션을 정상 종료합니다. 대화 ID 를 행에 저장합니다(`status: stopped`, `resumable: true`). `--purge-conversation --yes` 는 대신 대화를 지웁니다. `scripts/worktree_remove.sh` 는 서브모듈까지 깨끗한지 확인한 뒤에만 이슈 워크트리를 지웁니다. |
|
||||
| **`multi-agent-mux-resume`** | 멈춘 세션을 저장된 대화로 되살립니다(`claude -r`, `agy --conversation`, `hermes --resume`, `grok --resume`, `opencode --session`, `codex resume`). 세션이 원래 돌던 디렉터리에서만 재개합니다. |
|
||||
| **`multi-agent-mux-status`** | 모든 세션의 읽기 전용 스냅샷: 레지스트리 상태, herdr 생존, pane 명령과 cwd, 재개 ID, 불일치(drift). |
|
||||
| **`multi-agent-mux-monitor`** | 장기 실행 조정자(`reconcile.sh --subscribe`). 잡 이벤트에 반응하고, 브로커가 죽으면 폴링으로 돌아가며, 레지스트리 불일치를 고칩니다. 예를 들어 죽은 세션을 `terminated` 로 표시하고, 레지스트리가 모르는 살아 있는 세션을 등록합니다. |
|
||||
| **`multi-agent-mux-delegate-job`** | 세션(`herdr:<name>`)이나 다른 호스트의 러너(`remote:<name>`)에 잡을 위임하고 결과를 기다립니다. [위임 계약](#-위임-계약)을 보십시오. |
|
||||
| **`multi-agent-mux-loop`** | 계획·구현·리뷰: 선택적인 planner 와 creator, 그다음 선택한 리뷰어(`--reviewer A,B`, 또는 `--all-reviewer` 로 creator 를 뺀 실행 중인 리뷰어 전원)가 모두 `PASS` 를 낼 때까지(또는 `--max-loop` 까지). 둘 다 없으면 creator 가 스스로 리뷰합니다. 루프 밖에서 끝난 작업은 `--review-only` 로 리뷰합니다. 통과한 리포트는 `.agents/reports/<session>/` 으로 옮겨 보관합니다. |
|
||||
| **`multi-agent-mux-orc-onboard`** | 오케스트레이터 자신의 세션 ID 를 등록해, 세션 탐색이 그것을 하위 에이전트로 착각하지 않게 합니다. |
|
||||
|
||||
---
|
||||
|
||||
## 📐 아키텍처
|
||||
|
||||
MAM 은 각자 레지스트리를 가진 두 계층으로 이루어집니다.
|
||||
|
||||
1. **세션 (herdr)**: `lib.sh` 와 create/stop/resume/status/monitor 스크립트가 에이전트를 돌리고, `.mam/agent-sessions.yaml`(+ `.mam/agent-sessions.db`)을 기준 기록으로 유지합니다.
|
||||
2. **잡 (위임)**: `lib_py/delegation/` 이 `.mam/jobs/<id>.json` 에 잡을 등록하고, 브리프를 주입하고, MQTT 로 잡의 이벤트를 따라갑니다. 모든 이벤트는 잡의 감사 로그 `.mam/delegate_job_logs/<id>/` 에도 덧붙여집니다.
|
||||
|
||||
```text
|
||||
+--------------+ register / pick +----------------------+
|
||||
| orchestrator | -----------------> | .mam/jobs/<id>.json | live record
|
||||
| (wrapper) | +----------+-----------+
|
||||
+------+-------+ | every transition
|
||||
| inject brief v
|
||||
v +----------------------+
|
||||
+--------------+ publish_event | .mam/delegate_job_ | append-only
|
||||
| agent pane | --------+ | logs/<id>/ | audit log
|
||||
+--------------+ | +----------------------+
|
||||
v
|
||||
+-------------+ events + retained state
|
||||
| MQTT broker | -------------------------> job_subscriber (orchestrator)
|
||||
+-------------+ -------------------------> monitor (reconcile.sh)
|
||||
|
|
||||
v
|
||||
.mam/agent-sessions.yaml / .db
|
||||
```
|
||||
|
||||
### 🔒 Herdr 서버 격리
|
||||
|
||||
- **워크스페이스 전용 서버.** `create` 는 기본으로 워크스페이스 이름(slug)을 딴 herdr 서버에서 에이전트를 돌립니다. 이 서버는 기본 herdr 와 분리된 자기 소켓을 씁니다. `--herdr-session <name>` 또는 `HERDR_SESSION_NAME` 으로 다른 이름을 고를 수 있습니다. 서버 이름은 세션 행에 기록되고, 이후 모든 명령이 그 서버로 갑니다.
|
||||
- **shim.** `lib.sh` 를 source 하면 `<workspace>/.mam/shim/herdr` 를 쓰고 `PATH` 맨 앞에 둡니다. shim 은 스크립트가 쓰는 tmux 식 명령(`new-session`, `has-session` …)을 herdr 의 에이전트 API 위에 제공합니다. 이름 있는 서버면 호출마다 `--session <server>` 를 붙이고, 그 서버가 돌고 있지 않으면 헤드리스로 시작합니다. 단 `MAM_NO_AUTOSTART=1` 이면 시작하지 않습니다. `status` 와 `monitor` 가 이 값을 설정하므로, 조회만으로 서버가 뜨는 일은 없습니다. `default` 서버 호출은 바꾸지 않고 사용자의 herdr 로 그대로 갑니다.
|
||||
- **예상치 못한 재실행 없음.** MAM 이 시작한 서버는 보통 사용자의 herdr 설정에 `resume_agents_on_restore = false` 를 더해 씁니다. 그래서 herdr 가 재시작돼도 저장된 에이전트를 권한 플래그 없이 다시 띄우지 않습니다. `tomllib` 이 없는 Python(macOS 기본 3.9 등)에서는 이 파일에 그 키만 들어가므로, restore 는 꺼지지만 사용자의 다른 herdr 설정은 반영되지 않습니다. 이때 부트스트랩이 경고합니다. 설정 파일을 아예 쓰지 못한 경우에만 서버가 restore 가 켜진 채 시작하며, 이때도 경고를 남깁니다.
|
||||
- **pane 배치는 한 번에 하나.** pane 배치는 서버별 잠금(`lib_py/pane_lock.py`, macOS·Linux 에서 `flock`)을 잡고 합니다. 한 폴더에서 동시에 실행한 `create` 도 각자 자기 pane 을 받습니다.
|
||||
|
||||
### 🛡️ 레지스트리 쓰기와 동시성
|
||||
|
||||
- **직렬화된 쓰기.** `agent-sessions.yaml` 의 모든 변경은 `lib.sh::atomic_dump_yaml` 을 거칩니다. `.mam/agent-sessions.db` 의 배타적 SQLite 트랜잭션(`BEGIN IMMEDIATE`) 안에서 실행되고, 검증한 뒤에 YAML 을 원자적으로 다시 씁니다. 잡 레코드는 별도의 레지스트리 잠금을 씁니다.
|
||||
- **Python 인터프리터.** 레지스트리 쓰기와 위임 헬퍼는 이 순서로 Python 을 고릅니다: `AGENT_PYTHON_BIN`, 활성화된 가상환경, 스킬 위쪽에서 가장 가까운 `.venv`, 마지막으로 `PATH` 의 `python3`. shim 과 `create` 의 일부 같은 셸 경로는 `PATH` 의 `python3` 를 직접 부릅니다.
|
||||
- **네트워크 파일시스템.** `.mam/` 이 NFS/CIFS/SSHFS 에 있으면 `lib.sh` 가 경고하고, SQLite 저널 모드를 `WAL` 에서 `DELETE` 로 바꿉니다.
|
||||
- **체크아웃당 루프 하나.** 루프 잠금이 같은 제어 평면에서 두 번째 `run_loop.sh` 를 거부합니다.
|
||||
|
||||
---
|
||||
|
||||
## 📨 위임 계약
|
||||
|
||||
전체 명세는 [MESSAGING.md §2.5](MESSAGING.md)에 있습니다.
|
||||
|
||||
- **전달**: 프롬프트를 넘긴 뒤 **T** 초(기본 180) 안에 에이전트가 `started` 를 발행해야 합니다. 그러지 않으면 잡은 실패로 닫히고(`agent_blocked`, 종료 코드 1), 프롬프트를 두 번 넣지 않습니다.
|
||||
- **생존**: `started --heartbeat N` 이 자동 heartbeat 를 시작합니다(기본 30 초마다). **K×N** 초(기본 120 초) 동안 아무 이벤트가 없으면 무응답으로 봅니다. herdr 상태와 pane 텍스트는 진단용으로만 로그에 남깁니다.
|
||||
- **예산**: 잡마다 벽시계 예산이 있습니다(`--timeout` / `MAM_JOB_TIMEOUT_S`, 기본 3600 초). 예산을 다 쓴 잡은 `wall_clock_timeout` 으로 닫힙니다.
|
||||
- **바쁜 세션**: 래퍼는 그 세션의 앞선 열린 잡이 끝나기를 `MAM_DISPATCH_WAIT_S` 만큼 기다립니다. 끝나지 않으면 `cancelled`(`session_busy`, 종료 코드 5)로 끝나고, 프롬프트는 전달되지 않습니다.
|
||||
- **원격 에이전트**: `remote:<name>` 은 브리프를 서명된 retained 브로커 메시지로 다른 호스트의 `remote.py run` 러너에 보냅니다. 사설 브로커에서만 쓰십시오.
|
||||
|
||||
| 종료 코드 | 의미 |
|
||||
|:---:|---|
|
||||
| `0` | `completed` |
|
||||
| `1` | 실패, 또는 T 안에 `started` 없음 |
|
||||
| `2` | K×N 동안 이벤트 없음(`deadline_timeout`) 또는 예산 소진(`wall_clock_timeout`) |
|
||||
| `3` | 브로커를 쓸 수 없고, 디스크에도 종결 상태가 없음 |
|
||||
| `5` | 이번 시도는 프롬프트를 전달하지 않음: 세션이 바쁘거나 대상을 찾지 못함(잡은 `cancelled`), 또는 기다리는 동안 다른 시도가 레코드를 가져감(레코드는 새 소유자에게 그대로 둠) |
|
||||
|
||||
---
|
||||
|
||||
## 🔁 리뷰 루프
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
actor User as User
|
||||
participant PM as Project Manager
|
||||
participant W as Worker
|
||||
actor User
|
||||
participant L as run_loop.sh
|
||||
participant P as Planner (optional)
|
||||
participant C as Creator
|
||||
participant R as Reviewers
|
||||
participant M as MQTT Backplane
|
||||
|
||||
User->>PM: 요구사항 전달
|
||||
Note over PM: 태스크 수립 및 Job 등록
|
||||
PM->>M: Job 등록 및 Subscriber 시작
|
||||
PM->>W: 작업 위임 (Job ID 및 가이드 제공)
|
||||
W->>M: 'started' 이벤트 발행
|
||||
Note over W: 코드 변경 및 자체 검증 수행
|
||||
W->>M: 'completed' (또는 'error') 발행
|
||||
PM->>R: 병렬 리뷰 요청 (Diff 제공)
|
||||
Note over R: 에이전트 교차 검증 (Claude, Hermes, Grok, OpenCode, Codex)
|
||||
alt 리뷰 피드백 (NOT PASS)
|
||||
R->>PM: NOT PASS (대안 코드 블록과 함께 피드백 전달)
|
||||
Note over PM: PM 직접 수정 또는 다시 위임 결정
|
||||
PM->>W: 리뷰 피드백 반영 재요청
|
||||
else 검증 통과 (PASS)
|
||||
R->>PM: PASS
|
||||
User->>L: --task, --creator, --reviewer / --all-reviewer
|
||||
opt --plan
|
||||
L->>P: write the plan (Creator challenges it for --plan-talk turns)
|
||||
end
|
||||
PM->>User: 최종 머지 완료 보고 및 변경사항 커밋
|
||||
L->>C: implement and commit (skipped with --review-only)
|
||||
loop up to --max-loop
|
||||
L->>R: review the snapshot diff (base..head)
|
||||
alt every reviewer PASS and the source unchanged
|
||||
R-->>L: [VERDICT: PASS]
|
||||
else NOT PASS
|
||||
R-->>L: [VERDICT: NOT PASS] + findings
|
||||
L->>C: fix (or [REBUT:] up to --max-rebut)
|
||||
end
|
||||
end
|
||||
L->>User: reports promoted to .agents/reports/<session>/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔒 보안 프로토콜 및 Replay 공격 방어
|
||||
|
||||
공용 MQTT 브로커 환경에서도 통신의 무결성을 보장하기 위해 **HMAC-SHA256 암호화 서명** 체계를 갖추고 있습니다:
|
||||
* **PoC 모드 (무인증):** 기본 설정 모드로 `auth_token`이 `null`로 세팅되어 간단한 로컬 환경 검증 시 암호화 시그니처 체크를 건너뜁니다.
|
||||
* **프로덕션 모드 (인증 필수):** 각 잡마다 무작위 암호화 토큰이 발급되며, 백플레인을 오가는 모든 페이로드에 토큰 기반으로 생성된 `hmac_sig` 서명을 탑재해야 수신측에서 수용합니다.
|
||||
* **Replay 공격 방어:** 각 이벤트는 단조 증가하는 정수형 시퀀스 번호(`seq`)를 포함합니다. 구독자(`job_subscriber.py`)는 특정 잡에 대해 이미 수용한 최대 시퀀스 번호보다 크지 않은 시퀀스 번호를 가진 페이로드를 즉시 폐기합니다. 페이로드 바디에 대한 HMAC 서명과 결합하여, 이 메커니즘은 클록 동기화에 의존하지 않고 재전송(re-injected) 및 순서가 바뀐 패킷을 차단합니다. 메시지 내 타임스탬프 필드는 참고용 메타데이터이며, 백플레인은 시간 오차(clock-skew) 윈도우를 별도로 검증하지 않습니다.
|
||||
- **엄격한 판정**: 판정 토큰은 리포트 마지막 줄에 단독으로 있어야 합니다. 판정이 없으면 `NOT PASS` 로 봅니다.
|
||||
- **리뷰 identity** (`--worktree` / `--base`): 라운드마다 커밋하지 않은 파일까지 담은 스냅샷을 리뷰합니다. 라운드 중 소스가 바뀌면 그 승인은 버립니다. 보관되는 리포트 옆에는 base·head·tree·리뷰어를 적은 `report-<job>.identity.json` 이 붙습니다.
|
||||
- **하위 잡**: creator 가 작업 일부를 위임하면(`--parent-job`), 루프는 리뷰 전에 그 잡들을 기다리고 상태를 리뷰어에게 보여 줍니다.
|
||||
|
||||
---
|
||||
|
||||
## 📁 리포지토리 구성
|
||||
## 🔐 보안
|
||||
|
||||
- **서명된 이벤트**: 토큰을 직접 넘기거나 브로커가 TLS 또는 사용자 이름을 쓰면, 잡은 고유 토큰(`auth_token`)을 받습니다. 그때 모든 이벤트와 retained 상태 메시지에 그 토큰으로 만든 HMAC-SHA256 서명이 붙고, 구독자는 검증에 실패한 메시지를 버립니다. 이벤트와 상태 메시지에는 토큰이 아니라 서명만 실립니다. 토큰을 넘기지 않았고 브로커에 TLS 도 사용자 이름도 없으면(PoC 구성), 잡에 토큰이 없어 서명을 검사하지 않습니다.
|
||||
- **원격 디스패치에는 토큰이 실린다**: `remote:<name>` 디스패치 메시지에는 잡의 토큰이 들어갑니다(`MAM_DISPATCH_SECRET` 으로 서명될 뿐 암호화되지는 않음). 접근이 통제된 사설 브로커에서만 쓰십시오.
|
||||
- **재전송과 순서**: 이벤트마다 증가하는 `seq` 가 붙습니다. 구독자는 지금까지 본 것보다 큰 번호만 받고, 빈 번호는 `seq_gap` 으로 기록합니다. 타임스탬프는 참고용입니다.
|
||||
- **자격 증명**: 브로커 자격 증명은 `.mam.env` 에만 있고, 잡 레코드에는 없습니다.
|
||||
|
||||
---
|
||||
|
||||
## 🧪 테스트
|
||||
|
||||
```bash
|
||||
.venv/bin/python -m pytest -q -p no:cacheprovider tests
|
||||
```
|
||||
|
||||
- 테스트는 약 1,900 개이고, 전체 실행에 한 시간 넘게 걸립니다.
|
||||
- 프로세스 안에서 자체 MQTT 브로커를 띄우므로 `.mam.env` 가 필요 없습니다. 테스트용으로 `.mam.env` 를 export 하지 마십시오.
|
||||
- 모든 테스트는 임시 잡 레지스트리와 감사 로그 디렉터리를 씁니다. 약 3분의 1 은 임시 HOME 을 설정하는 샌드박스 픽스처도 쓰고, 그보다 적은 수는 mock herdr 도 씁니다.
|
||||
- 실제 herdr 를 다루는 테스트는 일회용 herdr 서버를 직접 띄웁니다.
|
||||
- 실행이 끝나면 세션 단위 가드가 실제 제어 평면과 사용자의 에이전트 홈(`~/.claude/projects`, `~/.codex`, `~/.gemini` …)을 확인하고, 테스트가 남긴 항목이 있으면 실행을 실패시킵니다.
|
||||
- 일부 테스트는 플랫폼에 따라 다릅니다. Python 3.11+(`tomllib`), Linux(`/proc`), `nats-docker` 서브모듈이 필요한 테스트는 그 밖의 환경에서 건너뜁니다.
|
||||
|
||||
---
|
||||
|
||||
## 📁 저장소 구조
|
||||
|
||||
```text
|
||||
.
|
||||
├── .agents/
|
||||
│ ├── MULTI_AGENT_RULES.md # 에이전트 역할 행동 강령 및 뷰포트 스냅샷 규칙
|
||||
│ ├── MULTI_AGENT_RULES.ko.md # 에이전트 역할 행동 강령 (한국어 백업)
|
||||
│ └── skills/ # 코어 오케스트레이션 셸 스크립트 및 라이브러리
|
||||
│ ├── lib.sh # 공통 오케스트레이션 셸 함수 라이브러리
|
||||
│ ├── lib_py/ # 파이썬 코어 오케스트레이션 엔진
|
||||
│ │ ├── agents/ # 멀티 에이전트 CLI 수명 주기 어댑터
|
||||
│ │ ├── delegation/ # 비동기 잡 위임 및 CAS 상태 전이 엔진
|
||||
│ │ └── loop/ # 자율 계획-실행-교차검증 루프 런타임
|
||||
│ ├── multi-agent-mux-create/
|
||||
│ ├── multi-agent-mux-stop/
|
||||
│ ├── multi-agent-mux-resume/
|
||||
│ ├── multi-agent-mux-status/
|
||||
│ ├── multi-agent-mux-monitor/
|
||||
│ ├── multi-agent-mux-delegate-job/
|
||||
│ │ ├── requirements.txt # 파이썬 의존성 패키지 선언
|
||||
│ │ └── scripts/ # 하위 호환 shim 스크립트 (Python)
|
||||
│ ├── multi-agent-mux-loop/
|
||||
│ └── multi-agent-mux-orc-onboard/
|
||||
├── .mam/ # Multi-Agent Mux 메타데이터 (git-ignored)
|
||||
│ ├── agent-sessions.db # SQLite WAL 세션 데이터베이스
|
||||
│ ├── agent-sessions.yaml # 텍스트 형식의 세션 레지스트리 스냅샷
|
||||
│ └── jobs/ # 비동기 잡 메타데이터 JSON 파일들
|
||||
├── deploy/ # 배포 및 설치 도구 패키지 폴더
|
||||
│ ├── INSTALL.md # 설치 가이드 및 퀵스타트 매뉴얼
|
||||
│ ├── install_mam.sh # 로컬/클론 인스톨러 스크립트
|
||||
│ ├── generate-env.sh # 환경 파일(.mam.env) 템플릿 복사 스크립트
|
||||
│ ├── install.sh # 원격/네트워크 인스톨러 스크립트
|
||||
│ ├── update.sh # 업데이트 헬퍼 스크립트
|
||||
│ └── remove.sh # 삭제/언인스톨 헬퍼 스크립트
|
||||
├── docs/ # 기술 규격서, 가이드 및 아키텍처 계약 문서
|
||||
│ ├── contracts/ # 이슈/백플레인 계약 및 마이그레이션 로드맵
|
||||
│ ├── MAM_WEB_PTY_BRIDGE_PLAN.md # Web PTY 터미널 브리지 설계 계획서
|
||||
│ ├── NEW_AGENT_INTEGRATION_GUIDE.md # 신규 AI 코딩 에이전트 연동 가이드
|
||||
│ └── OPENCODE_OLLAMA_GUIDE.md # OpenCode 인터프리터 + Ollama 연동 가이드
|
||||
├── nats-docker/ # 사설 NATS 브로커 배포 서브모듈
|
||||
├── tests/ # 종합 회귀 테스트 스위트 (32개 모듈)
|
||||
├── AGENTS.md # 에이전트 행동 지침 및 오케스트레이터 스코프 가드
|
||||
├── BOOTSTRAP.ko.md # 프로젝트 초기 설치 가이드 (한국어 백업)
|
||||
├── BOOTSTRAP.md # 프로젝트 초기 설치 및 검증 상세 가이드
|
||||
├── IMPROVEMENTS.md # 이슈 백로그 및 완료된 아키텍처 과제 추적 원장
|
||||
├── MESSAGING.md # MQTT 메시징 프로토콜 와이어 규격서
|
||||
├── README.ko.md # 프로젝트 대표 소개 파일 (한국어)
|
||||
├── README.md # 프로젝트 대표 소개 파일 (영문 원본)
|
||||
└── VERSIONS.md # 릴리스 노트 및 4-way 락스텝 버전 원장
|
||||
│ ├── MULTI_AGENT_RULES.md / .ko.md # 역할, 워크플로우, 협업 규칙
|
||||
│ ├── reports/ # 보관된 리뷰 리포트 (+ identity 사이드카)
|
||||
│ └── skills/
|
||||
│ ├── lib.sh # 공용 셸 라이브러리 (herdr shim, 레지스트리 쓰기)
|
||||
│ ├── lib_py/ # Python 코어
|
||||
│ │ ├── agents/ # 에이전트별 CLI 어댑터 (spawn/resume/discover)
|
||||
│ │ ├── delegation/ # 잡 레지스트리, 래퍼, MQTT 발행/구독, 원격 러너
|
||||
│ │ ├── loop/ # 리뷰 루프 런타임
|
||||
│ │ └── *.py # pane_lock, stall_watch, worktree, herdr_config, ...
|
||||
│ └── multi-agent-mux-*/ # 스킬마다 디렉터리 하나 (SKILL.md + scripts/)
|
||||
├── .mam/ # 런타임 상태 (git 제외): 세션, 잡, 감사 로그, shim
|
||||
├── deploy/ # install.sh, install_mam.sh, update.sh, remove.sh, generate-env.sh
|
||||
├── docs/ # contracts/, design/, 에이전트 통합·브리지 가이드
|
||||
├── nats-docker/ # 사설 NATS 브로커 배포 (서브모듈)
|
||||
├── tests/ # pytest 스위트
|
||||
├── AGENTS.md # 에이전트 행동 지침
|
||||
├── BOOTSTRAP.md / BOOTSTRAP.ko.md # 단계별 설치·검증 가이드
|
||||
├── IMPROVEMENTS.md # 백로그
|
||||
├── MESSAGING.md # MQTT 와이어 프로토콜과 위임 계약
|
||||
├── README.md # 영문 README
|
||||
└── VERSIONS.md # 릴리스 노트 (락스텝 버전 원장)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚦 빠른 시작
|
||||
|
||||
자세한 빌드 절차는 **[BOOTSTRAP.md](./BOOTSTRAP.md)** 문서를 참조하십시오. 아래는 간략한 요약입니다:
|
||||
전체 과정은 [BOOTSTRAP.ko.md](BOOTSTRAP.ko.md)를 보십시오. 요약하면:
|
||||
|
||||
1. **환경 설정 파일(.mam.env) 생성:**
|
||||
```bash
|
||||
./deploy/generate-env.sh
|
||||
```
|
||||
2. **가상환경 생성 및 의존성 패키지 설치:**
|
||||
```bash
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -r .agents/skills/multi-agent-mux-delegate-job/requirements.txt
|
||||
```
|
||||
3. **레지스트리 및 환경 작동 자가 검증:**
|
||||
```bash
|
||||
.venv/bin/python3 .agents/skills/multi-agent-mux-delegate-job/scripts/registry.py list
|
||||
```
|
||||
```bash
|
||||
# 1. 워크스페이스에 설치한 뒤 .mam.env 에 브로커를 설정
|
||||
bash deploy/install.sh
|
||||
|
||||
# 2. 전용 herdr 서버에서 creator 와 reviewer 시작
|
||||
bash .agents/skills/multi-agent-mux-create/scripts/create_session.sh \
|
||||
--workspace "$PWD" --agent claude --role developer --session creator-claude-01 \
|
||||
--herdr-session my-project --onboard
|
||||
bash .agents/skills/multi-agent-mux-create/scripts/create_session.sh \
|
||||
--workspace "$PWD" --agent codex --role reviewer --session reviewer-codex-01 \
|
||||
--herdr-session my-project --onboard
|
||||
|
||||
# 3. 세션 확인
|
||||
bash .agents/skills/multi-agent-mux-status/scripts/status.sh
|
||||
|
||||
# 4. 루프로 작업 실행
|
||||
bash .agents/skills/multi-agent-mux-loop/scripts/run_loop.sh \
|
||||
--creator creator-claude-01 --all-reviewer --task "Fix the typo in docs/guide.md"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 협업 에이전트 준수 사항
|
||||
## 📝 프로젝트에 합류하는 에이전트에게
|
||||
|
||||
이 프로젝트에 새로 합류한 에이전트는 다음 규칙을 준수해야 합니다:
|
||||
1. **[MULTI_AGENT_RULES.md](.agents/MULTI_AGENT_RULES.md)** 문서를 정독하여 프로젝트 매니저(PM), 작업자(Worker), 리뷰어(Reviewer) 간의 역할 및 개발 제약조건을 인지하십시오.
|
||||
2. 장시간 명령을 실행하는 경우 터미널 스크롤백 로그 유실을 방지하기 위해 `MULTI_AGENT_RULES.md` (제4장)에 기재된 **뷰포트 스냅샷 규칙(Pane Snapshotting Rules)**을 반드시 적용하십시오.
|
||||
3. 리뷰어 세션에 diff 검증을 요청하기 전에는 어떠한 코어 파일의 임의 수정도 프로덕션 브랜치에 승인 없이 머지할 수 없습니다.
|
||||
1. 역할과 규칙은 [AGENTS.md](AGENTS.md)와 [MULTI_AGENT_RULES.ko.md](.agents/MULTI_AGENT_RULES.ko.md)를 읽으십시오.
|
||||
2. 긴 출력이 pane 스크롤백 밖으로 사라지지 않도록 `MULTI_AGENT_RULES.ko.md` §4 의 스냅샷 규칙을 따르십시오.
|
||||
3. 브리프가 지시하는 대로 잡 이벤트를 발행하십시오(`started --heartbeat`, 그다음 `completed` 또는 `error`). 리뷰받은 diff 없이 핵심 로직을 바꾸지 마십시오.
|
||||
@@ -1,237 +1,242 @@
|
||||
# herdr-agent-orchestration
|
||||
|
||||
An advanced, high-reliability **Multi-Agent Orchestration & Messaging Backplane** framework built on Herdr and MQTT. It is designed to coordinate, isolate, and audit long-running agent tasks (such as code generation, refactoring, and security reviews) across multiple LLM backend clients (`claude`, `agy`, `hermes`, `grok`, `opencode`, `codex`).
|
||||
A **Multi-Agent Orchestration & Messaging Backplane** built on [herdr](https://herdr.dev) and MQTT. It runs long-lived coding agents (`claude`, `agy`, `hermes`, `grok`, `opencode`, `codex`) in isolated herdr panes, delegates work to them as tracked jobs, and drives planner / creator / reviewer loops until every reviewer passes the change.
|
||||
|
||||
[](VERSIONS.md)
|
||||
[](VERSIONS.md)
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Overview
|
||||
|
||||
Modern agentic workflows often suffer from session timeout, lack of process isolation, terminal viewport truncation (scrollback limits), and complex concurrency issues.
|
||||
|
||||
**herdr-agent-orchestration** addresses these problems by providing:
|
||||
1. **Herdr-based Process Isolation:** Spawning LLM client sessions inside dedicated, isolated herdr environments to support persistent background runs. Background daemon servers detach into their own OS session/process group (`start_new_session=True`), ensuring they survive signal broadcasts to the parent shell.
|
||||
2. **Asynchronous Event-Driven Architecture:** Leveraging an MQTT broker as a message backplane to coordinate state transitions (`started`, `progress`, `completed`, `error`) between collaborating agents.
|
||||
3. **Multi-Agent Mux (MAM):** Combining local file-based locks (fcntl) and an ACID-compliant SQLite WAL database (`.mam/agent-sessions.db`) to manage concurrent job claims and track running agent sessions without drift.
|
||||
4. **Automated Review & Quality Loop:** Implementing parallel reviewer loops where worker agents must receive a `PASS` rating from various specialized verification agents (e.g., Claude, Hermes, Grok, OpenCode, Codex) before merging code.
|
||||
Long agent runs break in predictable ways: a session dies with its terminal, two jobs land in one pane, the orchestrator cannot tell a busy agent from a dead one, and a review approves code that changed after it was read. Multi-Agent Mux (MAM) addresses these with:
|
||||
|
||||
1. **Isolated, resumable agent sessions.** Each agent runs in its own herdr pane, usually on a herdr server dedicated to the workspace. Sessions are recorded in `.mam/agent-sessions.yaml` (backed by SQLite) with their conversation ids, so a stopped agent resumes the same conversation later.
|
||||
2. **Jobs decided by events, not by the screen.** A delegated job is a registry record plus an MQTT event stream (`started`, `progress`, `completed`, `error`). The agent must acknowledge the prompt within a deadline and heartbeat while it works. A job is closed only by a protocol event or a timeout, never by reading the terminal.
|
||||
3. **One job per session at a time.** Before injecting a prompt, the dispatcher waits by the registry for the session's earlier jobs (onboarding included) to end. Pane placement is serialised per herdr server, so concurrent `create` calls do not take the same pane.
|
||||
4. **Reviewed loops with pinned evidence.** `multi-agent-mux-loop` sends a change to the reviewers you select and requires every one of them to `PASS`. You can name reviewers with `--reviewer` or take every running reviewer with `--all-reviewer`; without either, the creator reviews its own work. With `--worktree`/`--base`, each review round is bound to a snapshot of the source. If the source changes during the round, its approvals are discarded and the round is reviewed again.
|
||||
|
||||
---
|
||||
|
||||
## 📦 Installation & Setup
|
||||
|
||||
You can bootstrap the Multi-Agent Mux (MAM) framework in any workspace directory with a single command:
|
||||
Bootstrap MAM in any workspace directory:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://git.godopu.com/tmpl/multi-agent-mux/raw/branch/main/deploy/install.sh | bash
|
||||
```
|
||||
|
||||
Alternatively, if you have already cloned the repository locally, run the installer directly:
|
||||
or, from a local clone:
|
||||
|
||||
```bash
|
||||
bash deploy/install.sh
|
||||
```
|
||||
|
||||
The idempotent installer automatically validates system dependencies (herdr, python3, and PyYAML), creates the python virtual environment (`.venv`), installs dependencies, copies `.mam.env.example` as `.mam.env`, and initializes the `.agents/` scaffolding.
|
||||
`install.sh` is idempotent. It does the following:
|
||||
- checks that herdr and Python 3.9+ are installed, and that the system `python3` has PyYAML;
|
||||
- copies `.agents/` and `.mam.env.example` into the workspace;
|
||||
- creates `.venv` and installs `paho-mqtt` and PyYAML into it;
|
||||
- writes a starter `.mam.env` with `MQTT_BROKER=localhost`. An existing `.mam.env` is kept. If only a legacy `.env` exists, it is copied to `.mam.env` and the original stays;
|
||||
- adds `.venv`, `.mam/` and `.mam.env` to `.gitignore`.
|
||||
|
||||
Point `MQTT_BROKER` in `.mam.env` at a broker you run (see [MESSAGING.md](MESSAGING.md) for a private broker). If `MQTT_BROKER` is not set at all, the code falls back to the public `broker.hivemq.com`. That is fine for a trial, but not for real work. `deploy/generate-env.sh` creates `.mam.env` from `.mam.env.example` when it is missing (`--force` overwrites it, keeping a `.mam.env.bak`). `deploy/update.sh` and `deploy/remove.sh` update and uninstall. `deploy/install_mam.sh` is a separate installer that copies from a local clone into another directory.
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Core Skills & Scaffolding
|
||||
## 🛠️ Core Skills
|
||||
|
||||
All orchestration functionalities are structured under the `.agents/skills/` directory:
|
||||
Every skill lives under `.agents/skills/` with a `SKILL.md` that documents its options and exit codes.
|
||||
|
||||
* **`multi-agent-mux-create`**: Spawns isolated herdr sessions running specified agent CLI wrappers. It captures system processes, updates metadata registries, and enforces authentication checks.
|
||||
* **`multi-agent-mux-stop`**: Gracefully terminates agent CLI sessions (using key macros like `/exit` or `Exit`) and handles disk purge operations (removing conversation JSON files and SQLite logs for deleted workspaces).
|
||||
* **`multi-agent-mux-resume`**: Restores stopped sessions by resolving workspace UUIDs from disk or cache, and invokes the underlying agent using session-resume parameters (e.g., `claude -r <uuid>`, `agy --conversation <uuid>`, `hermes --resume <uuid>`, `grok --resume <uuid>`, `opencode --session <uuid>`, or `codex resume <uuid>`).
|
||||
* **`multi-agent-mux-status`**: Queries the running states of all active sessions, detecting PID mismatches, command signatures, and drifts between actual herdr instances and the registry database.
|
||||
* **`multi-agent-mux-monitor`**: A long-running reconcile worker that dynamically monitors herdr sessions and synchronizes states to `.mam/agent-sessions.yaml`.
|
||||
* **`multi-agent-mux-delegate-job`**: The core asynchronous task distribution module (core implementation in `.agents/skills/lib_py/delegation/`; `scripts/*.py` serves as compatibility shims):
|
||||
* `registry.py`: Atomically registers and claims jobs using file advisory locks (`fcntl`).
|
||||
* `job_subscriber.py`: Connects to the MQTT backplane, captures live events, and appends them to audit trails.
|
||||
* `publish_event.py`: Emits execution status transitions and error details from workspace scripts.
|
||||
* `mqtt_common.py`: Manages connection policies, authentication, and HMAC signing.
|
||||
* **`multi-agent-mux-loop`**: Autonomous planning-execution-review orchestration loop across Planner, Creator, and Reviewers until unanimous consensus (driven by Python loop runtime in `lib_py.loop`, eager-import immutable runtime, strict verdict parser).
|
||||
* **`multi-agent-mux-orc-onboard`**: Helper to register and isolate orchestrator session UUIDs to prevent sub-agent discovery capture.
|
||||
| Skill | What it does |
|
||||
|---|---|
|
||||
| **`multi-agent-mux-create`** | Starts an agent in a herdr pane and registers the session. `--onboard` waits until the onboarding job ends (exit 44 if it failed, 45 if it did not end in time; the session is kept). `scripts/worktree_prepare.sh` prepares an issue worktree for a creator. |
|
||||
| **`multi-agent-mux-stop`** | Stops a session gracefully. The conversation id is saved on the row (`status: stopped`, `resumable: true`). `--purge-conversation --yes` deletes the conversation instead. `scripts/worktree_remove.sh` removes an issue worktree only after checking it is clean, including its submodules. |
|
||||
| **`multi-agent-mux-resume`** | Brings a stopped session back with its saved conversation (`claude -r`, `agy --conversation`, `hermes --resume`, `grok --resume`, `opencode --session`, `codex resume`), in the directory it ran in. |
|
||||
| **`multi-agent-mux-status`** | Read-only snapshot of every session: registry status, herdr liveness, pane command and cwd, resume id, drift. |
|
||||
| **`multi-agent-mux-monitor`** | Long-running reconciler (`reconcile.sh --subscribe`). It reacts to job events, falls back to polling when the broker is down, and fixes registry drift. For example, it marks dead sessions `terminated` and registers live sessions the registry does not know. |
|
||||
| **`multi-agent-mux-delegate-job`** | Delegates a job to a session (`herdr:<name>`) or to a runner on another host (`remote:<name>`) and waits for its result. See [Delegation contract](#-delegation-contract). |
|
||||
| **`multi-agent-mux-loop`** | Plan, implement, review: an optional planner and a creator, then the selected reviewers (`--reviewer A,B`, or `--all-reviewer` for every running reviewer except the creator) until all of them `PASS` or `--max-loop` is reached. With neither option the creator reviews its own work. `--review-only` reviews work finished outside the loop. Passing reports are promoted to `.agents/reports/<session>/`. |
|
||||
| **`multi-agent-mux-orc-onboard`** | Registers the orchestrator's own session id, so session discovery never mistakes it for a sub-agent. |
|
||||
|
||||
---
|
||||
|
||||
## 📐 Big-Picture Architecture
|
||||
## 📐 Architecture
|
||||
|
||||
The system coordinates LLM agents across multiple workspaces through two core layers:
|
||||
MAM has two layers, each with its own registry:
|
||||
|
||||
1. **Layer A — Herdr Orchestration (lib.sh + status/resume/stop/create)**: Runs the agents (one herdr session per agent-workspace combination) and maintains an authoritative registry in `.mam/agent-sessions.yaml` (+ `.mam/agent-sessions.db`).
|
||||
2. **Layer B — Async Job Delegation (delegate-job)**: Dispatches a task to an agent and observes progress and completion via an event channel.
|
||||
|
||||
These two layers share one lock-guarded chokepoint for file I/O: `lib.sh::atomic_dump_yaml`. Every write is protected by an exclusive SQLite database transaction lock and schema validation.
|
||||
|
||||
### Data Flow Overview
|
||||
1. **Sessions (herdr)**: `lib.sh` and the create/stop/resume/status/monitor scripts run the agents and keep `.mam/agent-sessions.yaml` (+ `.mam/agent-sessions.db`) authoritative.
|
||||
2. **Jobs (delegation)**: `lib_py/delegation/` registers a job in `.mam/jobs/<id>.json`, injects the brief, and follows the job's events over MQTT. Every event is also appended to the job's audit log `.mam/delegate_job_logs/<id>/`.
|
||||
|
||||
```text
|
||||
+-----------+ register_job +-------------------+
|
||||
| delegator | ---------------> | .mam/jobs/<id>.json| <-- live record
|
||||
+-----------+ +---------+---------+
|
||||
|
|
||||
| atomic rename + fsync
|
||||
v
|
||||
+-----------------+
|
||||
| audit log | <-- append-only
|
||||
| .mam/delegate_ | events.ndjson
|
||||
| job_logs/<id>/ |
|
||||
+--------+--------+
|
||||
^
|
||||
| (best-effort mirrors)
|
||||
|
|
||||
+-----------+ publish_event +-----+-----+ +---------+
|
||||
| agent | ---------------> | MQTT broker | <--- | monitor |
|
||||
| (claude) | +-------------+ +----+----+
|
||||
+-----------+ |
|
||||
^ v
|
||||
| subscriber atomic_dump_yaml
|
||||
| (job_subscriber.py) (.mam/agent-sessions.yaml)
|
||||
| ^
|
||||
+-------- delegator waits here ----------+ |
|
||||
+---+---+
|
||||
| reconcil|
|
||||
| e.sh |
|
||||
+--------+
|
||||
+--------------+ register / pick +----------------------+
|
||||
| orchestrator | -----------------> | .mam/jobs/<id>.json | live record
|
||||
| (wrapper) | +----------+-----------+
|
||||
+------+-------+ | every transition
|
||||
| inject brief v
|
||||
v +----------------------+
|
||||
+--------------+ publish_event | .mam/delegate_job_ | append-only
|
||||
| agent pane | --------+ | logs/<id>/ | audit log
|
||||
+--------------+ | +----------------------+
|
||||
v
|
||||
+-------------+ events + retained state
|
||||
| MQTT broker | -------------------------> job_subscriber (orchestrator)
|
||||
+-------------+ -------------------------> monitor (reconcile.sh)
|
||||
|
|
||||
v
|
||||
.mam/agent-sessions.yaml / .db
|
||||
```
|
||||
|
||||
### 🔒 Herdr Server Isolation
|
||||
### 🔒 Herdr server isolation
|
||||
|
||||
To prevent workspace herdr processes from interfering with each other or with system herdr servers, the framework enforces isolated herdr environments:
|
||||
* **Per-Workspace Shim:** `_init_herdr_isolation` and `_resolve_real_herdr_path` instantiate a per-workspace shim directory under `/tmp/multi-agent-herdr-shim/<HERDR_SERVER_NAME>/herdr` that intercepts herdr commands and wraps them in `herdr -L <server>`.
|
||||
* **PATH Rewriting:** The `PATH` environment variable is dynamically prepended with the shim path in all child processes. This ensures any `herdr` invocation within the agent's process tree is restricted to its isolated socket server.
|
||||
* **Environment Restoration:** If `HERDR_SERVER_NAME` is set to `default`, the PATH override is removed, reverting to the default global herdr server.
|
||||
- **A dedicated server per workspace.** By default `create` runs the agents on a herdr server named after the workspace (its slug), with its own socket, separate from your default herdr. `--herdr-session <name>` or `HERDR_SESSION_NAME` picks another name. The server name is recorded on the session row, and every later command routes to it.
|
||||
- **The shim.** Sourcing `lib.sh` writes `<workspace>/.mam/shim/herdr` and puts it first on `PATH`. The shim provides the tmux-style commands the scripts use (`new-session`, `has-session`, …) on top of herdr's agent API. For a named server it adds `--session <server>` to each call, and it starts that server headless if it is not running. It does not start one when `MAM_NO_AUTOSTART=1`, which `status` and `monitor` set, so looking never starts a server. Calls for the `default` server go to your ambient herdr unchanged.
|
||||
- **No surprise relaunches.** A server MAM starts normally uses your herdr config plus `resume_agents_on_restore = false`. A herdr restart therefore does not relaunch saved agents without their permission flags. With a Python that has no `tomllib` (such as macOS's 3.9), the file holds only that key, so restore stays off but your other herdr settings are not carried over; the bootstrap warns about this. Only if no config file can be written at all does the server start with restore on, again with a warning.
|
||||
- **One pane claim at a time.** Pane placement holds a per-server lock (`lib_py/pane_lock.py`, `flock` on macOS and Linux). Concurrent `create` calls in one folder each get their own pane.
|
||||
|
||||
### 🛡️ Concurrency Design & Write Serialization
|
||||
### 🛡️ Registry writes and concurrency
|
||||
|
||||
The framework implements lock-guarded execution pathways to prevent race conditions during parallel agent operations:
|
||||
* **SQLite Database Locks (`BEGIN IMMEDIATE`):** Every mutation of `agent-sessions.yaml` and the SQLite registry runs through `atomic_dump_yaml` inside `lib.sh`, which serializes writes via an exclusive `BEGIN IMMEDIATE` transaction lock on the SQLite database `.mam/agent-sessions.db`.
|
||||
* **Dual-Interpreter Strategy:** To minimize dependency bloat and guarantee stability, the backplane splits execution environments: the virtual environment `.venv` handles MQTT communication and async jobs (requiring `paho-mqtt`), while the system `python3` executes `atomic_dump_yaml` (relying on system-wide `PyYAML`).
|
||||
* **NFS and Network FS Safeguards:** Since file locking (`flock`) and SQLite WAL behave unreliably over network protocols (NFS, CIFS, SSHFS), `lib.sh` performs filesystem detection. If a network mount is identified, it outputs a safety warning and SQLite automatically switches its journaling mode from `WAL` to `DELETE`.
|
||||
- **Serialised writes.** Every change to `agent-sessions.yaml` goes through `lib.sh::atomic_dump_yaml`. It runs under an exclusive SQLite transaction (`BEGIN IMMEDIATE`) on `.mam/agent-sessions.db` and is validated before the YAML is rewritten atomically. Job records use their own registry lock.
|
||||
- **Python interpreter.** Registry writes and the delegation helpers pick their Python in this order: `AGENT_PYTHON_BIN`, the active virtualenv, the nearest `.venv` above the skills, then `python3` on `PATH`. Some shell paths, such as the shim and parts of `create`, call `python3` from `PATH` directly.
|
||||
- **Network filesystems.** If `.mam/` is on NFS/CIFS/SSHFS, `lib.sh` warns, and SQLite switches its journal from `WAL` to `DELETE`.
|
||||
- **One loop per checkout.** A loop lock refuses a second `run_loop.sh` in the same control plane.
|
||||
|
||||
---
|
||||
|
||||
## 📐 Architecture & Coordination Loop
|
||||
## 📨 Delegation contract
|
||||
|
||||
The interaction between roles (Project Manager, Worker, and Reviewer) is structured as a strict iterative loop:
|
||||
The full specification is in [MESSAGING.md §2.5](MESSAGING.md).
|
||||
|
||||
- **Delivery**: after the prompt is handed over, the agent must publish `started` within **T** s (default 180). If it doesn't, the job fails closed (`agent_blocked`, exit 1), and the prompt is never injected twice.
|
||||
- **Liveness**: `started --heartbeat N` starts an automatic heartbeat (default every 30 s). After **K×N** s of silence (default 120 s) the job counts as unresponsive. herdr status and pane text are logged for diagnosis only.
|
||||
- **Budget**: each job has a wall-clock budget (`--timeout` / `MAM_JOB_TIMEOUT_S`, default 3600 s). A job that runs out is closed as `wall_clock_timeout`.
|
||||
- **Busy sessions**: the wrapper waits up to `MAM_DISPATCH_WAIT_S` for the session's earlier open jobs to end. If they don't, it ends as `cancelled` (`session_busy`, exit 5), and the prompt is never delivered.
|
||||
- **Remote agents**: `remote:<name>` sends the brief as a signed, retained broker message to a `remote.py run` runner on another host. Use this only with a private broker.
|
||||
|
||||
| Exit | Meaning |
|
||||
|:---:|---|
|
||||
| `0` | `completed` |
|
||||
| `1` | failure, or no `started` within T |
|
||||
| `2` | no event for K×N (`deadline_timeout`) or budget spent (`wall_clock_timeout`) |
|
||||
| `3` | broker unavailable, and no terminal status on disk |
|
||||
| `5` | this attempt did not deliver the prompt: the session was busy or the target was not found (the job is `cancelled`), or another attempt took the record over while this one waited (the record is left to its new owner, unchanged) |
|
||||
|
||||
---
|
||||
|
||||
## 🔁 Review loop
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
actor User as User
|
||||
participant PM as Project Manager
|
||||
participant W as Worker
|
||||
actor User
|
||||
participant L as run_loop.sh
|
||||
participant P as Planner (optional)
|
||||
participant C as Creator
|
||||
participant R as Reviewers
|
||||
participant M as MQTT Backplane
|
||||
|
||||
User->>PM: Hand over requirements
|
||||
Note over PM: Plan tasks & register jobs
|
||||
PM->>M: Register Job & start Subscriber
|
||||
PM->>W: Delegate task (Provide Job ID & Brief)
|
||||
W->>M: Publish 'started' event
|
||||
Note over W: Implement & verify code
|
||||
W->>M: Publish 'completed' (or 'error')
|
||||
PM->>R: Request parallel reviews (Provide Diff)
|
||||
Note over R: Parallel analysis (Claude, Hermes, Grok, OpenCode, Codex)
|
||||
alt Review Feedback (NOT PASS)
|
||||
R->>PM: NOT PASS (Feedback with code blocks)
|
||||
Note over PM: Apply fixes or re-delegate
|
||||
PM->>W: Re-delegate with comments
|
||||
else Verification PASS
|
||||
R->>PM: PASS
|
||||
User->>L: --task, --creator, --reviewer / --all-reviewer
|
||||
opt --plan
|
||||
L->>P: write the plan (Creator challenges it for --plan-talk turns)
|
||||
end
|
||||
PM->>User: Commit changes & Report completion
|
||||
L->>C: implement and commit (skipped with --review-only)
|
||||
loop up to --max-loop
|
||||
L->>R: review the snapshot diff (base..head)
|
||||
alt every reviewer PASS and the source unchanged
|
||||
R-->>L: [VERDICT: PASS]
|
||||
else NOT PASS
|
||||
R-->>L: [VERDICT: NOT PASS] + findings
|
||||
L->>C: fix (or [REBUT:] up to --max-rebut)
|
||||
end
|
||||
end
|
||||
L->>User: reports promoted to .agents/reports/<session>/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔒 Security & Replay Attack Defense
|
||||
|
||||
To ensure communication integrity across public MQTT brokers, the backplane integrates an **HMAC-SHA256 signature protocol**:
|
||||
* **PoC Mode (Unauthenticated):** Default mode where `auth_token` is `null`, skipping cryptographic validations for quick setups.
|
||||
* **Production Mode (Authenticated):** A unique cryptographic token is issued per job. Event payloads must include an `hmac_sig` computed with the token.
|
||||
* **Replay Attack Mitigation:** Each event carries a monotonically increasing integer sequence counter (`seq`). The subscriber (`job_subscriber.py`) drops any payload whose sequence number is not strictly greater than the highest sequence number it has already accepted for that job. Combined with the HMAC signature on the payload body, this rejects both re-injected and out-of-order packets without relying on clock synchronization. The wire-format timestamp field is advisory metadata only; the backplane does not enforce a clock-skew window.
|
||||
- **Verdicts are strict**: the verdict token must stand alone on the last line of the report. A missing verdict counts as `NOT PASS`.
|
||||
- **Review identity** (`--worktree` / `--base`): each round reviews a snapshot that includes uncommitted files. If the source changes during the round, its approvals are discarded. A promoted report gets a `report-<job>.identity.json` sidecar that records the base, head, tree and reviewer.
|
||||
- **Sub-jobs**: if the creator delegates part of its work (`--parent-job`), the loop waits for those jobs before the review and shows their status to the reviewers.
|
||||
|
||||
---
|
||||
|
||||
## 📁 Repository Layout
|
||||
## 🔐 Security
|
||||
|
||||
- **Signed events**: a job gets its own token (`auth_token`) when you pass one, or automatically when the broker uses TLS or a username. Each event and each retained state message then carries an HMAC-SHA256 signature made with it, and the subscriber drops anything that fails verification. Events and state messages carry only the signature, not the token. If no token is passed and the broker has neither TLS nor a username (the PoC setup), a job has no token and signatures are not checked.
|
||||
- **Remote dispatch carries the token**: the `remote:<name>` dispatch message includes the job's token (signed with `MAM_DISPATCH_SECRET`, not encrypted). Use it only on an access-controlled private broker.
|
||||
- **Replay and ordering**: each event carries an increasing `seq`. The subscriber accepts only sequence numbers higher than any it has seen and records gaps as `seq_gap`. Timestamps are informational only.
|
||||
- **Credentials**: broker credentials live only in `.mam.env`, never in a job record.
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Tests
|
||||
|
||||
```bash
|
||||
.venv/bin/python -m pytest -q -p no:cacheprovider tests
|
||||
```
|
||||
|
||||
- The suite has about 1,900 tests, and a full run takes over an hour.
|
||||
- It runs its own in-process MQTT broker, so it never needs `.mam.env`. Don't export `.mam.env` for tests.
|
||||
- Every test gets a temporary job registry and audit-log directory. About a third also use the sandbox fixtures, which set a temporary HOME (and, for fewer, a mock herdr):
|
||||
- the tests that drive a real herdr start their own throwaway herdr server;
|
||||
- after the run, session-level guards check the real control plane and your agent homes (`~/.claude/projects`, `~/.codex`, `~/.gemini`, …) and fail the run if a test left entries there.
|
||||
- Some tests are platform-specific. A few need Python 3.11+ (`tomllib`), Linux (`/proc`) or the `nats-docker` submodule; elsewhere they are skipped.
|
||||
|
||||
---
|
||||
|
||||
## 📁 Repository layout
|
||||
|
||||
```text
|
||||
.
|
||||
├── .agents/
|
||||
│ ├── MULTI_AGENT_RULES.md # Agent roles, snapshottings, and execution charter
|
||||
│ ├── MULTI_AGENT_RULES.ko.md # Agent roles, snapshottings, and execution charter (Korean)
|
||||
│ └── skills/ # Core orchestration shell wrappers & libraries
|
||||
│ ├── lib.sh # Shared orchestration library
|
||||
│ ├── lib_py/ # Python core orchestration engine
|
||||
│ │ ├── agents/ # Multi-agent CLI lifecycle adapters
|
||||
│ │ ├── delegation/ # Asynchronous delegation & CAS state engine
|
||||
│ │ └── loop/ # Autonomous planning-execution-review loop runtime
|
||||
│ ├── multi-agent-mux-create/
|
||||
│ ├── multi-agent-mux-stop/
|
||||
│ ├── multi-agent-mux-resume/
|
||||
│ ├── multi-agent-mux-status/
|
||||
│ ├── multi-agent-mux-monitor/
|
||||
│ ├── multi-agent-mux-delegate-job/
|
||||
│ │ ├── requirements.txt # Python dependency declaration
|
||||
│ │ └── scripts/ # Wire-compatibility shims (Python)
|
||||
│ ├── multi-agent-mux-loop/
|
||||
│ └── multi-agent-mux-orc-onboard/
|
||||
├── .mam/ # Multi-Agent Mux metadata (git-ignored)
|
||||
│ ├── agent-sessions.db # SQLite WAL session database
|
||||
│ ├── agent-sessions.yaml # Human-readable session registry
|
||||
│ └── jobs/ # Asynchronous job metadata files
|
||||
├── deploy/ # Distribution and installation package
|
||||
│ ├── INSTALL.md # User manual for installation and quick-start
|
||||
│ ├── install_mam.sh # Local/Clone installer script
|
||||
│ ├── generate-env.sh # Environment bootstrap helper
|
||||
│ ├── install.sh # Remote/Network installer script
|
||||
│ ├── update.sh # Updater script
|
||||
│ └── remove.sh # Uninstaller script
|
||||
├── docs/ # Specifications, guides, and architectural contracts
|
||||
│ ├── contracts/ # Issue/backplane contracts and migration roadmaps
|
||||
│ ├── MAM_WEB_PTY_BRIDGE_PLAN.md # Web PTY terminal bridge design plan
|
||||
│ ├── NEW_AGENT_INTEGRATION_GUIDE.md # Guide for integrating new AI coding agents
|
||||
│ └── OPENCODE_OLLAMA_GUIDE.md # OpenCode interpreter + Ollama integration guide
|
||||
├── nats-docker/ # Private NATS broker deployment submodule
|
||||
├── tests/ # Comprehensive test suite (32 modules)
|
||||
├── AGENTS.md # Behavioral guidelines and orchestrator scope guards
|
||||
├── BOOTSTRAP.ko.md # Installation and verification guide (Korean)
|
||||
├── BOOTSTRAP.md # Detailed installation and verification guide
|
||||
├── IMPROVEMENTS.md # Backlog tracking issues and completed architectural tasks
|
||||
├── MESSAGING.md # MQTT wire protocol specification and internals
|
||||
├── README.ko.md # Project introduction and overview (Korean)
|
||||
├── README.md # Project introduction and overview (this file)
|
||||
└── VERSIONS.md # Release notes and 4-way lockstep version ledger
|
||||
│ ├── MULTI_AGENT_RULES.md / .ko.md # Roles, workflow and collaboration rules
|
||||
│ ├── reports/ # Promoted review reports (+ identity sidecars)
|
||||
│ └── skills/
|
||||
│ ├── lib.sh # Shared shell library (herdr shim, registry writes)
|
||||
│ ├── lib_py/ # Python core
|
||||
│ │ ├── agents/ # Per-agent CLI adapters (spawn/resume/discover)
|
||||
│ │ ├── delegation/ # Job registry, wrapper, MQTT publish/subscribe, remote runner
|
||||
│ │ ├── loop/ # Review-loop runtime
|
||||
│ │ └── *.py # pane_lock, stall_watch, worktree, herdr_config, ...
|
||||
│ └── multi-agent-mux-*/ # One directory per skill (SKILL.md + scripts/)
|
||||
├── .mam/ # Runtime state (git-ignored): sessions, jobs, audit logs, shim
|
||||
├── deploy/ # install.sh, install_mam.sh, update.sh, remove.sh, generate-env.sh
|
||||
├── docs/ # contracts/, design/, agent integration and bridge guides
|
||||
├── nats-docker/ # Private NATS broker deployment (submodule)
|
||||
├── tests/ # pytest suite
|
||||
├── AGENTS.md # Behavioural guidelines for agents
|
||||
├── BOOTSTRAP.md / BOOTSTRAP.ko.md # Step-by-step setup and verification
|
||||
├── IMPROVEMENTS.md # Backlog
|
||||
├── MESSAGING.md # MQTT wire protocol and delegation contract
|
||||
├── README.ko.md # Korean README
|
||||
└── VERSIONS.md # Release notes (lockstep version ledger)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚦 Quick Start
|
||||
|
||||
For detailed setup instructions, please consult the **[BOOTSTRAP.md](./BOOTSTRAP.md)** file. Below is a quick summary:
|
||||
See [BOOTSTRAP.md](BOOTSTRAP.md) for the full walkthrough. In short:
|
||||
|
||||
1. **Initialize Environment Config:**
|
||||
```bash
|
||||
./deploy/generate-env.sh
|
||||
```
|
||||
2. **Create Virtual Environment and Install Dependencies:**
|
||||
```bash
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
pip install -r .agents/skills/multi-agent-mux-delegate-job/requirements.txt
|
||||
```
|
||||
3. **Run Registry Diagnostics:**
|
||||
```bash
|
||||
.venv/bin/python3 .agents/skills/multi-agent-mux-delegate-job/scripts/registry.py list
|
||||
```
|
||||
```bash
|
||||
# 1. Install into the workspace, then set the broker in .mam.env
|
||||
bash deploy/install.sh
|
||||
|
||||
# 2. Start a creator and a reviewer on a dedicated herdr server
|
||||
bash .agents/skills/multi-agent-mux-create/scripts/create_session.sh \
|
||||
--workspace "$PWD" --agent claude --role developer --session creator-claude-01 \
|
||||
--herdr-session my-project --onboard
|
||||
bash .agents/skills/multi-agent-mux-create/scripts/create_session.sh \
|
||||
--workspace "$PWD" --agent codex --role reviewer --session reviewer-codex-01 \
|
||||
--herdr-session my-project --onboard
|
||||
|
||||
# 3. Check the sessions
|
||||
bash .agents/skills/multi-agent-mux-status/scripts/status.sh
|
||||
|
||||
# 4. Run a task through the loop
|
||||
bash .agents/skills/multi-agent-mux-loop/scripts/run_loop.sh \
|
||||
--creator creator-claude-01 --all-reviewer --task "Fix the typo in docs/guide.md"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 Guidelines for Collaborating Agents
|
||||
## 📝 For agents joining the project
|
||||
|
||||
If you are an AI agent newly onboarded to this project:
|
||||
1. Read **[MULTI_AGENT_RULES.md](.agents/MULTI_AGENT_RULES.md)** to align on development constraints and roles (PM, Worker, Reviewer).
|
||||
2. Adhere to the **Pane Snapshotting Rules** in `MULTI_AGENT_RULES.md` (Section 4) to prevent scrollback data loss during long execution steps.
|
||||
3. Never modify core logic without submitting a diff to the reviewer sessions for evaluation.
|
||||
1. Read [AGENTS.md](AGENTS.md) and [MULTI_AGENT_RULES.md](.agents/MULTI_AGENT_RULES.md) for roles and rules.
|
||||
2. Follow the snapshotting rules in `MULTI_AGENT_RULES.md` §4, so long outputs are not lost to the pane's scrollback.
|
||||
3. Publish your job's events as your brief instructs (`started --heartbeat`, then `completed` or `error`). Don't change core logic without a reviewed diff.
|
||||
+22
-10
@@ -6,7 +6,7 @@
|
||||
|
||||
## 📌 현재 버전 개요 (Current Release)
|
||||
|
||||
- **프레임워크 버전**: `v4.9.1`
|
||||
- **프레임워크 버전**: `v4.9.2`
|
||||
- **최신 릴리스 일시**: 2026-10-13 (KST)
|
||||
- **기준 브랜치**: `main`
|
||||
- **핵심 아키텍처**:
|
||||
@@ -24,23 +24,35 @@
|
||||
|
||||
## 🧭 스킬 패키지 버전 매트릭스 (Skills Version Matrix)
|
||||
|
||||
모든 8개 스킬은 YAML frontmatter 메타데이터(`author`, `version`, `platforms`, `environments`) 표준화를 통해 `v4.9.1`로 동기화되어 배포됩니다.
|
||||
모든 8개 스킬은 YAML frontmatter 메타데이터(`author`, `version`, `platforms`, `environments`) 표준화를 통해 `v4.9.2`로 동기화되어 배포됩니다.
|
||||
|
||||
| 스킬명 | 버전 | 역할 및 주요 책임 | 상태 |
|
||||
| :--- | :---: | :--- | :---: |
|
||||
| **`multi-agent-mux-create`** | `4.9.1` | 에이전트 세션 신규 생성 및 Herdr 컨테이너 격리 스폰 | ✅ 배포 |
|
||||
| **`multi-agent-mux-stop`** | `4.9.1` | 대화 UUID 원자적 캡처 및 세션 안전 종료 (Graceful Stop) | ✅ 배포 |
|
||||
| **`multi-agent-mux-resume`** | `4.9.1` | 온디스크 대화 컨텍스트 기반 Tier-1 초고속 세션 복원 | ✅ 배포 |
|
||||
| **`multi-agent-mux-status`** | `4.9.1` | 실시간 Herdr 세션 및 레지스트리 드리프트 스냅샷 조회 | ✅ 배포 |
|
||||
| **`multi-agent-mux-monitor`** | `4.9.1` | YAML ↔ 런타임 상태 간 자율 조정자 (Reconciler Loop) | ✅ 배포 |
|
||||
| **`multi-agent-mux-delegate-job`** | `4.9.1` | MQTT 이벤트 채널 기반 비동기 단위 작업 위임 | ✅ 배포 |
|
||||
| **`multi-agent-mux-loop`** | `4.9.1` | Planner-Creator-Reviewer 3자 자율 계획·실행·피어리뷰 루프 | ✅ 배포 |
|
||||
| **`multi-agent-mux-orc-onboard`** | `4.9.1` | 오케스트레이터 UUID 격리 등록 및 서브 세션 오염 방지 | ✅ 배포 |
|
||||
| **`multi-agent-mux-create`** | `4.9.2` | 에이전트 세션 신규 생성 및 Herdr 컨테이너 격리 스폰 | ✅ 배포 |
|
||||
| **`multi-agent-mux-stop`** | `4.9.2` | 대화 UUID 원자적 캡처 및 세션 안전 종료 (Graceful Stop) | ✅ 배포 |
|
||||
| **`multi-agent-mux-resume`** | `4.9.2` | 온디스크 대화 컨텍스트 기반 Tier-1 초고속 세션 복원 | ✅ 배포 |
|
||||
| **`multi-agent-mux-status`** | `4.9.2` | 실시간 Herdr 세션 및 레지스트리 드리프트 스냅샷 조회 | ✅ 배포 |
|
||||
| **`multi-agent-mux-monitor`** | `4.9.2` | YAML ↔ 런타임 상태 간 자율 조정자 (Reconciler Loop) | ✅ 배포 |
|
||||
| **`multi-agent-mux-delegate-job`** | `4.9.2` | MQTT 이벤트 채널 기반 비동기 단위 작업 위임 | ✅ 배포 |
|
||||
| **`multi-agent-mux-loop`** | `4.9.2` | Planner-Creator-Reviewer 3자 자율 계획·실행·피어리뷰 루프 | ✅ 배포 |
|
||||
| **`multi-agent-mux-orc-onboard`** | `4.9.2` | 오케스트레이터 UUID 격리 등록 및 서브 세션 오염 방지 | ✅ 배포 |
|
||||
|
||||
---
|
||||
|
||||
## 📋 버전별 상세 변경 내역 (Changelog)
|
||||
|
||||
### 🚀 `v4.9.2` — README 를 현재 코드에 맞춰 다시 쓴다 (2026-10-13)
|
||||
|
||||
> **패치 (PATCH Release, 문서 전용)**: 코드 변경 없음. `README.md` 를 v4.9.1 의 코드와 대조해 다시 쓰고 `README.ko.md` 를 같은 내용으로 맞췄다.
|
||||
|
||||
#### 🌟 주요 개선 사항
|
||||
1. **낡은 설명 정정**: shim 은 `/tmp/multi-agent-herdr-shim/<server>` + `herdr -L` 이 아니라 `<workspace>/.mam/shim/herdr` + `--session`; 레지스트리 쓰기는 시스템 `python3` 이 아니라 `AGENT_PYTHON_BIN` → 가상환경 → 가장 가까운 `.venv` → `PATH` 의 `python3` 순; `install.sh` 의 실제 동작(검사 항목, `MQTT_BROKER=localhost` 초기 `.mam.env`, 기존 파일 보존, `.env` 복사); 저장소 구조와 Quick Start.
|
||||
2. **빠졌던 내용 추가**: 위임 계약(전달 T·heartbeat·K×N·예산·바쁜 세션 대기·원격 전송·종료 코드 표), 리뷰 루프(선택한 리뷰어 전원 PASS, 옵션이 없으면 creator self-review, 엄격한 판정, 리뷰 identity, 하위 잡), `create --onboard` 44/45, 서버별 pane claim, 워크스페이스 이름의 기본 서버와 조건부 자동 기동, restore-off 와 그 폴백, 보안 조건(토큰은 넘기거나 TLS/username 일 때만; 원격 디스패치에는 토큰이 실림), 테스트 격리.
|
||||
|
||||
#### ✅ 품질 검증
|
||||
- **리뷰 (`--review-only`, `--all-reviewer`, 사실 대조)**: 1회차(@20b1014) agy PASS, claude·grok·codex NOT PASS(설치 동작, 보안 조건, 서버 격리, 리뷰어 선택, 인터프리터 등); 2회차(@423abc7, `README.ko.md` 포함) claude·agy PASS, grok·codex NOT PASS(종료 코드 5 의 superseded, `.env` 복사, restore 폴백); 3회차(@ae28137) grok NOT PASS(샌드박스 픽스처 비율, generate-env); 4회차(@62da805) **4/4 PASS**. 리포트는 `.agents/reports/<session>/`.
|
||||
- **리뷰 중 발견(별도 수정)**: `tests/test_issue50_dispatch.py::test_u1e_a…` 가 `WORKSPACE_ROOT` 없이 래퍼를 실행해 체크아웃의 `.mam/shim/herdr` 를 쓴다(claude 재현). 다음 릴리스에서 고친다.
|
||||
|
||||
### 🚀 `v4.9.1` — 테스트가 실제 herdr 서버에 세션을 만들지 않는다 (2026-10-13)
|
||||
|
||||
> **패치 (PATCH Release)**: v4.9.0 병합 검증 중 에이전트 pane 에서 `--basetemp .../pytest-pr56-shim` 으로 돌린 스위트가 그 pane 의 실제 서버(`multi-agent-mux`)에 워크스페이스 7개를 남겼다(정리 완료). 제품 코드 변경은 실제 herdr 해석기의 `-shim` 규칙 한 가지.
|
||||
|
||||
Reference in new issue
Block a user