release(v4.6.0): bump framework and eight skills to 4.6.0 in lockstep; archive PR #22 merge-side reviews
Issue #21 phase-1 prerequisites (PR #22) add loop runner options and the
control-plane module: MINOR. VERSIONS.md gains the v4.6.0 entry, the
archived design reviews lose their markdown trailing whitespace so
`git diff --check` is clean, and the three merge-side PASS reports
(claude, agy, codex @ 4a81d15) are archived under .agents/reports/.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
This commit is contained in:
1 parent
4a81d15d95
commit
d34b532ccf
21 files changed
+426
-38
No files matched your search
@@ -0,0 +1,191 @@
|
||||
# 🔍 PR Review — Job 2b62056b (PR #22 `feat/issue-21-worktree-prereqs` @ `4a81d15`, base `main` `5611859`)
|
||||
|
||||
- **Reviewer**: `planner-reviewer-claude-01` (role: planner,reviewer) · 2026-09-14
|
||||
- **대상**:
|
||||
- 워크트리 `multi-agent-mux-wt/pr-22`(detached `4a81d15`)
|
||||
- `git log 5611859..HEAD` 9커밋, `git diff 5611859...HEAD` 19파일 +1905/−78
|
||||
- 설계 커밋 `fe96db1`·`dcf2fab` 과 구현·교정 커밋 7개(`d3d3a76` → `4a81d15`)
|
||||
- **방법**:
|
||||
- 워크트리 diff 를 정독하고 이슈 #21·PR 본문과 대조했다.
|
||||
- 임시 디렉터리에서 실험 1건을 했다(공백 경로 명령 실행).
|
||||
- 워크트리에서 **전체 스위트**를 읽기 전용 조건(`PYTHONDONTWRITEBYTECODE=1 -p no:cacheprovider`)으로 실행했다. 실패는 base(본 체크아웃 `5611859`)에서 같은 시험으로 대조했다.
|
||||
- 코드는 수정하지 않았다.
|
||||
- **안전 규칙 준수**:
|
||||
- 본 체크아웃은 `main` `5611859` 를 유지했다(checkout·switch·merge 없음). 워크트리의 추적 파일은 바꾸지 않았다(HEAD·`git status` 전후 동일). 다만 스위트 실행 중 일부 시험이 무시 대상 `.mam/`(`delegate_job_logs`·`shim`)을 워크트리에 만들었다. 기존 #20 위생 문제이며 §7 에 적었다.
|
||||
- 실제 `.mam`·monitor 데몬·에이전트 세션은 조작하지 않았다. push·merge·이슈/PR 상태 변경도 없었다.
|
||||
|
||||
## 0. 요약
|
||||
|
||||
| # | 항목 | 판정 |
|
||||
|---|---|---|
|
||||
| (1) | 래퍼 절대경로화 | ✅ 공백 경로·다른 cwd 에서도 동작한다(실험 E1) |
|
||||
| (2) | 루프 러너 `--worktree`/`--base`/`--review-only` | ✅ 소스 루트와 제어 루트가 정확히 나뉜다. 빈 변경분 가드는 diff 수집과 같은 정의라 문서만 바뀐 경우를 오탐하지 않는다 |
|
||||
| (3) | `control_plane.py` 와 create/resume/stop/status/reconcile | ✅ 바인딩 없는 기존 행과 기본 워크스페이스는 동작이 바뀌지 않는다(하위 호환) |
|
||||
| (4) | `lib.sh`·shim 계약 시험 | ✅ `_sks_*`·`send_keys_safe` 를 건드리지 않았다. h25 는 오히려 강화되었다 |
|
||||
| (5) | 설계 문서 정정 | ✅ codex NOT PASS 사유 4가지를 반영했다. 비차단 보강 1건 |
|
||||
| (6) | 신규 시험 결정성·격리 | ✅ tmp/sandbox 만 쓰고 브로커가 필요 없다. 위생 비차단 1건 |
|
||||
| (7) | 스위트 결과로 회귀 확인 | ✅(비차단) 937 passed / 4 failed. 4건 모두 기존 T-1 시간 임계(공개 브로커) 시험이고, base 에서도 같은 부류가 실패한다. PR 회귀 없음 |
|
||||
| (8) | #21 항목 완료·범위 | ✅ 1·2·3·6 완료, 4·5·7·8 은 타당하게 제외됐다. 후속 권고 2건 추가 |
|
||||
| (9) | 알려진 미비 (a)(b) 외 차단 결함 | 없음. (a)(b)는 확인했다(§9). 나머지는 비차단 권고뿐이다 |
|
||||
|
||||
## 1. (1) 래퍼 절대경로화 (`d3d3a76`)
|
||||
|
||||
- **레지스트리**:
|
||||
- `REGISTRY_DIR_DEFAULT="${MAM_JOBS_DIR:-.mam/jobs}"` 로 이제 `MAM_JOBS_DIR` 을 존중한다.
|
||||
- `cmd_submit` 은 `cd "$WORKDIR"` 직후 `_abs_registry_dir` 로 `cd -P … && pwd -P` 절대화하고 `SKS_REGISTRY_DIR` 로 export 한다. 상대 레지스트리는 종전처럼 `WORKDIR` 기준이다.
|
||||
- **명령 문자열**: `_pub_cmd` 가 모든 토큰을 `printf %q` 로 인용한다.
|
||||
- 감사 로그 루트는 구독자와 같은 해석기(`get_logs_dir`)의 절대경로를 `DELEGATE_JOB_LOGS_DIR=%q` 접두로 고정한다.
|
||||
- `_instructions` 는 `%s` 자리표시자만 쓰므로 경로의 `%` 로 인한 포맷 주입이 없다.
|
||||
- **경로 목록**:
|
||||
- 브리프 경로: `$REGISTRY_DIR/$JOB_ID/brief.md`
|
||||
- Output Report Path(direct·loop 두 곳)
|
||||
- 상대 `PY` 를 `cd` 전에 절대화
|
||||
- create 의 onboarding 발행 명령(`create_session.sh` delegate 블록)
|
||||
- **실험 E1** — 레지스트리 `…/reg a b/jobs`, 감사 로그 `…/logs dir`, 모두 공백 포함. 주입된 명령을 **다른 cwd** 에서 그대로 `eval` 했다(브로커는 닫힌 포트).
|
||||
|
||||
| 확인 | 결과 |
|
||||
|---|---|
|
||||
| 시작 명령 | `DELEGATE_JOB_LOGS_DIR=…/logs\ dir …/python …/publish_event.py --registry-dir …/reg\ a\ b/jobs --job … --event started --heartbeat 30` |
|
||||
| 시작·성공 명령 rc | 2, 2(브로커 불가, 로컬 기록 뒤) |
|
||||
| 공백 레지스트리의 events | `['started', 'completed']`, 레코드 `completed` |
|
||||
| 감사 로그 루트 | 지정한 `logs dir` 아래에 job 디렉터리 |
|
||||
| 다른 cwd 에 `.mam` 생성 | 0 |
|
||||
| heartbeat 타이머 잔여 | 0(터미널 발행이 멈춤) |
|
||||
|
||||
- 기존 주입 문구 계약: `test_t1_4` 가 소스에서 `.mam/jobs/$JOB_ID` 리터럴을 금지한다. issue14·issue6·issue18 시험 결과는 §7.
|
||||
- 남는 제한: 작은따옴표가 든 경로는 지원하지 않는다(주입 문구가 명령을 `'…'` 로 감싸는 prose 형식). 문서 §7 에 적혀 있다.
|
||||
|
||||
## 2. (2) 루프 러너 (`d907359`)
|
||||
|
||||
- **의미와 상호작용**:
|
||||
- `--worktree` 는 소스 루트다. 경로가 디렉터리이고, `--show-toplevel` 이 자기 자신이며, `git-common-dir` 가 제어 루트와 같아야 한다(`runner.py` `_validate_worktree`).
|
||||
- `--base` 는 소스 HEAD 의 조상인 커밋이어야 한다(`_resolve_base`). env 폴백은 없다(D17).
|
||||
- `--review-only` 는 `--base` 가 필수이고 `--plan` 과 배타다.
|
||||
- `MAM_LOOP_WORKTREE` env 는 CLI 가 우선이다.
|
||||
- **루트 분리**:
|
||||
- **소스 루트 기준**: diff(제어 루트의 `diff_collect.sh` 를 소스 cwd 에서 실행 — 워크트리의 미검토 수집기는 실행하지 않음), `base_commit`(`--base` 또는 Phase 2 시작 시 소스 HEAD), head, 변경분 가드.
|
||||
- **제어 루트 기준**: wrapper 경로, 래퍼에 넘기는 `--registry-dir self.jobs_dir`, `wait_for_job`·`find_report`·cleanup 의 `jobs_dir`, 체크포인트(`worktree_root`·`head_commit` 필드 추가), loop guard, 리포트 승격.
|
||||
- `jobs_dir` 는 `MAM_JOBS_DIR` 을 존중한다. 상대값은 제어 루트 기준이며, 래퍼 해석과 같다(`t2_15`).
|
||||
- **빈 변경분 fail-closed**:
|
||||
- `git diff --quiet <base>`(추적 파일의 작업 트리 대 base)와 `ls-files -o --exclude-standard`(미추적)로 판정한다. 이는 `diff_collect.sh` 가 수집하는 내용(`git diff "$base"` + 미추적 파일, `:40-48`, `:73-74`)과 같은 정의다.
|
||||
- 따라서 **문서만 바뀐 리뷰 전용 흐름도 `present`** 로 판정된다. 오탐이 없다.
|
||||
- `empty` 는 base 대비 추적 변경과 미추적 파일이 모두 없을 때뿐이다. 무시 파일만 바뀐 경우는 리뷰할 것이 없으므로 거부가 맞다.
|
||||
- git 오류는 `unknown` 이 되어 역시 거부된다. 가드는 `--worktree`/`--base` 가 있을 때만, 리뷰 반복마다 동작한다.
|
||||
- **`run_loop.sh`**:
|
||||
- 새 인자는 기존 `MAM_LOOP_ARGV` 로 Python 러너에 그대로 전달된다. freeze 재실행도 원래 argv 를 넘긴다.
|
||||
- 레거시 `MAM_LOOP_PY=0` 은 새 옵션(과 `MAM_LOOP_WORKTREE`)을 freeze·loop lock **이전에** exit 1 로 거부한다(`t2_8`, `mam_sandbox` 에서).
|
||||
- 참고: 가드는 "작업 트리 대 base" 이고, 브리프의 `[워크트리 컨텍스트]` 는 커밋 수와 미커밋 변경 유무를 함께 보여 준다. 따라서 커밋 0개·미커밋 변경만 있는 상태도 리뷰어에게 드러난다.
|
||||
|
||||
## 3. (3) `control_plane.py` 와 전파 경로 (`ee1d896`·`af8a54c`·`13259ed`)
|
||||
|
||||
- **스키마**: 행 필드 `control_plane = {workspace_root, agent_sessions_yaml, mam_jobs_dir, delegate_job_logs_dir}`, 모두 realpath 다.
|
||||
- **해석 순서**: `describe()` 는 행 바인딩(완전할 때)을 호출자 env 보다 우선하고, 다르면 stderr 로 경고한다. `forward` 는 `--workspace` 의 기본 바인딩과 다를 때만 참이다.
|
||||
- **전파**:
|
||||
- create·resume 은 `K=V ` 접두를 `CMD_FULL` 앞에 붙인다. `lib.sh` new-session 이 이것을 `--env` 로 바꾸는 기존 경로를 쓴다.
|
||||
- `13259ed`/`af8a54c`: env 플래그가 있으면 **idle pane 을 재사용하지 않고** `pane split`/`workspace create` 호출에 `--env` 를 싣는다(`lib.sh` 775-787 부근).
|
||||
- 재사용 pane 에 `env K=V` 를 `agent start --` 뒤 에이전트 인자로 넘기던 종전 결함(R1)이 없어졌다.
|
||||
- 공백이 든 바인딩을 전파해야 하면 rc 3 → create·resume 이 exit 2 로 거부한다(`lib.sh` 가 `--env` 플래그를 인용 없이 나누므로).
|
||||
- **resume**: 행 바인딩을 다시 전파한다. 바인딩 없는 기존 행은 이번 resume 의 바인딩으로 채운다(`update_yaml_resumed.sh`).
|
||||
- **stop**: env 가 없을 때만 행의 `mam_jobs_dir`·`delegate_job_logs_dir` 를 export 한다. 취소 발행과 감사 로그가 행의 제어 평면으로 간다(R3).
|
||||
- **status·reconcile**:
|
||||
- `MAM_JOBS_DIR`·행 바인딩·감사 로그를 먼저 보고, 그 뒤 종전 후보를 그대로 본다.
|
||||
- reconcile 구독 루프는 `MAM_JOBS_DIR` 을 우선한다(`reconcile.sh:239-245`). 이 부분의 시험은 소스 정적 가드뿐이다(`t3_7`).
|
||||
- **하위 호환**:
|
||||
- `--workspace` 가 제어 루트와 같은 일반 세션은 바인딩이 기본값과 같다. 그래서 기록만 되고 전파되지 않으며(`t3_2`), pane 생성 경로(idle pane 재사용 포함)가 종전과 같다.
|
||||
- 바인딩 없는 기존 행은 status·stop·reconcile 에서 종전 후보 순서로 처리된다.
|
||||
- 비차단: `mam_control_plane_json … 2>/dev/null || true`(create)가 실패를 삼키면 바인딩 없이 종전 동작으로 조용히 떨어진다. PR 후속 1·2 와 같다.
|
||||
|
||||
## 4. (4) `lib.sh`·shim 계약 시험
|
||||
|
||||
- **`lib.sh` 변경은 두 곳뿐이다**:
|
||||
- new-session 의 idle pane 재사용 조건에 `&& [ -z "$env_flags" ]` 를 추가하고, 재사용 pane 에 `env …` 를 붙이던 코드를 제거했다.
|
||||
- 파일 끝에 얇은 진입점 `mam_control_plane_json`·`mam_control_plane_prefix` 를 추가했다.
|
||||
- `_sks_*`·`send_keys_safe` 를 포함한 다른 hunk 는 없다.
|
||||
- **h25 는 약화가 아니라 강화다**:
|
||||
- 종전 h25 는 결함 있는 동작(idle pane 재사용 + 에이전트 인자로 env)을 고정하고 있었다.
|
||||
- 새 h25 는 env 가 **생성 호출의 `--env`** 에 있고 `agent start --` 인자에는 없음을 단정한다.
|
||||
- env 없는 재사용은 h24 가 그대로 고정한다.
|
||||
|
||||
## 5. (5) 설계 문서 정정 (`b61c8b1`)
|
||||
|
||||
- **codex NOT PASS 사유별 반영**:
|
||||
- 부분 지원: §3 제목이 "현재 코드 기준" 에서 "부분 지원 + 1단계 수정 반영" 으로 바뀌었다.
|
||||
- 루트 3종: §7 이 제어·소스·런타임 코드 루트를 정의한다.
|
||||
- 리뷰 identity: §2-C 가 항목 5 로 미뤘다고 명시한다.
|
||||
- 과장 표현: A 의 "완전 격리", 리뷰어 "읽기 전용", 잡 토픽과 지문을 정정했다(§1 표).
|
||||
- **추가된 내용**:
|
||||
- 스킬별 호환성 표(§7)
|
||||
- 1단계 운영 형태(구현은 루프 밖, 리뷰는 `--review-only` 로 하나씩)
|
||||
- 두 번째 루프는 **거부**된다는 서술
|
||||
- "실제 herdr `--env` 전파는 mock 수준까지만 검증" 이라는 정직한 단서
|
||||
- 비차단 보강: §3 의 create 레시피에 `MAM_NO_SUBSCRIBER_DAEMON=1` 을 넣을 것.
|
||||
- `create_session.sh:567` 의 `start_watchdog "$DELEGATE_JOB_ID" "$WORKSPACE"` 는 여전히 워크트리의 `reconcile.sh` 로 데몬을 띄울 수 있다(항목 4 에서 기본화 예정).
|
||||
- "모니터는 본 체크아웃에서만"(§3 본문)을 지키려면, 항목 4 가 오기 전까지는 레시피 한 줄로 막는 편이 안전하다.
|
||||
|
||||
## 6. (6) 신규 시험 780줄의 결정성·격리
|
||||
|
||||
- 파일 머리의 규칙대로 모든 쓰기가 `tmp_path`·`mam_sandbox` 아래에서 일어난다.
|
||||
- `wt_repo` 픽스처는 `monkeypatch.setenv` 로 `WORKSPACE_ROOT`·`MAM_JOBS_DIR` 을 임시 루트에 묶는다.
|
||||
- 래퍼 시험은 브로커를 `127.0.0.1:9`(`UNREACHABLE`)로 두어 **브로커가 필요 없다**.
|
||||
- 비차단 위생: `t2_6` 이 `monkeypatch` 대신 `os.environ` 을 직접 바꾼다. `try/finally` 로 복구하므로 새지는 않는다(PR 후속 3).
|
||||
- `t3_7` 은 reconcile 의 `MAM_JOBS_DIR` 우선을 소스 문자열로만 고정한다(브로커가 필요한 경로라서다). 약하지만 명시되어 있다.
|
||||
- 격리 실측(실제 `.mam/jobs`, 데몬, 워크트리 상태)은 §7.
|
||||
|
||||
## 7. (7) 테스트 실행 결과
|
||||
|
||||
| 실행 | 결과 |
|
||||
|---|---|
|
||||
| **전체 스위트** @ `4a81d15`(워크트리, 11:52–12:27Z, 오케스트레이터·다른 리뷰어 스위트와 동시) | **937 passed, 4 failed in 2103 s**. HEAD 전후 동일(`4a81d15`) |
|
||||
| 실패 4건 | pane-busy `test_issue14…::…ignores_pane_busy_token`(rc 0: 늦은 completed 가 수락됨), 벽시계 `…never_outlives_the_wall_clock`(closed after **28.12 s** > 28), AC1(rc 2), AC5(rc 2) |
|
||||
| 4건 단독 재실행 — PR `4a81d15` | 3 failed / 1 passed(AC1 통과). 이때 공개 브로커가 `no CONNACK from broker` 로 재시도하고 있었다 |
|
||||
| 4건 단독 재실행 — base `5611859`(본 체크아웃) | 2 failed / 2 passed(AC1·AC5 실패) |
|
||||
|
||||
- **판단**:
|
||||
- 4건은 #18 리뷰에서 main 계열 코드(`135d76f`·`7e1d3f0`·`ab842f1`)로도 같은 방식으로 여러 번 실패했던 T-1 부류다. 벽시계 28.1 s 는 그때와 같은 값이다.
|
||||
- 같은 브로커 상태에서 base 도 이 부류가 실패한다.
|
||||
- PR 이 래퍼 submit 에 python 호출 1회(`_logs_dir_abs`)를 추가했지만, 측정된 벽시계 값은 main 과 같다.
|
||||
- **PR 이 만든 실패는 0건으로 본다.**
|
||||
- PR 본문의 "33건 환경 실패" 는 이 환경(macOS, venv Python 3.9)에서는 재현되지 않았다. 이 환경의 실패는 위 4건뿐이다.
|
||||
- **격리**:
|
||||
- 본 체크아웃은 `main` `5611859` 클린을 유지했다. 실제 `.mam/jobs` 추가는 0 이다.
|
||||
- 워크트리의 추적 파일은 변하지 않았다(`?? .venv` 만).
|
||||
- **그러나 무시 대상 `.mam/` 이 워크트리에 생겼다**: `.mam/delegate_job_logs`(잡 21개)와 `.mam/shim`. 생성 시각이 20:52–21:13 KST 로 이 스위트 실행 중이다.
|
||||
- 일부 시험이 `$REPO_ROOT/.mam` 에 쓴다(#20 위생 문제). PR 후속 4 가 지목한 `test_issue14…::_job_for_inprocess_publish` 의 감사 로그와, 샌드박스 없이 `lib.sh` 를 소싱할 때 생기는 shim 이다.
|
||||
- PR 이 새로 만든 문제는 아니지만, 워크트리 병렬 운영에서는 워크트리마다 쌓인다.
|
||||
- 읽기 전용 규칙에 따라 지우지 않았다. 오케스트레이터가 정리할 것을 권한다.
|
||||
- 샌드박스 heartbeat 타이머: 실행 직후 집계에서 pytest 경로 타이머 3개가 보였으나, 재확인했을 때는 0개였다(동시에 돌던 다른 스위트의 것으로 보인다).
|
||||
- 모니터 데몬 전후 비교는 스냅샷 필터 오류로 판정하지 못했다.
|
||||
|
||||
## 8. (8) #21 작업 항목과 후속
|
||||
|
||||
- **완료**: 항목 1(래퍼 경로), 2(러너 옵션·가드), 3(바인딩 영속·전파, status/reconcile/stop/loop 의 `MAM_JOBS_DIR`), 6(문서 정정). 각각 시험으로 고정되어 있다.
|
||||
- **제외의 타당성**: 4(준비·해체 헬퍼, 데몬 기본화), 5(리뷰 identity·검증 격리), 7(실제 herdr 수용 사례), 8(다중 루프). 모두 설계 결정이나 실환경이 필요한 별도 작업이다. 1단계 운영(구현은 루프 밖, 리뷰 루프 하나)에 필요한 최소 변경만 이 PR 에 들어갔다는 판단에 동의한다.
|
||||
- **후속 권고 5건은 적절하다**. 추가로 두 가지를 권한다.
|
||||
- 6) 항목 4 전까지 §3 레시피에 `MAM_NO_SUBSCRIBER_DAEMON=1`(§5).
|
||||
- 7) 첫 실제 워크트리 creator 전에 항목 7 의 "실제 herdr `--env` 전파" 수용 사례를 먼저 확인한다(현재는 mock 검증뿐). 전파가 안 되더라도 주입 명령이 절대경로라 잡 발행은 동작하지만, creator 가 스스로 부르는 스킬은 워크트리 `.mam` 을 쓰게 된다.
|
||||
|
||||
## 9. (9) 병합을 막을 결함
|
||||
|
||||
- **알려진 미비**:
|
||||
- (a) 버전 bump 가 없다(4.5.0 유지). 새 CLI 옵션과 새 모듈이므로 4.6.0(MINOR)과 VERSIONS 항목이 필요하다.
|
||||
- (b) `docs/design/reviews/review-agy-fd384d6b.md` 의 markdown 줄바꿈용 trailing whitespace 로 `git diff --check` 가 실패한다.
|
||||
- 둘 다 확인했다. 코드 파일에는 whitespace 문제가 없다.
|
||||
- **그 밖에 병합을 막을 결함은 찾지 못했다**.
|
||||
- 비차단:
|
||||
- create 의 바인딩 해석 실패 삼킴(§3, PR 후속 1)
|
||||
- §3 레시피의 `MAM_NO_SUBSCRIBER_DAEMON=1`(§5)
|
||||
- `t2_6` 의 `os.environ` 직접 조작(§6)
|
||||
- 시험의 `$REPO_ROOT/.mam` 쓰기(§7, #20)
|
||||
- T-1 시간 임계 시험
|
||||
|
||||
## 10. 종합
|
||||
|
||||
- PR #22 는 #21 항목 1·2·3·6 을 정확히 구현했다.
|
||||
- 래퍼 경로는 공백 경로와 다른 cwd 에서도 절대·인용이 맞다(실험).
|
||||
- 러너는 소스 루트와 제어 루트를 분리하고 diff 수집과 같은 정의의 fail-closed 가드를 둔다.
|
||||
- 제어 평면 바인딩을 영속·전파하면서도 기존 워크스페이스와 바인딩 없는 행의 동작을 바꾸지 않는다.
|
||||
- `lib.sh` 변경은 idle pane 재사용 조건에 한정되며 계약 시험은 강화되었다.
|
||||
- 전체 스위트의 실패 4건은 base 에서도 같은 부류로 실패하는 기존 브로커 시간 임계 시험이다.
|
||||
- 병합 전에 알려진 미비 (a)(b)를 릴리스 커밋으로 처리하면 된다. 설계 재검토는 필요 없다.
|
||||
|
||||
[VERDICT: PASS]
|
||||
@@ -0,0 +1,51 @@
|
||||
# PR #22 independent review
|
||||
|
||||
Reviewer: planner-reviewer-codex-01. Job: fa5cfb00.
|
||||
Reviewed detached worktree `multi-agent-mux-wt/pr-22` at `4a81d15d95632d54c47b15297549ab28c41006f3`, against main `5611859`; reviewed the nine commits and aggregate diff.
|
||||
|
||||
PASS for the scoped implementation of #21 items 1, 2, 3, and 6. I found no additional merge-blocking implementation defect. This is not approval to merge the current tree without the two release corrections already identified in the brief:
|
||||
|
||||
- Add the 4.6.0 MINOR lockstep version changes and VERSIONS.md release entry. Passing version-consistency tests on the current 4.5.0 tree does not satisfy this release requirement.
|
||||
- Remove trailing whitespace in `docs/design/reviews/review-agy-fd384d6b.md` (lines 3–8, 36, 38, 104, 106, 108, 115, 117). `git diff --check 5611859...HEAD` currently fails on those known lines.
|
||||
|
||||
## Review findings
|
||||
|
||||
1. **Delegation paths and quoting:** The wrapper resolves the registry after entering the requested workdir, then supplies absolute brief/report paths and explicit registry and audit-log locations in injected lifecycle commands. The CLI registry override retains priority over MAM_JOBS_DIR. Executable paths containing a slash are made absolute before changing cwd. Bash quoting and execution from another cwd are exercised by the new tests, including spaces. Single-quote-containing paths remain an explicitly documented limitation.
|
||||
|
||||
2. **Loop roots and flags:** The runtime code and control plane remain in the control checkout; diff collection, base/head and creator context use the selected source worktree. Worktree validation checks the repository common directory. An explicit base must resolve to a commit and be an ancestor of source HEAD. Review-only requires a base and skips initial implementation, while later correction/compliance rounds may still dispatch a creator. That behavior is now documented. The empty-change guard accepts documentation changes and fails closed on unknown git state; it includes untracked files, so an unignored preparation symlink such as `.venv` can make an otherwise empty set nonempty. The design explicitly requires excluding that preparation artifact. The legacy shell runtime rejects unsupported options/environment configuration rather than silently ignoring them.
|
||||
|
||||
3. **Control-plane bindings:** The new resolver normalizes the four binding fields and persists them on creation. Resume prefers a complete saved binding, warns when the caller differs, and populates legacy rows without a binding. Stop retains both registry and audit-log routing; status checks the new locations alongside legacy candidates. Relative MAM_JOBS_DIR handling is covered. Reconcile's environment precedence has a static regression guard, not full runtime integration coverage. Forwarding paths containing whitespace is explicitly rejected; the legacy external wrapper path warns that propagation is unavailable. These are stated compatibility limits rather than hidden claims of complete support.
|
||||
|
||||
4. **Herdr shim:** With environment flags present, session creation bypasses idle-pane reuse and forwards environment through pane/workspace creation. It does not inject `env K=V` into agent arguments. The no-environment reuse path remains covered. The revised h25 assertions pin both environment forwarding and the absence of inappropriate agent arguments; I did not find a weakened contract. `_sks_*` and `send_keys_safe` implementations are unchanged by this diff.
|
||||
|
||||
5. **Design corrections and scope:** The revised document addresses my previous design objections: partial support, control/source/runtime roots, test-side writes, pending immutable review identity, and logical ownership rather than assumed database corruption. The first phase permits parallel implementation outside the loop and one review loop, with the base captured before implementation. Deferring preparation/recovery helpers (4), immutable review identity and isolated verification (5), real-herdr acceptance (7), and multi-loop scheduling (8) is reasonable for this bounded prerequisite PR. It must not be presented as completed production support for concurrent loops.
|
||||
|
||||
6. **Tests and isolation:** The new worktree tests use temporary repositories or mam_sandbox; the final T2-8 change places shell rejection checks in the sandbox. Static checks and mocked delegation/herdr behavior provide useful bounded coverage but do not establish actual pane environment propagation. The provided `.venv` symlink in the review tree predates this review. No source files, production sessions, monitor configuration, or checkout state were modified by this reviewer.
|
||||
|
||||
## Verification
|
||||
|
||||
Tests ran from the review worktree with `PYTHONDONTWRITEBYTECODE=1`, its supplied `.venv/bin/python`, and pytest's cache provider disabled.
|
||||
|
||||
| Check | Result |
|
||||
|---|---|
|
||||
| `test_issue21_worktree_prereqs.py`, `test_herdr_shim_contract.py`, `test_issue5_phase2a_loop.py`, `test_version_consistency.py` | 146 passed in 136.14 s |
|
||||
| `test_issue18_liveness_contract.py`, `test_issue6_turn_handshake.py` | 43 passed, 2 failed in 250.40 s |
|
||||
| Isolated stock acknowledgement-test rerun | 1 passed in 4.46 s |
|
||||
| Remote acceptance rerun with unique UUID4 session and secret | 1 passed in 32.00 s |
|
||||
| `bash -n` for nine changed shell files | Passed |
|
||||
| `git diff --check 5611859...HEAD` | Known archived-review trailing whitespace only |
|
||||
|
||||
The two initial failures require explicit qualification:
|
||||
|
||||
- `tests/test_issue18_liveness_contract.py:512`, `test_send_keys_safe_is_confirmed_by_the_job_started_event`: the command succeeded, but the elapsed-time assertion measured 13.393 s against an 11 s limit. The test joins the publisher thread before checking elapsed time, so publication latency affects that measurement. The isolated unmodified rerun passed. This test and the relevant acknowledgement implementation are unchanged relative to base; the observed result does not demonstrate a deterministic PR regression.
|
||||
- `tests/test_issue18_liveness_contract.py:1189`, `test_acceptance5_remote_runner_completes_a_job_over_the_broker_only`: the wrapper awaited job `fa85ad57`, but its `--once` runner consumed and completed job `4fd23659`. The stock test uses a fixed `sim-worker` session and shared secret on a wildcard broker subscription, allowing concurrently running suites to collide. I reran the same test with a pytest collection plugin replacing only those session/secret string constants in memory with UUID4 values; all original assertions remained, and it passed. No repository test file was edited. This supports a shared-broker test-isolation diagnosis, not a product-code regression. The stock acceptance test should gain unique identifiers in follow-up work.
|
||||
|
||||
I have not independently verified the PR's claim that all 33 full-suite failures are environmental or match base. These focused results should be combined with the orchestrator's separate full-suite evidence; they must not be generalized into a blanket endorsement of that claim.
|
||||
|
||||
## Follow-up recommendations
|
||||
|
||||
The remaining work is appropriately sequenced as: (1) preparation/teardown and original-cwd recovery helpers, (2) immutable review identity and isolated test execution, (3) real-herdr environment and lifecycle acceptance, (4) explicit reviewer ownership/queueing before multiple loops, and (5) reproducible operational recipes coordinated with the #17 shell-layer reduction. Keep the documented compatibility restrictions until those acceptance cases exist. Additionally, make the broker acceptance test's session and secret unique to avoid cross-suite interference.
|
||||
|
||||
Final checkout verification: main remains clean; the review tree remains at the requested detached commit with only its preexisting untracked `.venv` symlink. The two known release gates remain the orchestrator's responsibility before merge.
|
||||
|
||||
[VERDICT: PASS]
|
||||
@@ -0,0 +1,130 @@
|
||||
# PR #22 Review Report: Worktree Creator Operating Model Prerequisites (Phase 1)
|
||||
|
||||
- **Reviewer**: Antigravity (`herdr:reviewer-agy-01`)
|
||||
- **Job ID**: `de72b12e`
|
||||
- **Target PR**: [PR #22](https://git.godopu.com/tmpl/multi-agent-mux/pulls/22) (`feat/issue-21-worktree-prereqs` @ `4a81d15`, base `main` `5611859`)
|
||||
- **Target Worktree**: `/Users/godopu16/PuKi/laa/canary_projects/multi-agent-mux-wt/pr-22` (detached @ `4a81d15`)
|
||||
- **Base Repo**: `/Users/godopu16/PuKi/laa/canary_projects/multi-agent-mux` (`main` @ `5611859`, unmodified)
|
||||
- **Status**: Review Complete
|
||||
|
||||
---
|
||||
|
||||
## 1. Executive Summary
|
||||
|
||||
PR #22 implements Phase 1 prerequisites for the Worktree Creator Operating Model (addressing Issue #21 items 1, 2, 3, and 6). This review was conducted independently in worktree `/Users/godopu16/PuKi/laa/canary_projects/multi-agent-mux-wt/pr-22` without modifying any files in either the worktree or the main working copy.
|
||||
|
||||
All 9 checklist verification items have been thoroughly inspected and verified against the codebase and test suites.
|
||||
|
||||
Two known limitations (pre-identified and documented in the brief) were verified:
|
||||
1. **Version Lockstep**: Currently at 4.5.0. New CLI flags (`--worktree`, `--base`, `--review-only`) and new module `lib_py/control_plane.py` require a MINOR bump to 4.6.0 and an entry in `VERSIONS.md`. This is scheduled to be performed by the orchestrator in the merge release commit.
|
||||
2. **Markdown Trailing Whitespace**: `git diff 5611859...HEAD --check` flags trailing whitespace on lines in `docs/design/reviews/review-agy-fd384d6b.md` used for markdown line breaks (` \n`). No source code (`.py`, `.sh`) contains trailing whitespace or syntax issues. This is also scheduled for cleanup in the orchestrator release commit.
|
||||
|
||||
Beyond these two orchestrator release tasks, PR #22 is clean, robust, backwards-compatible, and passes all prerequisite test suites (100% pass rate on relevant tests).
|
||||
|
||||
---
|
||||
|
||||
## 2. Checklist Item-by-Item Verification
|
||||
|
||||
### (1) Wrapper Absolute Paths (`d3d3a76`)
|
||||
- **Path Resolution**: In `multi-agent-mux-delegate-job`, the brief file path, the `--registry-dir` argument in injected commands (`start`, `success`, `error`), the `Output Report Path`, and the audit log root (`DELEGATE_JOB_LOGS_DIR`) are strictly resolved to absolute paths rooted at `$REGISTRY_DIR` / canonical root, independent of the Creator's working directory (`$CWD`).
|
||||
- **Shell Quoting**: All path interpolations are enclosed in double quotes (`"$REGISTRY_DIR"`, `"$BRIEF_FILE"`), preventing word splitting on paths with spaces or special characters.
|
||||
- **Contract Alignment**: Conforms with existing prompt injection contracts:
|
||||
- Issue 14 (Delivery ACK): Start command with `--event started` and token verification remains intact.
|
||||
- Issue 6 (Turn Handshake): Handshake status sequence and wrapper idle checks remain compatible.
|
||||
- Issue 18 (Liveness Contract): `--heartbeat <N>` argument in start command is properly formatted.
|
||||
- **Tests**: `tests/test_issue21_worktree_prereqs.py` tests `test_t1_1_wrapper_emits_absolute_brief_path`, `test_t1_2_wrapper_emits_absolute_start_command_registry_dir`, `test_t1_3_wrapper_emits_absolute_audit_log_path`, `test_t1_4_wrapper_emits_absolute_output_report_path`, and `test_t1_5_wrapper_handles_spaces_in_root_path` all pass.
|
||||
|
||||
### (2) Loop Runner Worktree Integration (`d907359`)
|
||||
- **CLI Flags**: `lib_py/loop/runner.py` introduces `--worktree <path>`, `--base <ref>`, and `--review-only`.
|
||||
- **Worktree vs Control Plane Separation**:
|
||||
- `collect_changes_diff()` and `base_commit` resolution execute with `cwd=str(self.worktree_root)`. The diff passed to peer reviewers reflects changes in the worktree against base.
|
||||
- Control plane artifacts—the delegation wrapper (`multi-agent-mux-delegate-job`), jobs registry (`$MAIN/.mam/jobs`), loop checkpoint file (`$MAIN/.mam/loop-checkpoints/...`), and promoted reports (`$MAIN/.mam/reviews/...`)—remain strictly anchored to the main repository root.
|
||||
- **Fail-Closed Empty Change-Set Guard**:
|
||||
- `collect_changes_diff()` raises a fail-closed error if the diff between base and worktree is completely empty, preventing reviewers from hallucinating reviews over non-existent changes.
|
||||
- Documents-only changes produce non-empty diffs and correctly pass through to review.
|
||||
- **`run_loop.sh` & Freeze Mode**:
|
||||
- `run_loop.sh` passes `--worktree`, `--base`, and `--review-only` directly to `lib_py.loop.runner`.
|
||||
- The legacy bash loop path (`MAM_LOOP_PY=0`) explicitly rejects `--worktree` with an informative error message directing users to the Python runner, preventing silent misconfiguration.
|
||||
- **Tests**: Tests `test_t2_1` through `test_t2_14` in `test_issue21_worktree_prereqs.py` verify all flag combinations, diff scoping, empty diff fail-closed behavior, and review promotion.
|
||||
|
||||
### (3) Control Plane Binding & Persistence (`ee1d896`, `af8a54c`, `13259ed`)
|
||||
- **Binding Schema**: `lib_py/control_plane.py` defines clean dataclass and serialization helpers for control plane bindings:
|
||||
- `control_workspace_root`
|
||||
- `control_agent_sessions_yaml`
|
||||
- `control_mam_jobs_dir`
|
||||
- `control_delegate_job_logs_dir`
|
||||
- **Persistence & Forwarding**:
|
||||
- `create_session.sh`, `resume_session.sh`, and `stop_session.sh` propagate and persist binding fields into `agent-sessions.yaml`.
|
||||
- `status` and `reconcile` commands respect `MAM_JOBS_DIR` without corrupting state.
|
||||
- **Reused Pane vs New Pane Contract (h25 & af8a54c)**:
|
||||
- Reused panes do not receive environment variables as CLI arguments (`af8a54c`), avoiding argument pollution.
|
||||
- Per `13259ed` (h25 contract update): when env flags are present during `new-session`, the idle pane wait is skipped and environment variables are passed directly to the pane creation call.
|
||||
- **Relative `MAM_JOBS_DIR`**: Relative paths are normalized against `control_workspace_root`.
|
||||
- **Backwards Compatibility**: Rows in `agent-sessions.yaml` without binding fields fall back cleanly to default paths relative to the current workspace root.
|
||||
- **Tests**: Tests `test_t3_1` through `test_t3_13` in `test_issue21_worktree_prereqs.py` pass without regression.
|
||||
|
||||
### (4) `lib.sh` & Herdr Shim Contract (`4a81d15`, `13259ed`)
|
||||
- **Scope of Changes**: Changes in `lib.sh` (29 lines) are narrowly focused on the `new-session` path to forward environment flags to `herdr split-window` / `new-session`.
|
||||
- **Side Effects**: Critical primitives `_sks_*` and `send_keys_safe` are completely untouched.
|
||||
- **Contract Integrity**: `tests/test_herdr_shim_contract.py` (17 tests) passed 100% in 21.51s, including `test_h25_new_session_with_env_flags_skips_the_idle_pane_and_uses_env_on_split`. The contract is maintained and strengthened, not weakened.
|
||||
|
||||
### (5) Design Document Corrections (`b61c8b1`)
|
||||
- **Review Feedback Incorporation**: `docs/design/worktree-creator-model.md` was updated in commit `b61c8b1` to address all points raised in prior review rounds:
|
||||
- Replaced overgeneralized claims with explicit Phase 1 boundaries (review-only worktree workflow).
|
||||
- Formalized the 3 distinct filesystem roots: (1) Control Workspace Root, (2) Target Workspace Root, and (3) Worktree Root.
|
||||
- Explicitly defined reviewer session identity preserving `herdr` pane mappings.
|
||||
- Added compatibility table between control plane modes and agent roles.
|
||||
|
||||
### (6) New Test Suite Quality & Hermeticity (`test_issue21_worktree_prereqs.py`)
|
||||
- **Size & Coverage**: 780 lines, 35 unit and integration tests covering wrapper paths, runner worktree flags, control plane bindings, and freeze-mode guards.
|
||||
- **Hermetic Isolation**:
|
||||
- Uses `mam_sandbox` fixtures and `tmp_path`.
|
||||
- Never writes to the actual `.mam` directory or real session registries.
|
||||
- UUIDs generated via `uuid.uuid4()`.
|
||||
- Zero external MQTT broker dependency (no network flakiness).
|
||||
- **Execution**: 35 passed in 145.14s on the target worktree.
|
||||
|
||||
### (7) Regression & Test Suite Verification
|
||||
Targeted test execution in worktree `/Users/godopu16/PuKi/laa/canary_projects/multi-agent-mux-wt/pr-22`:
|
||||
| Test Suite | Result | Time |
|
||||
| :--- | :---: | :---: |
|
||||
| `tests/test_issue21_worktree_prereqs.py` | **35 / 35 PASS** | 145.14s |
|
||||
| `tests/test_herdr_shim_contract.py` | **17 / 17 PASS** | 21.51s |
|
||||
| `tests/test_issue5_phase2a_loop.py` | **91 / 91 PASS** | 2.75s |
|
||||
| `tests/test_version_consistency.py` | **3 / 3 PASS** | 0.87s |
|
||||
| `tests/test_issue6_turn_handshake.py` | **14 / 14 PASS** | 56.44s |
|
||||
|
||||
- **Verification of Author's "33 Failures" Claim**:
|
||||
- Investigated test failures in suites outside PR #22's diff (e.g. `test_issue18_liveness_contract.py::test_acceptance5` and `test_issue14_delivery_ack.py::test_wrapper_idle_grace_never_outlives_the_wall_clock`).
|
||||
- Analysis confirmed:
|
||||
- `test_acceptance5` failure was caused by collisions on the public shared MQTT broker (`python/mqtt/jobs/+/dispatch`) receiving dispatches from concurrent runs on other machines (`pu-macbook-pro.local`).
|
||||
- `test_issue14` timing test failure was a 56ms jitter (28.05s vs 28.00s threshold) under multi-process CPU contention with `slow-python sleep 0.7`.
|
||||
- Neither test was modified in PR #22 (zero diff against `5611859`).
|
||||
- All core subsystem and prerequisite tests for PR #22 pass 100%. No regressions introduced.
|
||||
|
||||
### (8) Issue #21 Scope Adherence & Deferrals
|
||||
- **Phase 1 Complete**:
|
||||
- Item 1: Wrapper absolute paths (Complete, verified).
|
||||
- Item 2: Loop runner worktree options & diff scoping (Complete, verified).
|
||||
- Item 3: Control plane binding propagation & persistence (Complete, verified).
|
||||
- Item 6: Dedicated test suite (Complete, verified).
|
||||
- **Properly Deferred to Phase 2**:
|
||||
- Item 4: Multi-loop worktree contention and queuing.
|
||||
- Item 5: Reviewer test artifact isolation / sandbox.
|
||||
- Item 7: Worktree deletion and cleanup safety script.
|
||||
- Item 8: Autonomous end-to-end worktree creator lifecycle.
|
||||
- **Follow-up Recommendations**: The 5 follow-up recommendations (Phase 2 worktree lifecycle script, isolated scratch spaces for reviewer test runs, worktree removal safety validation, loop lock file, telemetry) are appropriate and correctly planned for subsequent PRs.
|
||||
|
||||
### (9) Merge Readiness Assessment
|
||||
- **Blocker Scan**: No unhandled edge cases, no security vulnerabilities, no broken imports, no regressions.
|
||||
- **Known Limitations Acknowledged**:
|
||||
1. Version bump to 4.6.0 + `VERSIONS.md` entry (orchestrator release commit).
|
||||
2. Trailing markdown whitespace in review notes (orchestrator release commit).
|
||||
|
||||
---
|
||||
|
||||
## 3. Final Conclusion
|
||||
|
||||
PR #22 successfully delivers the Phase 1 prerequisites for the Worktree Creator Operating Model with high code quality, robust test isolation, and strict backwards compatibility.
|
||||
|
||||
[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.5.0"
|
||||
MAM_VERSION="4.6.0"
|
||||
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.5.0"
|
||||
FRAMEWORK_VERSION = "4.6.0"
|
||||
|
||||
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.5.0
|
||||
version: 4.6.0
|
||||
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.5.0
|
||||
version: 4.6.0
|
||||
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.5.0
|
||||
version: 4.6.0
|
||||
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.5.0
|
||||
version: 4.6.0
|
||||
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.5.0
|
||||
version: 4.6.0
|
||||
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.5.0
|
||||
version: 4.6.0
|
||||
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.5.0
|
||||
version: 4.6.0
|
||||
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.5.0
|
||||
version: 4.6.0
|
||||
author: godopu
|
||||
license: MIT
|
||||
platforms: [linux, macos]
|
||||
|
||||
Reference in new issue
Block a user