Files
llm-wiki/docs/superpowers/plans/2026-07-14-harness-correctness-sweep.md
T

452 lines
25 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 하네스 정합성 스위프 (Tier A) Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 문서·설정이 실제 repo 상태와 어긋난 4개 지점(A1 Antigravity 훅 경로 / A2 Codex 로딩 문서 오류 / A3 wiki-doc-author 계약 결함 3종 / A4 인벤토리 숫자)을 아키텍처 변경 없이 정합화한다.
**Architecture:** 순수 config·문서·프롬프트 텍스트 편집 + 결정론적 검증(grep / `json.tool` / `tomllib` / `pytest`). 새 기능 코드는 없다. "test" 사이클은 *현재상태 assert(grep) → 편집 → 정합 assert(grep/syntax) → commit*. A3 은 3개 플랫폼 계열 5개 표현 파일을 **하나의 commit 으로** 원자 정합화(부분 정합 = 새 드리프트).
**Tech Stack:** git, Python 3.12(`json.tool`, `tomllib`, `pytest`), grep, bash. Antigravity CLI(A1 E2E 확인용, user-gated).
**Spec:** [docs/superpowers/specs/2026-07-14-harness-correctness-sweep-design.md](../specs/2026-07-14-harness-correctness-sweep-design.md) (rev.3)
## Global Constraints
모든 task 는 아래를 암묵적으로 포함한다. 값은 spec 에서 verbatim 복사.
- **브랜치:** main 이 현재 dirty(무관한 미완 작업 존재). 반드시 `harness-correctness-sweep` 브랜치에서 작업.
- **스테이징 격리:** `git add -A` / `git add .` **절대 금지**. 각 commit 은 그 task 의 명시된 파일만 `git add <경로>`. (무관한 dirty 파일 오염 방지.)
- **git-diff allowlist (이 10파일 + 조건부 launcher + 본 plan/spec 외 변경 금지):**
```
.agents/hooks.json
CLAUDE.md
AGENTS.md
.codex/agents/README.md
.agents/plugins/wiki-superpowers/README.md
.claude/agents/wiki-doc-author.md
.agents/plugins/wiki-superpowers/agents/wiki-doc-author.md
.codex/agents/wiki-doc-author.md
.codex/agents/wiki-doc-author.toml
.agents/agents/wiki-doc-author/agent.json
# 조건부(A1 launcher 채택 시에만): .agents/hooks/run-wiki-hook.py
```
- **A1 portable-only:** 새 하드코딩 절대경로 채택 금지. 우선순위 — env var → `git rev-parse` → launcher self-locate. 절대경로는 임시 진단 외 최종안 아님.
- **A3 부분변경 = `Status = BLOCKED`** (고정, "또는 PARTIAL" 금지 — `PARTIAL` 은 doc-author output schema 에 미정의; `DONE | NEEDS_CONTEXT | BLOCKED` 뿐).
- **A3 카테고리 = 8** (branch-note, error-note, interview-prep, job-posting, blog-topic, lecture-note, project-note, daily-note). **validator 개수 하드코딩 제거**(8→7 로 바꾸지 **않음**).
- **A3 migrate 본문-보존 계약 불변** — 건드리지 않는다.
- **A4 historical 제외:** `docs/superpowers/plans/*`·`notes/*` 의 동일 stale 문구는 dated 기록이라 **정정 대상 아님**. "14개"/"7개" 는 다의어 — 자동 치환 금지, inventory 문맥만 수동 판정.
- **임시 진단/테스트 파일은 최종 `git diff` 잔존 0.**
### 공유 스니펫 — A3 새 계약 텍스트 (D1)
A3 의 5개 표현 파일이 **동일 계약**으로 수렴해야 하는 canonical 문구. 각 파일의 포맷(md 산문 / toml 문자열 / json 이스케이프 문자열)에 맞춰 적용하되 의미는 동일.
- **STOP 조건(파일수 STOP 대체):**
> target document + 그 Parent hub 외의 파일을 생성·수정하려는 요청 — 1 dispatch = 1 논리적 문서(허용 write set: target 1개 + 그 Parent hub 의 `## Cluster` 링크 유지만; 다른 raw/rule/template/derived 문서 수정 금지)
- **"What you are NOT" 라인 대체:**
> - target document + 그 Parent hub 외 파일 수정 금지 (1 dispatch = 1 논리적 문서: target 1개 + Parent hub Cluster 링크 유지만 허용)
- **description 절 대체** (`Writes exactly 1 file and reports validation.` →):
> Creates or migrates one target document (also maintaining its Parent hub Cluster link) and reports validation.
- **부분변경 규칙(신규 1줄, Shortcut Trap 또는 작업 절차 말미):**
> target 또는 Parent hub 중 일부만 변경되고 나머지가 실패하면 DONE 금지 → **Status = BLOCKED**, 변경 성공 파일 + 실패 단계 모두 보고 (자동 rollback 미구현).
---
## Task 0: 브랜치 + baseline 캡처 (setup)
**Files:** (변경 없음 — 브랜치 생성 + 읽기 전용 baseline)
- [ ] **Step 1: main 에서 작업 브랜치 생성**
```bash
git rev-parse --abbrev-ref HEAD # main 확인
git checkout -b harness-correctness-sweep
```
Expected: `Switched to a new branch 'harness-correctness-sweep'`
- [ ] **Step 2: A4 권위 카운트 baseline 기록 (이 값이 문서 정정의 근거)**
Run:
```bash
echo "templates=$(find templates -maxdepth 1 -type f -name '*.md' | wc -l)"
echo "rules=$(find rules -maxdepth 1 -type f -name '*.md' | wc -l)"
echo "claude_agents=$(find .claude/agents -maxdepth 1 -type f -name '*.md' | wc -l)"
echo "antigravity_exec_agents=$(find .agents/agents -mindepth 2 -maxdepth 2 -type f -name 'agent.json' | wc -l)"
echo "agent_prompt_ssot=$(find .agents/plugins/wiki-superpowers/agents -maxdepth 1 -type f -name '*.md' | wc -l)"
echo "commands=$(find .claude/commands -maxdepth 1 -type f -name '*.md' | wc -l)"
```
Expected: `templates=27 rules=14 claude_agents=12 antigravity_exec_agents=10 agent_prompt_ssot=10 commands=23`
(값이 다르면 STOP — spec 숫자 재확정 필요.)
- [ ] **Step 3: 현재 dirty 파일 목록 기록 (오염 감시 기준선)**
Run: `git status --short`
기대: 무관한 기존 변경(ca-tmpl 삭제, experiment-nplus1 수정, error 노트들, llm-wiki-harness.xml)이 보임. 이 파일들은 **이번 작업에서 절대 stage 하지 않는다.**
(commit 없음 — setup only.)
---
## Task 1: A1 — Antigravity 훅 경로 정합 (portable) + JSON 검증
**Files:**
- Modify: `.agents/hooks.json` (4개 command entry)
- (조건부, E2E 실패 시에만) Create: `.agents/hooks/run-wiki-hook.py`
**결정 배경 (spec §4 A1):** 대상 절대경로 `/home/donghyeon/dev/llm-wiki-private/...` 는 존재하지 않는 경로(dead). 새 절대경로로 바꾸면 이동·clone 시 재사망 → portable 필수. 이 세션(Claude Code)에서 Antigravity 실제 실행 cwd 를 관측할 수 없으므로, **Codex 가 이미 쓰는 검증된 상대경로 형태**(`.codex/hooks.json` 참조)를 기본값으로 채택하고, 실제 firing 은 user 가 Antigravity 세션에서 확인한다. E2E 확인 전까지 A1 verdict = **PARTIAL**.
- [ ] **Step 1: 현재 dead 경로 확인 (assert 실패상태)**
Run: `grep -n '/home/donghyeon/dev/llm-wiki-private' .agents/hooks.json`
Expected: 4개 line hit (claim-gate Pre/Stop, structure-gate Pre/Post). 그리고:
```bash
ls /home/donghyeon/dev/llm-wiki-private 2>&1 # → No such file or directory (dead 확인)
```
- [ ] **Step 2: 4개 command 를 Codex-미러 상대경로로 수정**
`.agents/hooks.json` 의 4개 `command` 문자열을 절대경로 → 상대경로로. (앞부분 `python3 ` + 뒷부분 flags 는 보존, 경로만 교체.)
| Gate.Event | 현재 | 수정 후 |
|---|---|---|
| wiki-claim-gate.PreToolUse | `python3 /home/donghyeon/dev/llm-wiki-private/.claude/hooks/wiki_claim_gate.py --antigravity` | `python3 .claude/hooks/wiki_claim_gate.py --antigravity` |
| wiki-claim-gate.Stop | `python3 /home/donghyeon/dev/llm-wiki-private/.claude/hooks/wiki_claim_gate.py --antigravity` | `python3 .claude/hooks/wiki_claim_gate.py --antigravity` |
| wiki-structure-gate.PreToolUse | `python3 /home/donghyeon/dev/llm-wiki-private/.claude/hooks/wiki_structure_lint.py --pre --antigravity` | `python3 .claude/hooks/wiki_structure_lint.py --pre --antigravity` |
| wiki-structure-gate.PostToolUse | `python3 /home/donghyeon/dev/llm-wiki-private/.claude/hooks/wiki_structure_lint.py --hook --antigravity` | `python3 .claude/hooks/wiki_structure_lint.py --hook --antigravity` |
`wiki-hard-gate`(global `~/.gemini/...`)는 **건드리지 않는다.**
- [ ] **Step 3: 정합 assert (grep) + JSON 구문 검증**
Run:
```bash
grep -c '/home/donghyeon/dev/llm-wiki-private' .agents/hooks.json # 기대: 0
grep -c 'python3 .claude/hooks/' .agents/hooks.json # 기대: 4
python3 -m json.tool .agents/hooks.json >/dev/null && echo "JSON OK"
```
Expected: `0`, `4`, `JSON OK`
- [ ] **Step 4: commit**
```bash
git add .agents/hooks.json
git commit -m "fix(hooks): repair dead Antigravity hook paths (absolute→portable relative)
wiki-claim-gate/wiki-structure-gate pointed at /home/donghyeon/dev/... which
does not exist. Mirror Codex's proven repo-root-relative form.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"
```
- [ ] **Step 5: E2E 확인 (USER-GATED — Antigravity 세션 필요)**
이 세션에서 Antigravity 를 구동할 수 없으므로, 사용자에게 아래를 요청하고 결과를 받는다. spec §5 A1 표 6행:
| Hook | 발생 이벤트 | 기대 |
|---|---|---|
| claim gate PreToolUse | Antigravity 에서 Write/Edit | hook 실행 로그 |
| claim gate Stop | agent 정상 종료 | 종료 hook 로그 |
| structure gate PreToolUse | Markdown Write/Edit | pre 검사 실행 |
| structure gate PostToolUse | Markdown 쓰기 완료 | post 검사 실행 |
| 차단 검증 | 규칙 위반 임시 입력 | BLOCK 전달 |
| 정상 검증 | 규칙 만족 임시 입력 | PASS 후 계속 |
- **firing 확인됨** → A1 = DONE.
- **firing 안 됨(cwd ≠ repo root)** → 상대경로 무효 → Step 6(fallback) 진행.
- **확인 불가(Antigravity 세션 없음)** → A1 = **PARTIAL**, 나머지 task 진행, 사용자 확인 시 재개.
- [ ] **Step 6: (조건부 fallback — Step 5 에서 firing 실패 시에만) launcher 도입**
Antigravity 가 repo-root cwd 가 아니고 workspace-root 환경변수도 없으면, `.agents/hooks.json` 이 참조할 수 있는 경로 형태(Antigravity 가 resolve 가능한 형태 — 진단으로 확정)로 launcher 를 두고, launcher 가 자기 위치에서 repo root 를 찾아 실제 hook 을 exec 한다. 진단(pwd/env)이 선행되어야 하며 결과에 따라 형태 확정. 이 fallback 을 쓰면 `.agents/hooks/run-wiki-hook.py` 를 allowlist 에 포함하고 별도 commit. **Step 5 firing 확인 전에는 착수하지 않는다.**
---
## Task 2: A2 — CLAUDE.md Codex 로딩 서술 정정
**Files:**
- Modify: `CLAUDE.md:82` (§2 Hooks bullet 내 codex fallback 절)
- [ ] **Step 1: 현재 오류 문구 확인 (assert)**
Run: `grep -n 'codex 가 본 CLAUDE.md 를 프로젝트 지침으로 읽음(AGENTS.md 중복 불필요)' CLAUDE.md`
Expected: line 82 hit.
- [ ] **Step 2: 문구 교체 (Codex 로만 증거 한정, Antigravity 단정 금지)**
`CLAUDE.md:82` 의 다음 절을 교체:
old:
```
`.codex/config.toml` 의 `project_doc_fallback_filenames = ["CLAUDE.md"]` 로 codex 가 본 CLAUDE.md 를 프로젝트 지침으로 읽음(AGENTS.md 중복 불필요).
```
new:
```
`.codex/config.toml` 의 `project_doc_fallback_filenames = ["CLAUDE.md"]` 는 해당 디렉터리에 `AGENTS.md` 가 **없을 때만** 쓰이는 fallback 이다 — 루트 `AGENTS.md` 가 존재하는 현재 구조에선 발동하지 않으므로, Codex 는 `AGENTS.md`(CLAUDE.md 의 ≤150줄 요약)를 진입점으로 로드한다. CLAUDE.md 는 그 요약이 가리키는 모든 모델 공통 **운영-규칙 SSOT** 로 유지된다(Codex 가 CLAUDE.md 를 자동 지침으로 직접 선택한다고 가정 금지).
```
- [ ] **Step 3: 정합 assert**
Run:
```bash
grep -c 'AGENTS.md 중복 불필요' CLAUDE.md # 기대: 0
grep -c '없을 때만' CLAUDE.md # 기대: ≥1 (새 문구)
```
Expected: `0`, `≥1`
- [ ] **Step 4: commit**
```bash
git add CLAUDE.md
git commit -m "docs(CLAUDE): correct Codex project-doc loading (AGENTS.md preempts CLAUDE.md fallback)
Root AGENTS.md exists, so project_doc_fallback_filenames never fires; Codex
loads AGENTS.md, not CLAUDE.md. Scope claim to Codex only.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"
```
---
## Task 3: A3 — wiki-doc-author 계약 정합 (5표현 원자 commit)
**Files (모두 한 commit):**
- Modify: `.agents/plugins/wiki-superpowers/agents/wiki-doc-author.md` (SSOT, 먼저)
- Modify: `.claude/agents/wiki-doc-author.md`
- Modify: `.codex/agents/wiki-doc-author.md`
- Modify: `.codex/agents/wiki-doc-author.toml`
- Modify: `.agents/agents/wiki-doc-author/agent.json`
**Interfaces (계약 불변식 — 5파일 수렴 목표):** target=1 · Parent hub edit 허용 · unrelated edit 금지 · category=8 · validator 개수 비고정 · migrate 본문보존 유지 · 부분변경→BLOCKED.
**결함 분포 (spec §4 A3):**
| 파일 | D1(파일수 STOP+What NOT+desc) | D2(category 7→8) | D3((8개 모두)→비고정) |
|---|---|---|---|
| plugin SSOT md | 有 (L78, L253, desc) | 有 (L73) | 편집 시 확인 |
| Claude md | 有 (L73, L240, desc) | 無(이미 8) | 無 |
| Codex md | 有 (What NOT L191, desc, STOP 재확인) | 無(이미 8) | 편집 시 확인 |
| Codex toml | 有 (What NOT L190, desc, STOP 재확인) | 無(이미 8) | 편집 시 확인 |
| agent.json | 有 (STOP#7, What NOT, desc) | 有 (STOP#2 + STOP-check table row2) | 有 ("(8개 모두)") |
각 파일은 **먼저 Read** 해서 정확한 old 문자열을 확보한 뒤 편집(사본마다 표현이 다름). 적용할 새 문구는 Global Constraints §"공유 스니펫 — A3 새 계약 텍스트 (D1)" 참조.
- [ ] **Step 1: plugin SSOT 편집 (`.agents/plugins/wiki-superpowers/agents/wiki-doc-author.md`)**
Read 후 적용:
- **D1** — L78 파일수 STOP(`2개 이상 파일 만들기 / 수정 (1 dispatch = 1 file 위반)`) → 공유 스니펫 STOP 문구. L253 "What NOT"(`여러 파일 동시 생성·수정 금지 (1 dispatch = 1 file)`) → 공유 스니펫 What-NOT 문구. description(`Writes exactly 1 file and reports validation.`) → 공유 스니펫 description. 부분변경 규칙 1줄 추가(Shortcut Trap 또는 작업 절차 말미).
- **D2** — L73 `Category ∉ 7 허용` → `Category ∉ 8 허용`.
- **D3** — Post-Write Validator 블록에 `(N개 모두)` 식 숫자 하드코딩이 있으면 `(위 Validator 의 모든 적용 가능 항목)` 로. 없으면 skip.
- [ ] **Step 2: Claude md 편집 (`.claude/agents/wiki-doc-author.md`)**
Read 후 적용:
- **D1** — L73 STOP #5(`5. 2개 이상 파일 생성·수정 요청 — 1 dispatch = 1 file`) → 공유 스니펫 STOP. L240 What-NOT(`여러 파일을 한 번에 생성·수정 금지 (1 dispatch = 1 file)`) → 공유 스니펫 What-NOT. L3 description → 공유 스니펫 description. 부분변경 규칙 1줄 추가.
- D2/D3 없음(이미 8, validator 하드코딩 없음).
- [ ] **Step 3: Codex md 편집 (`.codex/agents/wiki-doc-author.md`)**
Read 후 적용:
- **D1** — 파일수 STOP 조건(있으면) + What-NOT(L191 `여러 파일을 한 번에 생성·수정 금지 (1 dispatch = 1 file)`) + description → 공유 스니펫. 부분변경 규칙 1줄 추가.
- D3 — validator 숫자 하드코딩 있으면 제거.
- [ ] **Step 4: Codex toml 편집 (`.codex/agents/wiki-doc-author.toml`)**
Read 후 적용 (프롬프트가 TOML 문자열 — 따옴표/이스케이프 보존):
- **D1** — 파일수 STOP + What-NOT(L190) + description(L2) → 공유 스니펫. 부분변경 규칙 1줄 추가.
- D3 — validator 숫자 하드코딩 있으면 제거.
- [ ] **Step 5: agent.json 편집 (`.agents/agents/wiki-doc-author/agent.json`)**
Read 후 적용 (프롬프트가 JSON 이스케이프 문자열 — `\n`·`\"` 이스케이프 **보존**):
- **D1** — 임베디드 프롬프트의 STOP #7(`2개 이상 파일 만들기 / 수정 (1 dispatch = 1 file 위반)`) + What-NOT(`여러 파일 동시 생성·수정 금지 (1 dispatch = 1 file)`) + top-level `description`(`Writes exactly 1 file and reports validation.`) → 공유 스니펫. 부분변경 규칙 1줄 추가.
- **D2** — STOP #2(`Category ∉ 7 허용`) 및 STOP-check 표 row2(`Category in 7 allowed`) → `8`.
- **D3** — output schema 의 `... (8개 모두)` → `(위 Validator 의 모든 적용 가능 항목)`.
- [ ] **Step 6: 잔존-문구 grep (5표현 전부, 기대 0)**
Run (spec §5 A3 넓힌 패턴):
```bash
grep -RInE '1 dispatch = 1 file|Writes exactly 1 file|Write 1 file|write the file once|2개 이상 파일|여러 파일을 한 번에 생성.?수정 금지|여러 파일 동시 생성.?수정 금지|Category ∉ 7|Category in 7 allowed|8개 모두' \
.claude/agents/wiki-doc-author.md \
.codex/agents/wiki-doc-author.md \
.codex/agents/wiki-doc-author.toml \
.agents/plugins/wiki-superpowers/agents/wiki-doc-author.md \
.agents/agents/wiki-doc-author/agent.json
```
Expected: **0 hit**. hit 남으면 해당 파일 재편집.
> **판정 주의:** `write the file once` / `one file at a time` 같은 *도입 문장*이 잡히면 — **파일 수를 계약으로 단정하는 경우**(예: "you write **the file** once"가 '단일 파일만'을 함의)만 새 write-set 계약과 어긋나므로 정정한다. 단순히 target 문서 1개를 쓴다는 서술은 새 계약과 일치하므로 유지 가능. 즉 이 grep 은 *탐지 그물*이고, 제거 대상은 "target+Parent 2파일"과 모순되는 file-count 단정뿐이다.
- [ ] **Step 7: 새 계약 문구 존재 + 구문 검증**
Run:
```bash
# 새 write-set 계약 문구가 5표현 전부에 존재
grep -Rl '1 논리적 문서' \
.claude/agents/wiki-doc-author.md .codex/agents/wiki-doc-author.md \
.codex/agents/wiki-doc-author.toml \
.agents/plugins/wiki-superpowers/agents/wiki-doc-author.md \
.agents/agents/wiki-doc-author/agent.json | wc -l # 기대: 5
# 구문
python3 -m json.tool .agents/agents/wiki-doc-author/agent.json >/dev/null && echo "json OK"
python3 -c 'import tomllib; tomllib.load(open(".codex/agents/wiki-doc-author.toml","rb")); print("toml OK")'
# category=8 반영 (7 잔존 0)
grep -REc 'Category ∉ 7|Category in 7 allowed' .agents/plugins/wiki-superpowers/agents/wiki-doc-author.md .agents/agents/wiki-doc-author/agent.json # 기대: 0
```
Expected: `5`, `json OK`, `toml OK`, `0`
- [ ] **Step 8: 의미 패리티 표 확인 (수기 — grep 으로 안 잡히는 계약 동등성)**
각 파일을 훑어 아래 6행이 5파일 전부 PASS 인지 확인(문장은 달라도 계약값 동일):
| Contract | Claude md | plugin SSOT | Codex md | Codex toml | agent.json |
|---|---|---|---|---|---|
| target document 1개 | | | | | |
| Parent hub edit 허용 | | | | | |
| unrelated 문서 edit 금지 | | | | | |
| 허용 category = 8 | | | | | |
| validator 개수 비고정 | | | | | |
| migrate 본문 보존 유지 | | | | | |
1개라도 FAIL 이면 해당 파일 재편집 후 Step 6~8 반복.
- [ ] **Step 9: commit (5파일 원자)**
```bash
git add .agents/plugins/wiki-superpowers/agents/wiki-doc-author.md \
.claude/agents/wiki-doc-author.md \
.codex/agents/wiki-doc-author.md \
.codex/agents/wiki-doc-author.toml \
.agents/agents/wiki-doc-author/agent.json
git commit -m "fix(wiki-doc-author): replace '1 file' contradiction with explicit write set (5 platform copies)
D1: '1 dispatch=1 file' vs mandatory Parent-hub edit → explicit allowed write
set (target + its Parent hub only); partial write → BLOCKED. D2: category 7→8.
D3: drop hardcoded validator count. Syntax + semantic parity verified.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"
```
---
## Task 4: A4 — live 문서 인벤토리 숫자 정정
**Files:**
- Modify: `AGENTS.md` (L23, L24, L50)
- Modify: `CLAUDE.md` (L79 — 9→10 agent + scripts 문구)
- Modify: `.codex/agents/README.md` (L9 — scripts 문구)
- Modify: `.agents/plugins/wiki-superpowers/README.md` (L11 scripts, L46 rules 7→14)
**주의:** `CLAUDE.md:81`("생성기 부재(2026-06-06 확인)")은 여전히 참 — **변경 안 함**. historical(`docs/.../plans|notes`) 제외.
- [ ] **Step 1: 현재 stale 문구 확인 (assert, live 문서만)**
Run:
```bash
grep -nE '정의 \(14개|7개 rule|7 agents|동일 9개 agent|디렉터리 자체 부재|the .scripts. directory itself is absent|동일한 7개 rule 파일' \
AGENTS.md CLAUDE.md .codex/agents/README.md .agents/plugins/wiki-superpowers/README.md
```
Expected: AGENTS.md(23,24,50), CLAUDE.md(79), .codex/agents/README.md(9), plugin README(11,46) hit.
- [ ] **Step 2: 정정 적용 (각 파일 Read 후 정확 문자열 교체)**
| 파일:줄 | old | new |
|---|---|---|
| AGENTS.md:23 | `카테고리별 출력 형식 정의 (14개, ` | `카테고리별 출력 형식 정의 (27개, ` |
| AGENTS.md:24 | `**3개 모델 공유 SSOT** — 7개 rule ` | `**3개 모델 공유 SSOT** — 14개 rule ` |
| AGENTS.md:50 | `7 agents (` … `) 가 정의되어 있음.` | `10 agents (7 core + branch-depth-auditor·coverage-auditor·wiki-consistency-auditor) 가 정의되어 있음.` |
| CLAUDE.md:79 | `.claude/`와 동일 9개 agent` | `.claude/`와 동일 10개 agent` |
| CLAUDE.md:79 | `(위 7개 + `branch-depth-auditor`·`coverage-auditor`) 의` | `(위 7개 + `branch-depth-auditor`·`coverage-auditor`·`wiki-consistency-auditor`) 의` |
| CLAUDE.md:79 | `(2026-06-06 확인; `scripts/` 디렉터리 자체 부재)` | `(2026-06-06 확인; `scripts/` 는 존재하나 `sync_automation.py` 만 부재 — 2026-07-14 재확인)` |
| .codex/agents/README.md:9 | `(2026-06-06 확인; `scripts/` 디렉터리 자체 부재)` | `(2026-06-06 확인; `scripts/` 는 존재하나 `sync_automation.py` 만 부재 — 2026-07-14 재확인)` |
| plugin README:11 | `(the `scripts/` directory itself is absent)` | `(the `scripts/` dir now exists — deep-research — but `sync_automation.py` is still absent, re-checked 2026-07-14)` |
| plugin README:46 | `동일한 7개 rule 파일을 공유한다` | `동일한 14개 rule 파일을 공유한다` |
> AGENTS.md:50 은 이름 나열이 길면 위처럼 count+대표 3개로 축약. 정확한 old 문자열은 Read 로 확인 후 교체.
- [ ] **Step 3: 정합 assert (live 문서 stale 잔존 0)**
Run:
```bash
grep -nE '정의 \(14개|— 7개 rule|^본 skill.*7 agents|동일 9개 agent|디렉터리 자체 부재|directory itself is absent|동일한 7개 rule 파일' \
AGENTS.md CLAUDE.md .codex/agents/README.md .agents/plugins/wiki-superpowers/README.md
```
Expected: **0 hit**.
- [ ] **Step 4: 카운트 재검증 (문서값 == 실측)**
Run: Task 0 Step 2 의 `find` 블록 재실행 → 결과가 `27/14/12/10/10/23` 이고 문서 정정값과 일치 확인.
- [ ] **Step 5: commit**
```bash
git add AGENTS.md CLAUDE.md .codex/agents/README.md .agents/plugins/wiki-superpowers/README.md
git commit -m "docs: correct stale inventory counts (templates 14→27, rules 7→14, agents 9→10) + scripts-dir claim
Live docs only; historical plans/notes left as dated records. 2026-07-14
manual snapshot (to be automated by B1 generator).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>"
```
---
## Task 5: 전역 검증 + verdict
**Files:** (변경 없음 — 검증만)
- [ ] **Step 1: 구문 검증 전체**
Run:
```bash
python3 -m json.tool .agents/hooks.json >/dev/null && echo "hooks.json OK"
python3 -m json.tool .agents/agents/wiki-doc-author/agent.json >/dev/null && echo "agent.json OK"
python3 -c 'import tomllib; tomllib.load(open(".codex/agents/wiki-doc-author.toml","rb")); print("toml OK")'
```
Expected: 3 × OK.
- [ ] **Step 2: 기존 hook test 회귀**
Run: `python3 -m pytest .claude/hooks -q`
Expected: 전부 PASS (test_wiki_structure_lint / _consistency_check / _claim_gate / _rules / _quorum 등). 실패 시 원인 조사 — 이번 편집이 hook 스크립트 로직을 안 건드렸으므로 무관 실패면 기록.
- [ ] **Step 3: git-diff allowlist 이탈 감시**
Run: `git diff --name-only main...HEAD`
Expected: 아래 집합의 부분집합만 (+ launcher 는 A1 Step 6 채택 시에만):
```
.agents/hooks.json
CLAUDE.md
AGENTS.md
.codex/agents/README.md
.agents/plugins/wiki-superpowers/README.md
.claude/agents/wiki-doc-author.md
.agents/plugins/wiki-superpowers/agents/wiki-doc-author.md
.codex/agents/wiki-doc-author.md
.codex/agents/wiki-doc-author.toml
.agents/agents/wiki-doc-author/agent.json
docs/superpowers/specs/2026-07-14-harness-correctness-sweep-design.md
docs/superpowers/plans/2026-07-14-harness-correctness-sweep.md
```
이 집합 밖 파일이 나오면 STOP + 사유 확인 (무관한 dirty 파일이 stage 됐는지 점검). 임시 진단/테스트 파일 잔존 0 확인.
- [ ] **Step 4: verdict 판정 (spec §8)**
- A2·A3·A4: 각 assert PASS + 구문 통과 + 패리티 표 전 PASS → **DONE**.
- A1: Antigravity firing 관측됨 → DONE / 직접 실행만 확인 → **PARTIAL** / 계약·구문 불일치 → BLOCKED.
- 전체: allowlist 한정 + pytest PASS 확인.
- [ ] **Step 5: 사용자 보고**
Status(A1 PARTIAL/DONE, A2·A3·A4 DONE) + 변경 파일 + A1 E2E 잔여(사용자 Antigravity 확인 필요 여부) + 다음 후보(백로그 B1~B4) 요약. 커밋은 브랜치에 있음 — merge/PR 여부는 사용자 결정.
---
## 완료 기준 요약 (spec §8 대응)
- **A1:** hooks.json 4개 command portable 수정 + JSON OK + (E2E firing 확인 시 DONE, 아니면 PARTIAL). 새 절대경로 0.
- **A2:** "AGENTS.md 중복 불필요" 0건, Antigravity 단정 없음, "운영-규칙 SSOT" 표기.
- **A3:** 5표현 잔존-문구 0 + 새 write-set 계약 존재 + category 8 + validator 비고정 + JSON/TOML OK + 패리티 표 PASS + migrate 계약 불변.
- **A4:** live 문서 stale 0 + 실측값 일치 + 두 "10" 디렉터리 구분 + 스냅샷 명시. historical 미변경.
- **전역:** `git diff --name-only` allowlist 한정 + `pytest .claude/hooks` PASS + 임시파일 잔존 0.