Repository navigation
Releases: sshworld/sshworld-best-practice
Release list
v 1.17.2 — marketplace 에서 caveman 제거
v1.17.2 — marketplace 에서 caveman 제거
♻️ Refactor / Chore
- marketplace 의
cavemanopt-in 항목과allowCrossMarketplaceDependenciesOn을 제거. 압축 문체는 서비스 A-Z 작업에서 표현력을 깎아 실익이 없었다. 필요하면 원 저장소(JuliusBrussee/caveman)에서 직접 설치 - known-issues #16(용도 불명 cross-marketplace 설정) 해결 표기
📝 Docs
- README·infra-setup 토큰 절약 레이어 표에서 출력 압축 행 제거
업데이트: /plugin update sshworld
v 1.17.1 — 자식 dispatch MCP 상속 기본 복귀
v1.17.1 — 자식 dispatch MCP 상속 기본 복귀
🐛 Fix
- 자식 dispatch 가 부모 MCP 를 다시 상속한다. v1.17.0 이
--strict-mcp-config를 기본 부착해 사용자 MCP·플러그인 MCP(Figma 등)가 자식에서 전부 사라졌고, 설계서 대조가 필수인 슬라이스가 도구 없이 「미조회」로 조용히 종결되는 사고가 있었다. 이제 상속이 기본. 절약이 필요하면DISPATCH_STRICT_MCP=1로 spec 단위 opt-in.DISPATCH_INHERIT_MCP=1은 호환용 no-op - 판단 강제 가드 —
DISPATCH_STRICT_MCP=1인데 spec 이mcp__·Figma·Notion·MCP 를 언급하면 dispatch 를 거절한다(exit 2). 정말 끊으려면DISPATCH_STRICT_MCP=force - 실측 정정: strict-mcp 의 절약폭은 기대보다 훨씬 작다(MCP 툴 스키마는 deferred 로딩 — 컨텍스트엔 이름만 실림). 자식 첫 턴 61k 의 주성분은 시스템 프롬프트·내장 툴·스킬 목록·CLAUDE.md.
outputStyle default부착은 유지(자식이 Learning 스타일로 사람 기여를 요청하는 동작 방지)
📝 Docs
commands/plan-dev/cmux-dispatch.mdPhase 2 표 아래 env 단락, README·CLAUDE.md 환경변수 동기
업데이트: /plugin update sshworld
v 1.17.0 — plan-dev 명확화 정형화 · plan 단계 다이어트 · 자식 고정비 절감
v1.17.0 — plan-dev 명확화 정형화 · plan 단계 다이어트 · 자식 고정비 절감
✨ Feature
- 판단 요소 인벤토리 — plan-dev 1-1 을 "정반대 가능할 때만 질문" 에서 차원 전수 점검으로 교체. 11개 차원(데이터 모델·상태 전이·에러 정책·동시성·호환·권한·성능·관측·배포·테스트 오라클·UX 엣지)을
확정/파생/해당없음셋 중 하나로 닫고,미정0 까지 AskUserQuestion 라운드 반복.## Assumptions섹션 폐지 →## 판단 요소표 +## Out of scope(사유·재개 트리거). 차원별 파생 근거·질문 예시는commands/plan-dev/clarification-dimensions.md - 잔여 게이트 hook
enforce-plan-closure.sh(PreToolUse ExitPlanMode) — plan 에미정·미결·결정 필요·TBD·TODO,## Assumptions/## 가정헤딩,- 가정:줄이 남았거나## 판단 요소표가 없으면 승인 요청 차단.## Out of scope안·백틱 인라인 코드·``` / ~~~ 펜스 블록은 면제. 우회CBP_PLAN_CLOSURE_OK=1(1회) / `DISABLE_PLAN_CLOSURE_HOOK=1`(영구). plan 파일 리졸버 `scripts/cbp-plan-path.sh`(marker `plan_file` → `~/.claude/plans` 최신) 공유 — `enforce-cmux-dispatch.sh` 도 인자 비면 파일 폴백 - 자식 dispatch 고정비 절감 — 자식 claude 에
--strict-mcp-config+--settings '{"outputStyle":"default"}'기본 부착. 부모의 MCP 툴 스키마(실측 figma 44 + notion 78)와 Learning 출력 스타일을 상속하지 않는다. opt-outDISPATCH_INHERIT_MCP=1,DISPATCH_OUTPUT_STYLE=<name|inherit> plan-dev-session.sh set-plan <abs> --total=N [--design=<abs>]— plan latch·슬라이스 수·상태 pill 을 한 번에. 기존 키(design_doc·start_ts) 보존- plan-dev.md 다이어트 2,309 → 899 단어(200 → 130줄). 순서·호출·계약만 남기고 금지/우회 서술은
antipatterns.md로. 1-0 Explore 는Agent(Explore)1회 위임(부모 직접 Read ≤ 3), 1-3 Plan 리뷰 opt-in, ExitPlanMode 는 인자 없이 호출(plan 재복사 15k chars 낭비 제거)
🐛 Fix
enforce-cmux-dispatch.shdirect-edit 탐지가 산문의| direct-edit |를 표 셀로 오인 — 표 행 시작 앵커DISPATCH_OUTPUT_STYLE값 검증([A-Za-z0-9_-]) — 부적합 값은 경고 후default폴백, JSON 손상 방지
📝 Docs
- README 하네스 가드·환경변수 표, CLAUDE.md 환경변수 줄 동기
업데이트: /plugin update sshworld
v 1.16.2 — 커밋 메시지 개조식 규칙
v1.16.2 — 커밋 메시지 개조식 규칙
📝 Docs
commit-advisor에 개조식·본문 길이 규칙 추가 — 제목은 명사형 종결(~추가,~제거)로 강제하고 서술형 문장(~했다)을 금지한다. 본문은 필요할 때만 불릿 3~5줄까지.- 경위·재발방지·실측 서사는 설계 문서(
## 6. 결과)와 PR 본문이 담당하도록 역할을 명시했다. 커밋 메시지에 같은 내용을 중복시키지 않는다. - 금지 형태(20줄 산문)를 예시로 박아뒀다 — 기존 규칙이 "한 문장" 뿐이라 본문 길이에 제약이 없었고, 실제로 이 저장소의 최근 커밋들이 그 틈으로 길어졌다.
업데이트: /plugin update sshworld
v 1.16.1 — Orca 워크트리 카드 모드 dispatch 복구
v1.16.1 — Orca 워크트리 카드 모드 dispatch 복구
v1.16.0 의 워크트리 카드 모드가 실제 Orca 에서 즉시 죽었다. 단일-repo Orca 워크스페이스에서 --mode=orca dispatch 를 쓰는 경우에만 해당하며, 탭 모드는 영향 없었다.
🐛 Fix
Unknown flag --workspace-status for command: worktree create로 dispatch 가 실패하던 문제 —--workspace-status는worktree set전용 플래그인데worktree create에 붙어 있었다. Orca 버전이 바뀌어 생긴 문제가 아니라 어떤 버전에도 없던 플래그였다. 워크트리 카드는 생성 시 이미in-progress상태가 되므로 플래그 자체가 불필요했고, 그대로 제거했다.--help출력을 파싱해 플래그 유무로 분기하는 우회는 쓰지 않았다. 없앨 수 있는 의존을 조건부로 감싸면 복잡도만 영구히 남고, 그 경로가ORCA_BIN을 우회해 테스트가 볼 수 없게 된다.
- 같은 종류의 버그를 테스트가 잡도록 보강 — 테스트용 가짜 Orca 가 어떤 플래그든 받아주는 바람에 계약 테스트 12개가 전부 통과한 채로 배포됐다. 이제 가짜 Orca 가 실제 CLI 와 동일하게 미지 플래그를 거부하며, 허용 플래그 목록은 실제
orca <서브커맨드> --help에서 옮겨왔다. 회귀 케이스도 함께 추가했다.
전수 감사 결과 이 하나를 제외하면 코드가 사용하는 Orca 플래그는 모두 실재한다.
업데이트: /plugin update sshworld
v 1.16.0 — Orca 워크스페이스에서도 plan-dev dispatch 가 동작한다
v1.16.0 — Orca 워크스페이스에서도 plan-dev dispatch 가 동작한다
지금까지 plan-dev 의 자식 dispatch 는 tmux / cmux 두 환경만 알았다. Orca 세션에서는 환경 감지가 default 로 떨어져 dispatch 경로 전체가 subagent 폴백으로 축소됐고, 자식을 곁눈으로 볼 수도 회수할 수도 없었다. 이번 릴리즈로 Orca 가 세 번째 1급 driver 가 된다.
✨ Feature
- Orca 자동 감지 — Orca 터미널 안에서
/plan-dev를 돌리면 별도 설정 없이dispatch(orca)가 기본이 된다. 감지 우선순위는 tmux → cmux → orca 순이라 기존 cmux 사용자의 동작은 그대로다. --mode=orca자식 dispatch — 슬라이스마다 자식 Claude 가 현재 워크스페이스의 새 탭으로 뜬다. 부모 세션에서 서브에이전트 안으로 들어가지 않아도 진행이 보인다.- 워크트리 카드 모드 — 세션이 Orca 에 git repo 로 등록된 단일-repo 워크스페이스면 자식이 독립 카드로 뜨고 카드에 슬라이스 이름이 표시된다. 여러 repo 를 감싸는 folder 워크스페이스면 자동으로 탭 모드로 폴백한다. 플래그가 아니라 환경이 결정하며,
ORCA_WORKTREE_MODE=0으로 끌 수 있다. - 회수·정리 전 계통 지원 —
reap/reap-orphans/cleanup/ 계보 원장(--kind=orca) 이 Orca 에서도 동작한다. 자기 터미널은 기록·회수 양쪽에서 구조적으로 차단된다. - 설계 문서를 Orca 편집기로 연다 —
scripts/open-doc.sh추가. Orca 세션이면 내장 에디터로 열고, 워크스페이스 밖 경로는 기존 심링크를 경유해 재시도한 뒤 OS 기본 앱으로 폴백한다. 심링크를 임의로 만들지는 않는다.
🐛 Fix
- 자식 회수가 조용히 무력이던 문제 — Orca 자식을 터미널 제목으로 식별하고 있었는데, 자식 Claude 가 기동하면서 제목을 자기 것으로 덮어쓴다(되돌려도 몇 초 뒤 다시 덮인다). 그 결과
cleanup이 "0개 정리함" 을 성공으로 보고하고,reap-orphans가 고아를 못 찾고, 자식 수 상한(CLAUDE_MAX_CHILD_PANES)이 Orca 에서 전혀 걸리지 않았다. 식별 근거를 계보 원장으로 옮겨 세 경로를 모두 복구했다. - 환경 감지 확장으로 드러난 테스트 격리 구멍 8곳 — 그중 둘은 "감지 실패" 를 검증한다면서 실제로는 다른 이유로 통과하던 가짜 통과였고, 둘은 테스트가 실제 Orca 워크스페이스 상태를 변경하고 있었다.
♻️ Refactor / Chore
- 훅 6개를 멀티플렉서 공용으로 — 계획 승인 게이트(direct-edit 차단), 세션 시작 안내, 완료 통지, 자동 회수, 자식 수 상한, 컨텍스트 경고가 cmux 와 Orca 양쪽에서 동작한다. 파일명과 기존 환경변수 이름은 그대로 두고
CBP_*별칭만 추가해, 이미 설치된 설정을 재설치 없이 쓸 수 있다.
📝 Docs
- Slice File Map 의
Mode컬럼에dispatch(orca)추가, dispatch 가이드에 Orca 절 신설. - 환경변수 표에
ORCA_BIN/ORCA_WORKTREE_MODE/OPEN_DOC_DRY_RUN/CBP_DESIGN_LINK추가. - Orca 환경에서 테스트를 쓸 때의 함정을 안티패턴에 기록 — 개발 머신 자체가 Orca 세션이면 환경변수를 걷어내지 않은 테스트가 엉뚱한 이유로 통과·실패한다.
업데이트: /plugin update sshworld
v 1.15.0 — orbit: 라우트 사이클이 닫히는가
v1.15.0 — orbit: 라우트 사이클이 닫히는가
Next.js App Router 프로젝트에서 빌드도 테스트도 못 잡는 결함 부류가 있다. 도달 못 하는 페이지, 갇히는 화면, 끊긴 링크, 실패 경로 없는 흐름 — 프레임워크가 조용히 폴백하고, 링크가 없는 것은 애초에 에러가 아니다. 사람이 클릭해보기 전까지 안 드러난다. orbit 은 라우트를 방향 그래프로 보고 그걸 점검한다.
✨ Feature
orbit스킬 (/orbit) — 검사 4종을 한 스킬이 담당한다.dangling엣지 끝에 실존 라우트 없음 ·orphaninbound 0 ·sinkoutbound 0 ·미폐쇄성공 엣지만 있고 실패·무권한·복구 경로 없음- 산출물은 보고서다. 스킬이 파일을 고치지 않는다.
- sink 는 프레임워크 동작을 단정하지 않는다 — "기본 404 는 공통 레이아웃 밖에서 렌더된다" 같은 문장은 버전·설정에 따라 틀리고, 틀리면 틀린 근거로 결함을 보고하게 된다. 대신 확인 가능한 질문으로 판단한다:
notFound()를 던지는데 수신 파일(not-found.tsx/error.tsx)이 있는가, 그 화면에서 앱으로 돌아가는 링크가 있는가. - 엣지 추출은
<Link>만 보지 않는다 — 템플릿 리터럴href,router.push,redirect(),middlewarematcher, 그리고 네비게이션 링크 상수 파일. 마지막 것을 빠뜨리면 사이드바를 배열로 모아둔 흔한 패턴에서 orphan 오탐이 쏟아진다. - 자체 픽스처 내장 (
skills/orbit/fixture/) — 결함 4종이 심겨 있다. 다만 핵심은 결함이 아니라 오탐 유발 요소 3종(공통 레이아웃<Nav/>/NAV_LINKS상수 / middleware 리다이렉트)이다. 이게 있어야 "안 잡아야 할 걸 안 잡았나" 가 검증된다. 빌드하지 않는다 — 정적 분석 대상. - 프로젝트에 심을 상시 규칙 두 줄을 SKILL.md 안 복사용 섹션으로 제공 — 스킬은 호출해야 뜨므로 "구현 중 상시" 는 대상 프로젝트의 CLAUDE.md 에 붙여넣어야만 성립한다.
ℹ️ 실행이 잡은 빈틈
픽스처에 실제로 돌려보니 루트 app/page.tsx 가 inbound 0 이라 정의상 orphan 으로 잡혔다 — 진입점이지 결함이 아니다. 진입점 예외를 넣되 "직접 진입 설계라는 근거를 함께 적는다" 를 조건으로 달았다. 조건 없이 면제하면 orphan 검사 자체가 무력화된다.
정작 잡힌 오탐은 의도적으로 심은 3종이 아니라 아무도 심지 않은 루트 노드였다. 결함 목록을 설계할 때 "정상인데 검사에 걸리는 것" 은 잘 떠오르지 않는다.
업데이트: /plugin update sshworld
v 1.14.1 — dispatch 가 죽는 세션의 탈출구를 실제로 열었다
v1.14.1 — dispatch 가 죽는 세션의 탈출구를 실제로 열었다
cmux dispatch 는 stale CMUX_WORKSPACE_ID 로 통째로 죽는 세션이 있다(백그라운드 job 에서 특히 흔하다). 그때 유일한 격리 실행 경로가 subagent 인데, 두 세션이 같은 자리에서 막혀 결국 부모가 직접 편집해야 했다. 이번 버전이 그 경로를 열고 실제로 돌려서 확인했다.
🐛 Fix
- subagent 폴백 절차 명문화 — 막힌 원인은
.gitignore의.claude/specs/*.spec.md였다. spec 파일이 격리 worktree 로 따라가지 않는다. 해법은 파일 복사도 gitignore 예외도 아니라 spec 본문을 프롬프트에 인라인하는 것 — subagent 는 cmux send 크기 제약이 없으므로 파일 전달을 포기하면 문제가 사라진다. 절차는commands/plan-dev/troubleshooting-dispatch.md의 'subagent 폴백'. - 작업 디렉토리 지시 정정 — 초안은 "자식 worktree 절대경로를 넘겨라" 였는데 실제로 넘길 수가 없다.
isolation="worktree"는 하네스가 경로를 정하므로 프롬프트 작성 시점에 그 값이 없다(dispatch 스크립트는 부모가git worktree add하니 알 수 있었다). "시작 즉시pwd확인, 밖으로cd금지" 로 지시한다. enforce-doc-sync.sh가git -C <path> commit/git -c k=v commit을 놓치던 문제 — 탐지 정규식이git commit만 잡아 DOC 영향 평가가 조용히 누락됐다.commit이 서브커맨드 위치일 때만 매치하도록 확장. 적대 검증 9케이스 통과 (git commit-tree접두 오매치,git log --grep=commit인자 값, 따옴표 안 문자열,&&체인).dispatch --mode=subagent안내가 절차 문서와 gitignore 함정을 직접 가리킨다.
📝 Docs
known-issues.md#18 의 "subagent 폴백 경로는 검증됨" 오기 정정 → 2026-08-19 실측 완료로 갱신. #12 는 해결 표기.
ℹ️ 이번 fix 는 이번 fix 로 만들어졌다
enforce-doc-sync 수정(위 3번째 항목)은 새로 연 폴백 경로로 실행했다 — 자식이 격리 worktree 에서 TDD 완주(9 테스트 PASS) 후 ✅ 반환, 부모가 검토·통합. 절차 결함 1건도 그 과정에서 드러나 같이 고쳤다.
업데이트: /plugin update sshworld
v 1.14.0 — 슬라이스 간 계약을 사람이 승인하는 슬롯으로
v1.14.0 — 슬라이스 간 계약을 사람이 승인하는 슬롯으로
Slice File Map 은 이름과 달리 rebase 충돌을 막는 머지 물류표였다. 파일이 안 겹친다고 계약이 맞는 건 아닌데, 슬라이스 간 인터페이스와 에러 정책을 사람이 승인하는 자리가 어디에도 없었다. 이번 버전이 그 슬롯을 만든다.
✨ Feature
- 설계 문서에
## 3.5 인터페이스 계약블록 신설 —제공자 / 소비자 / 계약(시그니처·불변식·소유권) / 실패 시(중단·감수)4칸.실패 시칸이 곧 에러 정책이다. 슬라이스가 2개 이상이고 서로의 산출물을 소비할 때 채운다. - 계약은 게이트 트리거가 아니다 — 2게이트 판정은 기존 4개 블록(원인분석/구조델타/결정갈림길/기준선)으로 유지된다. 계약을 트리거에 넣으면 조건이 "슬라이스 2개 이상"이라 거의 모든 세션이 2게이트가 되어 fast path 가 사라지기 때문. 계약은 구조 델타의 하위 상세다.
- spec 작성 규약에
## 계약섹션 필수 — 설계 문서는 개인 머신에 있고 plan 은 작업 후 폐기되며 dispatch 는 spec 본문이 아니라 경로만 자식에게 보낸다. 이 섹션이 계약이 자식에게 도달하는 유일한 통로다. - implementor 가 계약을 요구사항으로 취급 — 입력에 계약·에러 정책이 추가됐고, 계약의
실패 시에 적힌 에러 경로는 YAGNI 대상이 아님을 명시했다. 구현이 곤란하면 조용히 빼지 말고❌로 보고한다. 기존에는 "최소 구현 + YAGNI" 조합이 에러 경로를 지웠다. - plan 의 동작 스펙에 에러 정책 연결 규칙 — 계약에서
중단인 경로는 동작 스펙에 대응 테스트 케이스가 있어야 한다. implementor 는 테스트 목록으로 일을 받으므로, 계약에만 적고 케이스가 없으면 그 경로는 구현되지 않는다.
📝 Docs
- 설계 문서 경로 표기 드리프트 정정 —
docs/design/<slug>.md→~/.claude/design/<repo>/<slug>.md(v1.13.0 에서 옮겼는데 plan-dev 커맨드에만 옛 경로가 남아 있었다).
♻️ Chore
- lint 4종 (
contract_spec_lint.sh신규 + 기존 3종 확장). 트리거 열거 회귀 가드는 파일 전체가 아니라 게이트 판정 문장만 보도록 좁혔다 — 변이 테스트로 실증.
⚠️ 알아둘 한계
하네스는 템플릿에 슬롯이 있다까지만 보증한다. 세션이 실제로 계약을 채웠는지는 설계 문서 인스턴스가 repo 밖에 있어 구조적으로 검사할 수 없다 — 콘텐츠 전용 강제다.
업데이트: /plugin update sshworld
v 1.13.0 — 비-git dispatch 자식 회수 복구 + 설계 문서는 개인 머신으로
v1.13.0 — 비-git dispatch 자식 회수 복구 + 설계 문서는 개인 머신으로
비-git 디렉토리에서 자식 4개가 전부 정상 완료했는데 부모가 받은 완료 통지가 0건이었다. 부모는 자식이 끝난 줄 모르고 턴을 종료했다.
🐛 Fix
- done-marker 가 사실상 한 경로에서만 기록되던 문제.
hooks/notify-slice-done.sh의 조기 종료가 4중이었다 — 비-cmux / 비-git / 일반 체크아웃(GIT_DIR==GIT_COMMON) /TOPLEVEL이*/.worktrees/*아님. 전 경로exit 0이라 실패가 로그에도 안 남았다. marker 부재가 reap fast-path ·reap-on-stop자동 통지 · (폴백인)wait-idle을 동시에 죽였다 — 벨트와 멜빵이 같은 못에 걸려 있었다. scripts/cbp-marker-path.sh신설 (공용 리졸버). writer 1곳과 reader 4곳(cmux-pane.sh×3,reap-on-stop.sh)이 각자 marker 경로를 계산해서, 한 곳만 고치면 writer/reader 가 갈라졌다. 우선순위:CBP_MARKER_DIR> git-common-dir >~/.cache/cbp/marker-<workspace>. 비-git 폴백 규칙은enforce-cmux-dispatch.sh가 이미 쓰던 것을 재사용했다.wait-idle이 살아있는 Claude TUI 상대로 원리상 반환하지 않던 문제. 화면 원본 sha 비교라 경과시간·비용·스피너가 매초 바뀌어 idle 에 도달하지 못했다(실측timeout (540s), 자식이 이미 파일을 쓴 뒤). 해시 전 변동 라인을 마스킹한다 — 단 맨 초 단위(42s)는 상태줄에서만 지운다. 전역으로 지우면 본문의 진행 변화까지 삼켜 "아직 일하는 중인데 idle" 로 조용히 오판한다.- 비-git dispatch 하드 실패.
git worktree add실패로 종료했고--worktree우회 안내도 없었다. 격리는 목적이 아니라 슬라이스간 파일 충돌 방지 수단이고 그 충돌은 plan 의 Slice File Map 이 관리하므로, 경고 1줄 후 cwd 로 진행한다. git repo 경로는 무변경. - 게이트 escape 안내가 코드와 불일치. 비-git 폴백의
-<sanitized workspace>접미사가 빠진 경로를 안내해서, 그대로touch하면 훅이 절대 보지 않는 파일이 생기고 재시도해도 같은 자리에서 다시 막혔다. 안내가 훅이 실제로 소비하는 변수를 그대로 출력하도록 단일 출처화. read-screen→capture.read-screen은 cmux CLI 명령이고cmux-pane.sh의 대응은capture다. 안내대로 하면 실패했다.- 비-git 에서 detached HEAD 오진단.
marker_path()안의die가 항상 command substitution 에서 실행돼 서브셸만 죽였고, 본체가 계속 진행해 사실과 다른 진단을 냈다. 판정을do_start진입부로 옮겨 실제로 종료되게 했다. - launch-time 사망의 원인 확정 (한 달 미해결).
cmux new-pane호출이 stderr 를 버려서, 실제 에러not_found: Workspace not found가 "PTY 미기동(not a terminal)" 이라는 엉뚱한 메시지로 나타났다. 세션이 자기 workspace 보다 오래 살아남으면(데몬 재시작·재호스팅)CMUX_WORKSPACE_ID가 stale 이 된다. stderr 보존 + stale 선검사 + 폴백 안내를 추가했다. 기존 가설("surface 는 생기나 terminal 미attach")은 틀렸다 — surface 는 애초에 만들어지지 않았다.
♻️ Refactor
- 설계 문서 기본 경로를
~/.claude/design/<repo>/로. v1.10.0 은 repodocs/design/에 두고 "인수인계·이력서 자산" 으로 규정했는데, 그 프레이밍은 모델이 얹은 것이고 사용자가 말한 "영속" 은 개인 머신 영속이었다. 이 저장소는 공개라 커밋하면 개인 작업 노트가 그대로 공개되고, 팀 저장소라면 타인에게 읽기·유지를 강요한다.CBP_DESIGN_DIRoverride 는 유지 — 팀과 공유할 문서만 repo 안 경로를 명시한다. 커밋돼 있던docs/design/plan-presentation.md는 제거했다.
📝 Docs
- dispatch 후 감시를 의무로 명시. 통지 체인은 조용히 실패할 수 있다(실측 0건). 감시 루프를 걸지 않은 채 턴을 종료하지 말 것.
- 설계 문서는 작성 직후
open으로 사용자 화면에 띄운다 — 못 본 상태의 승인은 승인이 아니다.
계약 변경: 일반 체크아웃과 .worktrees/ 밖 worktree 에서도 이제 통지·marker 가 기록된다. 구계약을 검사하던 테스트 2건을 새 계약으로 갱신했다.
테스트: 91개 전체 통과 (신규 27항목). 설계 문서의 재현 절차를 기준선으로 실행해 4단계 전부 증상 소멸을 확인했다.
업데이트: /plugin update sshworld