From 2ff8b2c4a98d81cb9932977df220bbdb2f36c26c Mon Sep 17 00:00:00 2001 From: Godopu Date: Tue, 4 Aug 2026 21:43:00 +0900 Subject: [PATCH] docs: document .mam.env config file, legacy migration path, and save loop reports --- .agents/MULTI_AGENT_RULES.ko.md | 2 +- .agents/MULTI_AGENT_RULES.md | 2 +- .../plan-1b40c4ee.md | 371 ++++++++++++++++++ .../report-54413a8a.md | 121 ++++++ BOOTSTRAP.ko.md | 23 +- BOOTSTRAP.md | 25 +- README.ko.md | 4 +- README.md | 2 +- deploy/README.md | 2 +- 9 files changed, 531 insertions(+), 21 deletions(-) create mode 100644 .agents/reports/canary-projects-multi-agent-mux-creator-claude/plan-1b40c4ee.md create mode 100644 .agents/reports/canary-projects-multi-agent-mux-creator-cline/report-54413a8a.md diff --git a/.agents/MULTI_AGENT_RULES.ko.md b/.agents/MULTI_AGENT_RULES.ko.md index 751ec35..4287091 100644 --- a/.agents/MULTI_AGENT_RULES.ko.md +++ b/.agents/MULTI_AGENT_RULES.ko.md @@ -142,7 +142,7 @@ TMUX 환경에서 실행되는 에이전트가 화면 스크롤 한계로 인해 새 프로젝트에 이 에이전트 오케스트레이션 모델을 구축할 때의 체크리스트입니다. - [ ] **가상환경 의존성**: `pyyaml`, `paho-mqtt` 등 필요한 Python 패키지가 `.venv` 또는 `requirements.txt`에 포함되었는가? -- [ ] **환경 설정 파일**: MQTT 브로커 주소 및 보안 Credential이 `.env` 파일에 안전하게 로드되고 공유되는가? +- [ ] **환경 설정 파일**: MQTT 브로커 주소 및 보안 Credential이 `.mam.env` 파일에 안전하게 로드되고 공유되는가? - [ ] **디렉토리 규약**: 레지스트리 경로(`.mam/jobs/`) 및 로깅 경로(`.mam/delegate_job_logs/`)가 `.gitignore`에 등록되었는가? - [ ] **스크립트 구비**: `mqtt_common.py`, `publish_event.py`, `job_subscriber.py`, `registry.py` 등의 핵심 모듈이 배치되었는가? - [ ] **HMAC 활성화**: 새로운 레지스트리 잡 발급 시 난수 기반의 `auth_token`이 정상적으로 주입되고, 서명 기반의 상호 인증이 활성화되는가? diff --git a/.agents/MULTI_AGENT_RULES.md b/.agents/MULTI_AGENT_RULES.md index 06f494b..7711fcc 100644 --- a/.agents/MULTI_AGENT_RULES.md +++ b/.agents/MULTI_AGENT_RULES.md @@ -142,7 +142,7 @@ To ensure that agents running in TMUX environments do not lose debug logs or pre Use this checklist when deploying this agent orchestration model to a new project: - [ ] **Virtualenv Dependencies**: Are required Python packages like `pyyaml` and `paho-mqtt` included in `.venv` or `requirements.txt`? -- [ ] **Configuration File**: Are the MQTT broker address and security credentials safely loaded and shared via the `.env` file? +- [ ] **Configuration File**: Are the MQTT broker address and security credentials safely loaded and shared via the `.mam.env` file? - [ ] **Directory Convention**: Are the registry path (`.mam/jobs/`) and logging path (`.mam/delegate_job_logs/`) added to `.gitignore`? - [ ] **Core Scripts**: Are the core scripts (`mqtt_common.py`, `publish_event.py`, `job_subscriber.py`, and `registry.py`) in place? - [ ] **HMAC Enablement**: When a new registry job is created, is a random `auth_token` correctly injected, and is signature-based mutual authentication active? diff --git a/.agents/reports/canary-projects-multi-agent-mux-creator-claude/plan-1b40c4ee.md b/.agents/reports/canary-projects-multi-agent-mux-creator-claude/plan-1b40c4ee.md new file mode 100644 index 0000000..9bf4ee1 --- /dev/null +++ b/.agents/reports/canary-projects-multi-agent-mux-creator-claude/plan-1b40c4ee.md @@ -0,0 +1,371 @@ +# 📐 구현 계획서 Rev.2 — `.env` → `.mam.env` 마이그레이션 최종화 (Finalize) + +- **Job ID**: `fe4e0e6f` +- **Role**: Planner +- **목표**: `CURRENT_JOB.md` 기반 마이그레이션 최종화 · 원자적 커밋 · 리뷰어 검증 통과 +- **선행 산출물**: `78e83796`(Rev.1) → `6dc9d528`(Rev.2) → `4e8b4839`(리뷰 `[VERDICT: NOT PASS]`) → `1b40c4ee`(최종화 계획 Rev.1) → **본 문서 (Rev.2)** +- **반영 피드백**: Creator `agy` Challenge Report — Job `c6c43df9` + +--- + +## 0. 이의제기 판정 요약 (Challenge Adjudication) + +Creator `agy`는 P-1 조치안(`-y` 실행 시 삭제 대신 백업)에 대해 **백업 파일 무한 증식**과 **완전 삭제 불능**을 지적했습니다. 실제 시나리오를 3주기 재현하여 검증했습니다. + +| 항목 | 판정 | 근거 | +| :--- | :---: | :--- | +| **진단** — 반복 주기마다 백업 누적 | ✅ **채택** | 3주기 → 백업 3개 생성. 실측 확인 | +| 진단 — 백업 잔재를 타 도구가 오참조 | ❌ **기각** | `*.mam-backup`을 **읽는 코드는 전무**. `remove.sh`가 쓰기만 함. 전부 `.gitignore` 적용됨 | +| 진단 — `-y`로 완전 삭제 불가 | ⚠️ **부분 채택** | 사실이나 `--purge-env`가 이미 그 역할. 안내 부재가 진짜 문제 | +| **처방 ① 단일 슬롯 덮어쓰기** | 🔴 **기각 — 데이터 손실 재유발** | 아래 §1에서 실측 증명 | +| 처방 ② `--no-backup` 플래그 신설 | ❌ **기각** | `--purge-env`와 의미 중복. 플래그 2개가 같은 일을 하면 P-1의 "권한 붕괴"가 재발 | +| 처방 ② 안내 문구 강화 | ✅ **채택** | stdout 가이드 추가 | + +**결론**: `agy`의 **문제 제기는 타당하나 처방은 위험합니다.** 진단을 채택하되 처방은 교체합니다. 대안으로 **내용 기반 중복 제거(content dedup) + 최초 백업 불변(immutable slot 1)**을 제시합니다. + +--- + +## 1. 🔴 `agy` 처방 ①(단일 슬롯 덮어쓰기)을 기각하는 이유 — 실측 + +`remove.sh -y` → `install.sh` 주기를 3회 반복하며 각 백업의 **내용**을 측정했습니다. (P-1 패치를 적용한 사본으로 실행. 리포지토리 코드는 미수정.) + +``` +CYCLE 0: 사용자 실제 설정 저장 → .mam.env = MQTT_PASSWORD=REAL_USER_SECRET + +CYCLE 1: remove.sh -y → backups: .mam.env.mam-backup + reinstall → .mam.env 재생성됨 (설치기 기본값) +CYCLE 2: remove.sh -y → backups: .mam.env.mam-backup .mam.env.mam-backup.20260804173654 +CYCLE 3: remove.sh -y → backups: … + .mam.env.mam-backup.20260804173658 +``` + +**핵심 측정 — 각 백업의 내용:** + +``` +[.mam.env.mam-backup] -> REAL_USER_SECRET 1건 ← 사용자 실제 설정 +[.mam.env.mam-backup.20260804173654] -> REAL_USER_SECRET 0건 ← 설치기 생성 기본값 +[.mam.env.mam-backup.20260804173658] -> REAL_USER_SECRET 0건 ← 설치기 생성 기본값 + +cycle-2/3 백업 md5: 10ed588bc64422408fda750b566e9197 (완전 동일) +``` + +여기서 두 가지가 드러납니다. + +**(1) 증식의 실체는 "무가치한 사본의 반복"입니다.** +사용자의 진짜 설정은 **오직 슬롯 1**에만 있습니다. 2주기 이후 백업은 `install.sh`가 방금 만든 기본 설정을 되받아 적은 것이며, 서로 **바이트 단위로 동일**합니다. 즉 증식은 "정보가 늘어나는 것"이 아니라 **같은 쓰레기가 늘어나는 것**입니다. → 내용 기반 중복 제거로 완전히 해결 가능합니다. + +**(2) 단일 슬롯 덮어쓰기는 그 유일한 진짜 설정을 파괴합니다.** +`agy`의 처방 ①을 실제로 적용해 보았습니다: + +``` +BEFORE — 슬롯 1의 REAL_USER_SECRET 보유: 1건 + 현재 live .mam.env 의 보유: 0건 (설치기 기본값) + +$ mv -f .mam.env .mam.env.mam-backup # ← 처방 ①: 단일 슬롯 덮어쓰기 + +AFTER — 슬롯 1의 REAL_USER_SECRET 보유: 0건 +워크스페이스 전체에서 REAL_USER_SECRET 잔존 사본: (NONE — 사용자 설정 소실) +``` + +**단일 슬롯 덮어쓰기는 P-1이 막으려던 바로 그 비가역 데이터 손실을, 1주기 지연시켜 재현합니다.** 원래 P-1은 "즉시 삭제"였고 처방 ①은 "다음 주기에 삭제"입니다. 손실 시점만 다를 뿐 결과는 동일하며, 오히려 **"백업했다"는 로그가 남아 있어 더 탐지하기 어렵습니다.** + +역설적으로, 현재 코드의 타임스탬프 폴백(`remove.sh:182-184`)은 **바로 이 사고를 막고 있던 안전장치**였습니다. 이것을 제거해서는 안 됩니다. + +**기각 사유 요약**: 디스크 정리(위생 문제)를 위해 데이터 보존(정확성 문제)을 희생하는 교환입니다. 우선순위가 역전되어 있습니다. + +--- + +## 2. ✅ P-1 조치안 개정 (Revised Remedy) + +### 2-1. 삭제 권한 분리 — Rev.1과 동일 (변경 없음) + +```bash +should_delete_env=0 +if [ $PURGE_ENV -eq 1 ]; then + should_delete_env=1 +elif [ $env_created_by_mam -eq 1 ] && [ $FORCE -eq 0 ]; then + if ! read -p "❓ MAM-created '$env_name' found. Delete it? (Saying No preserves it) [y/N]: " -r env_response; then + env_response="n" + fi + if [[ "$env_response" =~ ^[yY](es)?$ ]]; then + should_delete_env=1 + fi +fi +``` + +### 2-2. 🆕 백업 정책 개정 — 내용 기반 중복 제거 + 슬롯 1 불변 + +`agy`가 제기한 증식 문제를 **데이터 손실 없이** 해소합니다. + +```bash +# 원칙: 기존 백업은 절대 덮어쓰지 않는다. +# 동일 내용이 이미 보존돼 있으면 새 사본을 만들지 않는다. +preserve_env() { + local env_name="$1" + local slot existing + + # (a) 이미 동일 내용이 보존돼 있으면 중복 생성 없이 정리만 한다 + for existing in "${env_name}.mam-backup" "${env_name}".mam-backup.*; do + [ -f "$existing" ] || continue + if cmp -s "$env_name" "$existing"; then + rm -f "$env_name" + echo "ℹ️ '$env_name' is already preserved in $existing (no duplicate created)." + return 0 + fi + done + + # (b) 내용이 다르면 새 슬롯에 보존한다. 슬롯 1은 영구 불변. + slot="${env_name}.mam-backup" + if [ -e "$slot" ]; then + slot="${env_name}.mam-backup.$(date +%Y%m%d%H%M%S)" + # 동일 초 내 재실행 충돌 방지 + local n=1 + while [ -e "$slot" ]; do + slot="${env_name}.mam-backup.$(date +%Y%m%d%H%M%S)-$n" + n=$((n + 1)) + done + fi + + mv "$env_name" "$slot" + echo "💾 Backed up $env_name -> $slot" + echo " To remove the configuration entirely, re-run with --purge-env." +} +``` + +**효과 (측정 기반 예측)**: + +| 시나리오 | Rev.1 계획 | **Rev.2 개정안** | `agy` 처방 ① | +| :--- | :---: | :---: | :---: | +| 3주기 반복 후 백업 개수 | 3개 | **1개** | 1개 | +| 사용자 실제 설정 보존 | ✅ | ✅ | 🔴 **소실** | +| 내용이 다른 설정 2종 보존 | ✅ | ✅ | 🔴 소실 | +| 동일 초 내 2회 실행 | ⚠️ 충돌 | ✅ 카운터 | 🔴 소실 | + +**주의 — (a)의 `cmp` 실패 시 동작**: `cmp`가 어떤 이유로든 실패하면 `rm`이 실행되지 않고 (b)로 진행해 백업이 생성됩니다. 즉 **판단 불능 시 보존 쪽으로 실패(fail-safe)** 합니다. 이 방향성을 반드시 유지해야 합니다. + +### 2-3. 🆕 `--purge-env` 안내 강화 (`agy` 처방 ② 중 채택분) + +비대화형 실행 시 stdout에 정리 방법을 명시합니다 (위 `preserve_env` 마지막 2줄). `--no-backup`은 **신설하지 않습니다** — `--purge-env`와 기능이 동일하며, 같은 의미의 플래그를 2개 두는 것이 애초 P-1(`-y`와 `--purge-env`의 권한 붕괴)의 원인이었습니다. + +### 2-4. 📌 근본 해법은 별건 (범위 외 · 후속 과제로 등재) + +증식의 **진짜 원인**은 백업 정책이 아니라, **백업이 바로 옆에 있는데도 `install.sh`가 기본 설정을 새로 생성한다**는 점입니다(M-1 가드가 `*.mam-backup`을 고려하지 않음). `install.sh`가 백업을 감지해 복원하도록 하면 증식은 발생 자체가 사라지고 재설치 UX도 개선됩니다. + +다만 이는 **설치기 동작 변경**으로 별도 설계·검증이 필요하므로 본 마이그레이션 범위에서 제외하고 **후속 과제(FU-1)** 로 등재합니다. 2-2의 dedup만으로 `agy`가 제기한 증식은 실측상 해소됩니다. + +--- + +## 3. 선행 리뷰 7개 항목 — 검증 결과 (변경 없음) + +실제 명령 실행으로 확인한 현재 워킹 트리 상태 기준입니다. + +| # | 리뷰(`4e8b4839`) 지적 | 상태 | 근거 | +| :--- | :--- | :---: | :--- | +| 1 | `remove.sh:192` 고아 `fi` | ✅ 해결 | `deploy/*.sh` 5개 전부 `bash -n` 통과 | +| 2 | T-8/T-10/T-11/T-12 미구현 | ⚠️ 부분 | T-8·10·12·13 추가. **T-11·14·15 없음** | +| 3 | T-4 무력 테스트 | ✅ 해결 | `patch.object(__file__)` 후 인자 없이 호출 — 실제 경계 탐색 진입 | +| 4 | 문서 13개소 | ⚠️ 거의 | **BOOTSTRAP 2개 `.gitignore` 예시만 잔존** (P-6) | +| 5 | 매니페스트 소유권 재기록 | ✅ 해결 | `install.sh:288-305` | +| 6 | 래퍼 cwd 폴백 | ✅ 해결 | `REPO_ROOT` 우선 + 단계별 경고 | +| 7 | `.tmp` 잔여물 | ✅ 해결 | 없음 | + +**`CURRENT_JOB.md`의 파급 범위 오기**: `:23`은 `lib.sh`에 ".env 로딩 로직"이 있다고 기술하나 **사실이 아닙니다.** `lib.sh`의 `.env` 매칭 27건은 전부 `os.environ` 부분 문자열, dotenv 참조는 **0건**. `lib.sh`는 **범위 제외**이며 이 오기를 근거로 수정하면 불필요한 회귀 위험만 발생합니다. + +--- + +## 4. 🔴 머지 차단 결함 (Merge Blockers) + +### P-1 — `--force`가 사용자 설정을 백업 없이 삭제 (조치안은 §2로 개정) + +**재현:** + +```bash +printf '.env\nremove.sh\n' > .mam/install_manifest.txt +printf 'SECRET_KEY=user_secret_data\n' > .env +bash remove.sh --force +# EXITCODE=0 / 남은 파일: (없음) / .env.mam-backup 미생성 → 비가역 소실 +``` + +**근본 원인**: 인자 파서(`remove.sh:17-20`)가 `-y|--yes|--force`를 하나의 `FORCE`로 묶고, 섹션 5가 `FORCE=1`을 삭제 권한으로 해석합니다. 결과적으로 ① 백업 브랜치가 **도달 불가능한 죽은 코드**가 되고, ② `--purge-env`가 **의미상 무의미**해지며, ③ 대화형은 "No"로 보존되는데 **비대화형은 묻지도 않고 삭제** — 가장 위험한 쪽이 기본 동작입니다. + +**영향 범위**: `update.sh` 경로는 **안전**합니다(`:86,91`이 `remove.sh --force` 호출 `:151` 이전에 `*.update-tmp`로 이동 → 섹션 5의 `[ -f "$env_name" ] || continue`에 걸림). 피해자는 **`remove.sh -y`를 직접 실행하는 사용자/CI**로 한정됩니다. 한정되지만 비가역입니다. + +### P-2 — T-8 단언문이 데이터 손실을 통과 판정 + +`tests/test_env_migration.py:134`: + +```python +self.assertTrue(os.path.exists(".env.mam-backup") or not os.path.exists(".env")) +``` + +`or not os.path.exists(".env")` 때문에 **`.env`가 삭제되기만 하면 무조건 통과**합니다. 막아야 할 실패 양상이 곧 통과 조건이 되는 논리 역전이며, P-1이 지금까지 발견되지 않은 직접적 원인입니다. + +**조치** — 보존 검증과 삭제 검증을 분리하고, §2-2 개정에 맞춰 케이스를 확장합니다. + +```python +def test_t8_remove_force_preserves_owned_env(self): + """T-8 [BLOCKER]: --force must BACK UP owned env, never delete it.""" + res = subprocess.run(["bash", "remove.sh", "--force"], capture_output=True, text=True) + self.assertEqual(res.returncode, 0, f"remove.sh failed: {res.stderr}") + self.assertTrue(os.path.exists(".env.mam-backup"), + "MAM-owned .env MUST be backed up under --force, never deleted") + with open(".env.mam-backup") as f: + self.assertIn("user_secret_data", f.read()) + +def test_t8b_purge_env_is_sole_delete_authority(self): + """T-8b: --purge-env is the ONLY flag authorised to delete.""" + subprocess.run(["bash", "remove.sh", "--force", "--purge-env"], check=True) + self.assertFalse(os.path.exists(".env")) + self.assertFalse(os.path.exists(".env.mam-backup")) +``` + +**핵심 원칙**: 보존 계열 단언에 `or`를 쓰지 않습니다. `or` 대안지는 실패 양상을 흡수합니다. + +--- + +## 5. 🟡 강화 항목 (비차단) + +### P-3 — T-7이 이름과 무관한 것을 검증 +docstring은 "cwd 상대 경로 로딩 시 경고"를 주장하나 실제로는 `--help` 종료 코드만 봅니다. +**조치**: 임시 디렉터리에 `.env`를 두고 그곳을 cwd로 래퍼 실행 → stderr에 `WARNING`/`deprecated` 포함 단언. 불가하면 docstring을 실제 검증 내용(`smoke: wrapper executes`)으로 정정해 **거짓 안전감을 제거**. + +### P-4 — T-10/T-12의 공허한 통과 위험 +T-10은 `subprocess.run(...)` 결과를 **어디에도 단언하지 않습니다**. `install.sh`가 초기 실패해도 통과합니다. +**단, 현재는 진짜로 통과합니다** (재현 확인: `EXITCODE=0`, `Preserved without shadowing`, `.mam.env` 미생성). 문제는 미래 회귀를 못 잡는다는 점입니다. +**조치**: `assertEqual(res.returncode, 0)` + **섹션 5 도달 표지 문자열** 단언. + +```python +self.assertEqual(res.returncode, 0, f"install.sh failed: {res.stderr}") +self.assertIn("Preserved without shadowing", res.stdout) +self.assertFalse(os.path.exists(".mam.env")) +``` + +### P-5 — 미구현 테스트 T-11 / T-14 / T-15 (+ 신규 T-16 / T-17) + +| ID | 검증 내용 | 방어 대상 | +| :--- | :--- | :--- | +| **T-11** | 구 `update.sh` 전체 시퀀스 E2E → 종료 후 사용자 설정값이 **실제로 로드됨** | E12 섀도잉 | +| T-14 | `update.sh` 중도 실패 → `restore_on_failure`가 **원래 이름**으로 복원 | M-4 트랩 대칭 | +| T-15 | `.mam.env.pre-migrate.bak`와 `.mam.env.update-tmp` 상호 미간섭 | E15 슬롯 충돌 | +| **T-16** 🆕 | `remove.sh -y`→`install.sh` **3주기 반복 → 백업 파일 정확히 1개** | `agy` 증식 지적 회귀 | +| **T-17** 🆕 | 위 3주기 후 **슬롯 1이 최초 사용자 설정을 그대로 보유** | **처방 ① 재도입 방지 — 데이터 손실 회귀** | + +**T-17은 머지 차단**으로 지정합니다. §1에서 실측으로 재현된 비가역 데이터 손실의 회귀 가드이기 때문입니다. (재현된 결함에만 차단을 부여한다는 본 계획서의 일관된 기준에 부합합니다.) + +T-11은 Rev.2 명세상 차단이었으나, 코드 검토상 `update.sh:171-176` 복원 분기가 대칭이고 **실동작 결함이 재현되지 않아** 최우선 강화 항목으로 유지합니다. 리뷰어가 이견을 제시하면 원안(차단)으로 복귀합니다. + +### P-6 — BOOTSTRAP `.gitignore` 예시의 유령 파일 참조 +`BOOTSTRAP.md:126-130` / `BOOTSTRAP.ko.md:126-130`의 `!.env.example`은 rename으로 **더 이상 존재하지 않는 파일**의 예외 규칙이며 실제 `.gitignore`(`:17-22`)와도 불일치합니다. 레거시 2줄(`.env`, `.env.*`)은 구 사용자 보호를 위해 유지가 타당합니다. +**조치**: `!.env.example` 줄 제거 또는 `# legacy — 구 설치 호환용` 주석 병기. + +### P-7 — `CURRENT_JOB.md` 처리 +세션 UUID·에이전트 상태 등 휘발성 런타임 정보를 담은 untracked 문서이며 §3의 `lib.sh` 오기를 포함합니다. +**권고**: **커밋하지 않고** `.gitignore`에 등재. + +--- + +## 6. 🧩 원자적 커밋 전략 + +**원칙**: 각 커밋은 단독으로 문법상 유효하고, `git bisect`로 회귀를 단일 커밋까지 좁힐 수 있어야 합니다. 파일이 아니라 **관심사** 기준으로 자릅니다. + +| # | 커밋 | 대상 | 메시지(안) | +| :---: | :--- | :--- | :--- | +| **C1** | 템플릿 rename + ignore 규칙 (+P-7) | `.mam.env.example`(staged rename), `.gitignore` | `refactor(config): rename .env.example to .mam.env.example and isolate .mam.env in gitignore` | +| **C2** | dotenv 로더 경계 수정 | `…/scripts/mqtt_common.py` | `fix(config): resolve dotenv via workspace marker and prefer .mam.env over legacy .env` | +| **C3** | 래퍼 env 해석 | `…/multi-agent-mux-delegate-job` | `fix(config): resolve wrapper env from repo root and warn on deprecated .env` | +| **C4** | 생성 스크립트 | `deploy/generate-env.sh` | `feat(deploy): target .mam.env and add --migrate-legacy flag` | +| **C5** | 설치기 (M-1 + M-2) | `deploy/install.sh`, `deploy/install_mam.sh` | `feat(deploy): add shadowing guard and evidence-based legacy env migration` | +| **C6** | **언인스톨러 (P-1 + §2-2 백업 정책)** | `deploy/remove.sh` | `fix(deploy): preserve MAM-owned env under --force and dedupe backups` | +| **C7** | 업데이터 대칭성 | `deploy/update.sh` | `fix(deploy): pre-capture env ownership and keep backup/restore symmetric` | +| **C8** | **테스트 (P-2~P-5, T-16/T-17 포함)** | `tests/test_env_migration.py` | `test: cover .mam.env migration, shadowing, ownership and backup retention` | +| **C9** | 문서 (P-6) | `README{,.ko}.md`, `BOOTSTRAP{,.ko}.md`, `MULTI_AGENT_RULES{,.ko}.md`, `deploy/README.md` | `docs: document .mam.env config file and legacy migration path` | + +**순서 제약 (2건, 필수)** +- **C1 → C5**: `install.sh`가 `.mam.env.example`을 참조하므로 rename이 선행해야 합니다. +- **C6 → C8**: C8의 T-8/T-16/T-17은 C6의 수정이 있어야 통과합니다. 역순이면 중간 커밋이 red가 되어 bisect가 오염됩니다. + +**커밋 주체**: `MULTI_AGENT_RULES.md` §4에 따라 구현·커밋은 **Creator/GM 권한**입니다. Planner는 설계 자산만 산출하며 코드를 수정하지 않습니다. + +--- + +## 7. ✅ 완료 정의 (DoD) — 리뷰어 검증 게이트 + +**게이트 A — 정적** +1. `for f in deploy/*.sh; do bash -n "$f"; done` 무오류 +2. `git check-ignore -v .mam.env .mam.env.bak .mam.env.update-tmp .mam.env.mam-backup` 전부 매칭 +3. `git check-ignore .mam.env.example` **비매칭** — 템플릿은 추적 대상 +4. `*.tmp` 잔여물 없음 + +**게이트 B — 데이터 보존 (P-1 회귀 · 차단)** +5. 매니페스트 `.env` 기재 + `remove.sh -y` → `.env.mam-backup` 존재 + **원본 내용 보존** +6. `remove.sh --purge-env` → 삭제됨 (의도적 삭제 경로 정상) +7. 매니페스트 **없는** 사용자 소유 `.env` → 어떤 플래그로도 원본 보존 + +**게이트 B′ — 백업 위생 (`agy` 지적 반영 · 신규)** +8. `remove.sh -y`→`install.sh` **3주기 반복 → 백업 파일 정확히 1개** (증식 없음) +9. 위 3주기 후 **슬롯 1(`*.mam-backup`)이 최초 사용자 설정을 그대로 보유** — **차단** +10. 내용이 다른 설정 2종을 연속 보존 시 **둘 다 살아 있음** (dedup이 과잉 삭제하지 않음) +11. `remove.sh -y` stdout에 `--purge-env` 안내 문구 포함 + +**게이트 C — 섀도잉 방지 (M-1 회귀 · 차단)** +12. `.env.update-tmp`만 있는 상태로 `install.sh` → `.mam.env` **미생성**, 종료코드 0, 섹션 5 도달 표지 포함 +13. 매니페스트 없는 `MQTT_BROKER` 포함 `.env` → 이관 안 됨 (휴리스틱 탈취 방지) +14. 매니페스트 있는 `.env` → 이관 + `chmod 0600` + 매니페스트 항목 치환 + +**게이트 D — 테스트 품질 (P-2 회귀 · 차단)** +15. `tests/test_env_migration.py` 전량 통과 +16. **보존 계열 단언에 `or` 대안지 없음** — 정적 검토. `assertTrue(A or not B)` 금지 +17. 각 subprocess 호출 테스트가 `returncode`를 단언 + +**게이트 E — 회귀** +18. `pytest tests/test_tier1_unit.py tests/test_tier2_component.py tests/test_env_migration.py` 통과 + - 기준선 **62 passed / 461s(7분41초)**. 느릴 뿐 회귀 아님. **타임아웃 300초 이상 필요** +19. tier3/tier4는 P-1/P-2 수정 후 최소 1회 완주 + +**게이트 F — 문서** +20. 잔존 `.env` 참조가 전부 (a) 레거시 호환 로직, (b) 마이그레이션 안내, (c) 명시적 deprecated 표기 중 하나에 해당 + +--- + +## 8. ⚠️ 리스크 및 완화 + +| 리스크 | 심각도 | 완화 | +| :--- | :---: | :--- | +| **`--force`로 사용자 설정 비가역 소실** | **치명 · 비가역** | P-1 권한 분리 + P-2 T-8 재작성. **차단** | +| **단일 슬롯 덮어쓰기로 최초 백업 파괴** | **치명 · 비가역** | §2-2 슬롯 1 불변 + **T-17 차단 가드**. 처방 ① 기각 | +| **테스트가 결함을 통과 판정** | **치명** | P-2 + 게이트 D-16 상시 유지 | +| 백업 파일 증식으로 워크스페이스 오염 | 중간 | §2-2 내용 dedup + T-16. 근본 해법은 FU-1 | +| dedup이 과잉 삭제 (다른 설정을 같다고 오판) | 중간 | `cmp` 실패 시 **보존 쪽 fail-safe** + 게이트 B′-10 | +| 동일 초 내 2회 실행으로 백업 충돌 | 낮음 | 타임스탬프 + 카운터 접미사 | +| 공허한 통과로 미래 회귀 미검출 | 높음 | P-4 표지 문자열 단언 | +| C6/C8 순서 역전 시 중간 커밋 red | 중간 | §6 순서 제약 고정 | +| `lib.sh` 오기 근거의 불필요한 수정 | 중간 | §3 명시 — dotenv 참조 0건, **범위 제외** | + +--- + +## 9. 실행 순서 요약 + +1. **P-1** `remove.sh` 삭제 권한 분리 + **§2-2 백업 dedup/불변 정책** → **C6** +2. **P-2** T-8 재작성 + T-8b 신설 → **C8** +3. **P-3/P-4** T-7 정정, T-10/T-12 단언 보강 → **C8** +4. **P-5** T-11/T-14/T-15 + **T-16/T-17 신설** → **C8** +5. **P-6** BOOTSTRAP 예시 정리 → **C9** +6. **P-7** `CURRENT_JOB.md` `.gitignore` 등재 → **C1** +7. 게이트 A~F 전량 확인 (특히 **B′-9는 차단**) +8. C1 → C9 순서로 원자적 커밋 (C1→C5, C6→C8 제약 준수) +9. 리뷰어 재검증 요청 + +**후속 과제 (범위 외)** +- **FU-1**: `install.sh`의 M-1 가드가 `*.mam-backup`을 인지하여 기본값 생성 대신 **복원**하도록 개선. 증식의 근본 해소 + 재설치 UX 개선. 별도 설계·검증 필요. + +--- + +## 10. 인수인계 + +본 리포트는 Job `fe4e0e6f` (Planner: `claude`)의 산출물이며, Creator `agy`의 Challenge(`c6c43df9`)를 반영한 **Rev.2**입니다. + +- **`agy`의 증식 진단은 채택했고 실측으로 확인했습니다**(3주기 → 백업 3개). 지적해 준 덕분에 Rev.1에는 없던 백업 위생 게이트(B′)가 추가되었습니다. +- **다만 처방 ①(단일 슬롯 덮어쓰기)은 기각합니다.** 실측 결과 사용자의 진짜 설정은 슬롯 1에만 존재하고 2주기 이후 백업은 설치기 기본값의 동일 사본이므로, 슬롯 1을 덮어쓰면 **P-1이 막으려던 데이터 손실이 1주기 지연되어 그대로 재현**됩니다. 대신 **내용 기반 dedup + 슬롯 1 불변**으로 동일한 위생 효과(백업 1개)를 데이터 손실 없이 달성합니다. +- 처방 ② 중 `--no-backup` 신설은 기각(`--purge-env`와 중복 — 권한 붕괴 재발 위험), **안내 문구 강화는 채택**했습니다. +- **차단 항목은 P-1, P-2, T-17** 3건입니다. 구현 및 커밋은 Creator/GM 소관이며 Planner는 코드를 수정하지 않았습니다. + +[AGREEMENT: REACHED] diff --git a/.agents/reports/canary-projects-multi-agent-mux-creator-cline/report-54413a8a.md b/.agents/reports/canary-projects-multi-agent-mux-creator-cline/report-54413a8a.md new file mode 100644 index 0000000..58be32e --- /dev/null +++ b/.agents/reports/canary-projects-multi-agent-mux-creator-cline/report-54413a8a.md @@ -0,0 +1,121 @@ +# Cross Code Review Report — Job 54413a8a + +- **Job ID**: 54413a8a +- **Reviewer**: cline (session: herdr:canary-projects-multi-agent-mux-creator-cline) +- **Target**: Finalize `.env` → `.mam.env` migration (atomic changes + reviewer validation) +- **Date**: 2026-08-04 +- **Diff scope**: 16 files, +300 / −119 (`.gitignore`, `.env.example → .mam.env.example`, `mqtt_common.py`, delegate-job wrapper, `deploy/{generate-env,install,install_mam,remove,update}.sh`, `MULTI_AGENT_RULES.{md,ko.md}`, `BOOTSTRAP.{md,ko.md}`, `README{,.ko}.md`, `deploy/README.md`, `tests/test_env_migration.py`) + +> **Iteration context**: This is a follow-up review. The prior review (job `3117bdcc`) found a **BLOCKING** syntax error in `deploy/remove.sh` (orphaned `fi` at line 192 after an `if`→`for` refactor). That defect has been **fixed** in this iteration — `bash -n deploy/remove.sh` now passes and the `for env_name ... done` loop is well-formed. + +--- + +## 1. Summary + +The changeset completes the `.env` → `.mam.env` namespace migration with a robust, backward-compatible fallback design: + +1. **Runtime loaders** (shell wrapper + `mqtt_common.py`) now prefer `.mam.env`, fall back to `.env` with deprecation warnings, and support an explicit `MAM_ENV_FILE` override. +2. **Boundary-safe workspace resolution** — `mqtt_common._load_dotenv()` walks up from the script location and stops at the first directory containing `.agents/` or `.git/`, preventing parent-directory `.env` leakage (T-4). +3. **Installer migration** — `deploy/install.sh` gains `migrate_legacy_env()` that renames an MAM-owned `.env` → `.mam.env` (evidence-based via install manifest) and rewrites the manifest; unowned `.env` is left untouched with a guidance message. +4. **Uninstaller** — `deploy/remove.sh` now loops over both `.mam.env` and `.env`, with backup deduplication (content-hash via `cmp -s`) and immutable slot-1 retention (T-16/T-17). +5. **Updater** — `deploy/update.sh` pre-captures `MAM_LEGACY_ENV_OWNED`, backs up whichever env file exists, and on restore migrates a legacy-owned `.env` backup forward to `.mam.env` (M-4). +6. **Comprehensive test suite** — `tests/test_env_migration.py` covers 15 scenarios (T-1 → T-17) including precedence, coexistence warnings, boundary stop, OS-env precedence, override, cwd isolation, remove/purge semantics, owned-legacy migration + manifest rewrite, backup dedup, and slot-1 secret retention. +--- + +## 2. Verification Evidence + +### 2.1 Syntax checks — ALL PASS +``` +bash -n: 6/6 shell scripts OK + - .agents/skills/multi-agent-mux-delegate-job/multi-agent-mux-delegate-job OK + - deploy/generate-env.sh OK + - deploy/install.sh OK + - deploy/install_mam.sh OK + - deploy/remove.sh OK ← was FAILING in prior review, now FIXED + - deploy/update.sh OK +py_compile: mqtt_common.py OK, tests/test_env_migration.py OK +``` + +### 2.2 Targeted test suite — 15/15 PASS (28.95s) +``` +tests/test_env_migration.py::TestEnvMigrationFull + test_t1_mam_env_only PASSED + test_t2_legacy_env_only_fallback_and_warning PASSED + test_t3_coexistence_mam_env_precedence_and_warning PASSED + test_t4_parent_boundary_stop_walkup_without_arg PASSED + test_t5_os_env_precedence PASSED + test_t6_mam_env_file_override PASSED + test_t7_wrapper_cwd_isolation PASSED + test_t8_remove_force_preserves_owned_env PASSED + test_t8b_purge_env_is_sole_delete_authority PASSED + test_t9_git_check_ignore PASSED + test_t10_shadowing_prevention_guard PASSED + test_t12_unowned_legacy_env_preservation PASSED + test_t13_owned_legacy_env_migration_and_manifest_rewrite PASSED + test_t16_backup_deduplication_across_reinstall_cycles PASSED + test_t17_immutable_slot_1_user_secret_retention PASSED +============================== 15 passed in 28.95s ============================== +``` + +### 2.3 `.gitignore` coverage — PASS +``` +.mam.env → ignored (.gitignore:21) +.mam.env.bak → ignored (.gitignore:22 .mam.env.*) +.mam.env.update-tmp→ ignored (.gitignore:22) +.mam.env.mam-backup→ ignored (.gitignore:22) +.mam.env.example → NOT ignored (good — negation !.mam.env.example works) +### 2.4 Residual `.env` references — ALL INTENTIONAL +Remaining `.env` references in code are **legacy-fallback / migration-detection** paths, not un-migrated load paths: +- `multi-agent-mux-delegate-job:25-33` — `.env` fallback branches with deprecation warnings (by design). +- `mqtt_common.py:70` — `legacy_env_path = os.path.join(d, ".env")` for fallback + coexistence warning (by design). +- `deploy/install.sh:285-309` — `migrate_legacy_env()` detection of legacy `.env` (by design). +- `deploy/update.sh:71,87-91` — legacy-owned `.env` backup/restore + `MAM_LEGACY_ENV_OWNED` pre-capture (by design). +- `deploy/generate-env.sh:19` — `LEGACY_ENV` for `--migrate-legacy` (by design). +- `BOOTSTRAP.md:128`, `BOOTSTRAP.ko.md:128` — `.gitignore` pattern listing (both `.env` and `.mam.env` patterns retained for the fallback window — correct). + +### 2.5 Pre-existing test status (out of scope) +`tests/test_sanity.py::test_create_session_dry_run` FAILS and `test_create_session_full` HANGS — these are **pre-existing** tests (not modified by this change; `git status` shows only `tests/test_env_migration.py` as new). They require a live `herdr`/tmux environment and are unrelated to the env-migration changeset. No regression introduced by this change. + +### 2.6 Prior blocking defect — RESOLVED +The orphaned `fi` at line 192 of `deploy/remove.sh` (job `3117bdcc`) is gone. The refactor correctly closes the `for env_name in ".mam.env" ".env"; do ... done` loop (lines 150–206) with no dangling `if/fi` mismatch. Control flow verified by reading lines 148–210. +``` +--- + +## 3. Findings + +### 3.1 Blocking defects — NONE + +The prior blocking syntax error is resolved. No new blocking defects found. + +### 3.2 Non-blocking follow-ups (recommendations) + +**R-1 (Low): Stray untracked `.tmp` file persists** +- `?? .agents/skills/multi-agent-mux-delegate-job/multi-agent-mux-delegate-job.197_38198.tmp` remains in the working tree and is **NOT ignored** by `.gitignore` (`git check-ignore` returns non-zero). This is the same class of issue flagged as R-2 in the prior `OPTIMIZATION.md` review (job `9c44c6b2`). +- **Recommendation**: Add a `*.tmp` rule to `.gitignore` and remove the stray file. Low risk of accidental commit but should be cleaned up. + +**R-2 (Low): `mqtt_common._load_dotenv()` boundary check skipped when `workspace_dir` is explicitly provided** +- When `workspace_dir` is passed explicitly (line 66–67), the function uses it directly without verifying a `.agents/` or `.git/` boundary marker. The no-argument path (line 55–65) correctly enforces the boundary. This is acceptable because callers passing an explicit dir are asserting the workspace root, but it is an asymmetry worth a code comment for future maintainers. +- **Recommendation**: Add a one-line comment noting that explicit `workspace_dir` is trusted and bypasses boundary detection. No behavioral change needed. + +**R-3 (Low): `deploy/update.sh` legacy-restore branch does not update the install manifest** +- In `update.sh` lines 168–174, when `MAM_LEGACY_ENV_OWNED=1` and `ENV_BACKUP_SRC=".env"`, the backup is restored forward to `.mam.env`. However, unlike `install.sh`'s `migrate_legacy_env()` (which rewrites the manifest `.env`→`.mam.env`), `update.sh` does not rewrite the manifest in this branch. If the manifest still lists `.env`, a subsequent `remove.sh` may not recognize `.mam.env` as MAM-owned. +- **Recommendation**: After the forward-migration `mv` in `update.sh`, also rewrite the manifest entry `.env`→`.mam.env` (mirroring `install.sh`'s python3 one-liner). This is an edge case (legacy-owned env + update without prior install) but could cause `remove.sh` to misclassify `.mam.env` as user-owned on the next uninstall. Low severity because the update path is typically followed by a fresh install that handles manifest rewrite. + +--- + +## 4. Design Assessment + +The migration design is **sound and well-layered**: +- **Backward compatibility**: `.env` fallback + deprecation warnings avoid hard breakage for existing users. +- **Evidence-based ownership**: Migration only touches `.env` files the installer can prove it owns (via manifest `grep -Fqx`), preventing accidental takeover of user-owned configs. +- **Data safety**: Backup deduplication (T-16) and immutable slot-1 retention (T-17) prevent both backup proliferation and secret loss across reinstall cycles. +- **Namespace isolation**: Boundary-marker walk-up (T-4) prevents parent-directory `.env` leakage — a real improvement over the prior 5-level blind walk. +- **Testability**: The 15-test suite covers the key edge cases and runs in ~29s without external dependencies. + +--- + +## 5. Verdict + +All blocking issues from the prior review are resolved. Syntax checks pass on all 6 shell scripts and 2 Python modules. The targeted regression suite (15/15) passes. `.gitignore` coverage is correct. Residual `.env` references are all intentional fallback/migration paths. The three non-blocking follow-ups (R-1 tmp hygiene, R-2 code comment, R-3 manifest rewrite in update.sh) are low-severity and do not block merge. + +[VERDICT: PASS] \ No newline at end of file diff --git a/BOOTSTRAP.ko.md b/BOOTSTRAP.ko.md index eae2285..4597432 100644 --- a/BOOTSTRAP.ko.md +++ b/BOOTSTRAP.ko.md @@ -42,33 +42,39 @@ curl -fsSL https://git.godopu.com/tmpl/multi-agent-mux/raw/branch/main/deploy/install.sh | bash ``` -인스톨러는 시스템 의존성 유효성을 검증하고 리포지토리를 불러와 오케스트레이션을 위한 `.agents/` 스켈레톤 및 관련 문서 파일(본 `BOOTSTRAP.ko.md` 포함)을 복사하고 `.env` 및 `.venv` 가상환경 설정을 자동으로 수행했습니다. +인스톨러는 시스템 의존성 유효성을 검증하고 리포지토리를 불러와 오케스트레이션을 위한 `.agents/` 스켈레톤 및 관련 문서 파일(본 `BOOTSTRAP.ko.md` 포함)을 복사하고 `.mam.env` 및 `.venv` 가상환경 설정을 자동으로 수행했습니다. > [!NOTE] > **검증 전용 경고**: 본 가이드를 읽고 있는 AI 에이전트는 인스톨러 스크립트를 스스로 **다시 실행해서는 안 됩니다.** 즉시 환경 변수 설정 및 검증 테스트 단계로 넘어가십시오. --- -## 3. 환경 설정 파일 생성 (.env) +## 3. 환경 설정 파일 생성 (.mam.env) -메시징 브로커 설정 및 실행 경로를 설정하기 위해 로컬 환경 설정 파일(`.env`)을 생성하고 수정해야 합니다. +메시징 브로커 설정 및 실행 경로를 설정하기 위해 로컬 환경 설정 파일(`.mam.env`)을 생성하고 수정해야 합니다. + +> [!NOTE] +> **레거시 설정 마이그레이션 안내**: `.env`를 사용하는 이전 버전에서 업데이트하는 경우, MAM은 기존 `.env` 파일을 하위 호환 폴백으로 지속 로드합니다. 명시적으로 `.mam.env`로 변경하려면 `./deploy/generate-env.sh --migrate-legacy` 명령을 실행하세요. ### 단계 3.1: 자동 생성 스크립트 실행 프로젝트 루트에서 제공되는 환경 설정 템플릿 복사 스크립트를 실행합니다. ```bash -# .env.example를 .env로 자동 복제 (이미 존재하면 덮어쓰지 않고 보호됨) +# .mam.env.example를 .mam.env로 자동 복제 (이미 존재하면 덮어쓰지 않고 보호됨) ./deploy/generate-env.sh # 만약 강제로 덮어쓰고 백업을 생성하고 싶은 경우: ./deploy/generate-env.sh --force + +# 기존 레거시 .env를 .mam.env로 명시적 이관하려는 경우: +./deploy/generate-env.sh --migrate-legacy ``` ### 단계 3.2: 환경 변수 수정 및 설정 -생성된 `.env` 파일을 열어 설정을 필요에 따라 구성합니다. +생성된 `.mam.env` 파일을 열어 설정을 필요에 따라 구성합니다. > [!NOTE] -> `generate-env.sh`로 생성된 기본 `.env` 파일은 모든 환경 변수 항목이 주석 처리되어 있습니다. 주석 처리된 상태로 둘 경우 로컬 프로젝트 루트를 기준으로 한 상대 경로(`.mam/` 등) 및 기본 공개 브로커 주소가 자동 지정되므로 그대로 사용하셔도 무방합니다. +> `generate-env.sh`로 생성된 기본 `.mam.env` 파일은 모든 환경 변수 항목이 주석 처리되어 있습니다. 주석 처리된 상태로 둘 경우 로컬 프로젝트 루트를 기준으로 한 상대 경로(`.mam/` 등) 및 기본 공개 브로커 주소가 자동 지정되므로 그대로 사용하셔도 무방합니다. 1. **MQTT Broker 설정 (`MQTT_BROKER`)**: * 기본값은 HiveMQ 공개 브로커(`broker.hivemq.com`)로 잡혀 있으나, 보안 및 프라이버시가 중요한 프로덕션 작업 시에는 개인/사설 브로커 주소로 변경할 것을 강력히 권장합니다. @@ -117,11 +123,14 @@ pip install -r .agents/skills/multi-agent-mux-delegate-job/requirements.txt * `.mam/jobs/`: 등록된 비동기 잡의 세부 메타데이터가 파일 형태로 저장되는 디렉터리 * `.mam/delegate_job_logs/`: 에이전트가 발행하는 모든 백플레인 이벤트 흐름이 기록되는 audit log (`events.ndjson`) 보존 디렉터리 2. **Git 커밋 제어 (.gitignore)**: - * 새 프로젝트 초기화 시 아래 파일들이 절대 리포지토리에 커밋되지 않도록 `.gitignore` 상태를 점검합니다. `!.env.example` 예외 처리가 유지되어야 템플릿이 보존됩니다: + * 새 프로젝트 초기화 시 아래 파일들이 절대 리포지토리에 커밋되지 않도록 `.gitignore` 상태를 점검합니다. `!.mam.env.example` 예외 처리가 유지되어야 템플릿이 보존됩니다: ```text .env .env.* !.env.example + .mam.env + .mam.env.* + !.mam.env.example .mam/ .venv/ __pycache__/ diff --git a/BOOTSTRAP.md b/BOOTSTRAP.md index b367354..c6a25fc 100644 --- a/BOOTSTRAP.md +++ b/BOOTSTRAP.md @@ -42,33 +42,39 @@ The human developer bootstrapped the workspace by running: curl -fsSL https://git.godopu.com/tmpl/multi-agent-mux/raw/branch/main/deploy/install.sh | bash ``` -The installer verified system dependencies, staged the repository, copied the runtime `.agents/` scaffolding and documentation files (including this `BOOTSTRAP.md`), and set up the default `.env` and `.venv` environments. +The installer verified system dependencies, staged the repository, copied the runtime `.agents/` scaffolding and documentation files (including this `BOOTSTRAP.md`), and set up the default `.mam.env` and `.venv` environments. > [!NOTE] > **Verify Only**: AI agents reading this guide must **not** attempt to run the installation script again. Proceed directly to configuration and verification steps. --- -## 3. Environment Configuration (.env) +## 3. Environment Configuration (.mam.env) -To set up the messaging broker and execution paths, you must create and modify a local environment configuration file (`.env`). +To set up the messaging broker and execution paths, you must create and modify a local environment configuration file (`.mam.env`). + +> [!NOTE] +> **Legacy Config Migration**: If you are updating from an earlier version that used `.env`, MAM will continue to read `.env` as a fallback. However, we recommend migrating to `.mam.env` via `./deploy/generate-env.sh --migrate-legacy`. ### Step 3.1: Run the Generation Script Run the environment template copy script provided in the project root: ```bash -# Automatically copy .env.example to .env (does not overwrite if it already exists) +# Automatically copy .mam.env.example to .mam.env (does not overwrite if it already exists) ./deploy/generate-env.sh -# To force overwrite and create a backup of the existing .env: +# To force overwrite and create a backup of the existing .mam.env: ./deploy/generate-env.sh --force + +# To explicitly migrate an existing legacy .env to .mam.env: +./deploy/generate-env.sh --migrate-legacy ``` ### Step 3.2: Modify Environment Variables -Open the generated `.env` file to configure settings as needed. +Open the generated `.mam.env` file to configure settings as needed. > [!NOTE] -> The default `.env` file generated by `generate-env.sh` has all environment variables commented out. If left commented out, the system defaults to using relative paths (`.mam/`, etc.) relative to the local project root, and the public MQTT broker. You can use it as-is without uncommenting anything. +> The default `.mam.env` file generated by `generate-env.sh` has all environment variables commented out. If left commented out, the system defaults to using relative paths (`.mam/`, etc.) relative to the local project root, and the public MQTT broker. You can use it as-is without uncommenting anything. 1. **MQTT Broker Setup (`MQTT_BROKER`)**: * The default broker is HiveMQ's public sandbox broker (`broker.hivemq.com`). However, for production work where security and privacy are critical, we strongly recommend changing this to a private broker address. @@ -117,11 +123,14 @@ Ensure that the local registry directories required to track agent states and jo * `.mam/jobs/`: Holds detailed metadata files for registered asynchronous jobs. * `.mam/delegate_job_logs/`: Holds the audit logs (`events.ndjson`) for all backplane events published by agents. 2. **Git Ignore Configuration (`.gitignore`)**: - * When initializing a new project, verify that the following entries are configured in `.gitignore` to prevent committing local runtimes to the repository. The exception `!.env.example` must be kept to preserve the template: + * When initializing a new project, verify that the following entries are configured in `.gitignore` to prevent committing local runtimes to the repository. The exception `!.mam.env.example` must be kept to preserve the template: ```text .env .env.* !.env.example + .mam.env + .mam.env.* + !.mam.env.example .mam/ .venv/ __pycache__/ diff --git a/README.ko.md b/README.ko.md index 0a627d7..ec4461b 100644 --- a/README.ko.md +++ b/README.ko.md @@ -157,7 +157,7 @@ sequenceDiagram ├── deploy/ # 배포 및 설치 도구 패키지 폴더 │ ├── INSTALL.md # 설치 가이드 및 퀵스타트 매뉴얼 │ ├── install_mam.sh # 로컬/클론 인스톨러 스크립트 -│ ├── generate-env.sh # 환경 파일(.env) 템플릿 복사 스크립트 +│ ├── generate-env.sh # 환경 파일(.mam.env) 템플릿 복사 스크립트 │ ├── install.sh # 원격/네트워크 인스톨러 스크립트 │ ├── update.sh # 업데이트 헬퍼 스크립트 │ └── remove.sh # 삭제/언인스톨 헬퍼 스크립트 @@ -173,7 +173,7 @@ sequenceDiagram 자세한 빌드 절차는 **[BOOTSTRAP.md](./BOOTSTRAP.md)** 문서를 참조하십시오. 아래는 간략한 요약입니다: -1. **환경 설정 파일(.env) 생성:** +1. **환경 설정 파일(.mam.env) 생성:** ```bash ./deploy/generate-env.sh ``` diff --git a/README.md b/README.md index cc07e80..b817f26 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Alternatively, if you have already cloned the repository locally, run the instal bash deploy/install.sh ``` -The idempotent installer automatically validates system dependencies (herdr, python3, and PyYAML), creates the python virtual environment (`.venv`), installs dependencies, copies `.env.example` as `.env`, and initializes the `.agents/` scaffolding. +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. --- diff --git a/deploy/README.md b/deploy/README.md index 1409b43..60f47fc 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -6,7 +6,7 @@ This directory contains packaging templates and installation scripts to deploy t ## 📁 Deployment Directory Structure -* **`install.sh`**: A self-contained, idempotent remote shell installer (via curl) that checks system requirements (`herdr`, `python3`), detects NFS/network filesystem mounts, sets up a local python virtual environment (`.venv`), and initializes environment configuration (`.env`). +* **`install.sh`**: A self-contained, idempotent remote shell installer (via curl) that checks system requirements (`herdr`, `python3`), detects NFS/network filesystem mounts, sets up a local python virtual environment (`.venv`), and initializes environment configuration (`.mam.env`). * **`install_mam.sh`**: A local-clone installer that copies rules/skills (`.agents/`), `AGENTS.md`, and sets up environment bootstrap on target projects. * **`generate-env.sh`**: Environment configuration bootstrap helper. * **`INSTALL.md`**: Detailed installation and quick-start user manual.