Files

169 lines
12 KiB
Markdown

---
description: wiki 품질 검사 (과장/혼동/stale/누락). `--fix-plan` 으로 수정 계획 구조화
argument-hint: [--fix-plan] <wiki 경로 또는 비워두면 전체>
disallowed-tools: NotebookEdit, WebSearch, WebFetch
---
wiki 품질을 검사합니다.
**대상:** $ARGUMENTS (지정 안 하면 `wiki/` 전체)
## 작업 절차 — 결정론 선행 (LLM 수기 재연 금지)
1. **구조 린터 전수 실행 (필수 1단계)**: `python3 .claude/hooks/wiki_structure_lint.py --all`
- 깨진 링크(`BROKEN_LINK`/`BROKEN_MD_LINK`) → **CRITICAL**, 섹션·frontmatter 누락(`MISSING_SECTION`/`MISSING_FRONTMATTER``UNMAPPED_SOURCE_TYPE`·`NAMING_VIOLATION`**WARN** 으로 그대로 흡수.
- 이 검사들을 LLM 이 수백 파일에서 수기로 재연하지 않는다 — D군의 해당 항목은 린터 출력이 SSOT.
2. **stale 결정론 집계**: `python3 .claude/hooks/wiki_structure_lint.py --stale`
- 90/30/14일 임계(C군)를 기계가 계산 — LLM 날짜 암산 금지. 출력(`STALE_90`/`RECHECK_30`/`NEEDS_CONFIRMATION_14`)을 WARN 으로 흡수.
3. **의미 검사** — 아래 체크리스트(A0/A/B/D 잔여/E/F + 투자 트리)에서 결정론 린터가 못 보는 *의미* 판정만 수행. 대상이 넓으면 `wiki-research-lane` 슬라이스 병렬 위임.
## 검사 항목
### A0. Claim Traceability
- [ ] `raw/official-docs/` 또는 `raw/company-tech-blogs/` 문서에 `## Claims Extracted` 가 없음
- [ ] Claim row 의 `Evidence quote``## 핵심 인용` 또는 원문 self-grep proof 와 연결되지 않음
- [ ] `raw/branch-notes/` 문서에 `## Decision Evidence Map` 이 없음
- [ ] Decision row 의 `Supporting Claims` 가 비어 있는데 `UNSUPPORTED_DECISION` 도 아님
- [ ] 존재하지 않는 Claim ID 를 참조함 (`BROKEN_CLAIM_REFERENCE` — 형식: `<SOURCE-SLUG-UPPER>-C<n>`, `/migrate-claims` §Claim ID 규약)
- [ ] 회사 기술 블로그 Claim 만으로 공식 best practice / 표준 / 공식 지원이라고 서술함
- [ ] `wiki/concepts/` 문서에 `## Claim-backed Knowledge` 가 없거나 FACT/INFERENCE 구분이 없음
### A1. 구현 가이드 추적성 (CLAUDE.md §15.5 — 3-rule)
branch-note 의 `## 구현 가이드 / Implementation Specification` 섹션에 대해:
- [ ] sub-section / row 에 Trace 표시(`D<n>` Decision ID + Claim ID reference) 누락 (R1 위반)
- [ ] 근거 raw 가 *원칙*만 권고하고 *detail*(메커니즘/명명/glob/algorithm)은 권고하지 않는 cell 에 `UNSUPPORTED_IMPL_DECISION` 라벨 + trade-off 한 줄 누락 (R2 위반)
- [ ] 본 branch 결정 범위 밖 cell 잔존 — 도메인 특화 또는 타 branch 결정 영역(security/persistence/HTTP-standard 등)이 이관 없이 남음 (R3 위반, `OUT_OF_BRANCH_SCOPE`)
### A. 출처 / 신뢰도
- [ ] 단정적 진술인데 Sources가 비어 있는 문장
- [ ] `source_type: company-tech-blog` 문서를 "공식 best practice"처럼 서술
- [ ] `source_type: llm-generated` 문서가 `confidence: high`로 설정됨
- [ ] 외부 URL이 raw에 발췌 보존 없이 링크만 있음
### B. 프로젝트 증거
- [ ] 프로젝트 관련 진술에 증거 등급 누락
- [ ] `documented-only` / `planned` 항목이 "구현했다"는 표현으로 작성됨
- [ ] `wiki/portfolio/` · `wiki/interview/` · `wiki/blog/` 문서에 `actually-implemented` / `locally-verified` / `prod-verified` **이외** 등급이 섞임
- [ ] 이력서/README용 문장에 `prod-verified` 또는 `locally-verified` 표기 없이 "운영", "프로덕션", "최적화" 같은 표현 사용
### C. Stale (→ 절차 2단계 `--stale` 출력이 SSOT — LLM 재계산 금지)
- [ ] `STALE_90` / `RECHECK_30` / `NEEDS_CONFIRMATION_14` 출력을 WARN 으로 보고
### D. 구조
- [ ] `wiki/llm-wiki.md` (vault MOC) 에 누락된 주요 허브 문서
- [ ] `index.md` 파일 존재 (named hub 룰 위반 — `rules/linking-rules.md` §12)
- [ ] `raw/`에만 존재하고 `wiki/`로 변환되지 않은 자료 (특히 `project-notes`, `errors`, `official-docs`, `company-tech-blogs`, `lectures`, `interviews`, `job-postings`, `blog-topics`)
- **예외 — 영구 보관 정책:** `raw/daily-notes/`, `raw/branch-notes/`는 그 자체가 wiki로 옮겨지지 않는 것이 정상. 두 경로는 "**promotable 항목이 적절히 추출되었는지**"만 검사:
- daily-note: `한 일` / `배운 점` / `트러블슈팅` / `면접·포트폴리오 옮길 만한 것`에 항목이 있지만 wiki에 대응 추출이 없는 경우 → WARN
- branch-note: `status_label``merged`인데 `완료 후 정리 → wiki 추출 대상``actually-implemented` / `locally-verified` 항목이 `wiki/projects/`에 없는 경우 → WARN
- `status_label``abandoned`인 branch-note는 추출 누락 검사 제외 (의도된 미추출)
- blog-topic: `wiki/blog/` 직접 변환 여부가 아니라 canonical 후보(`wiki/concepts/` 또는 `wiki/projects/`)와 상태(`captured`/`triaged`/`promoted`/`discarded`)가 명확한지 검사
- [ ] ~~깨진 `[[wikilink]]`~~ → 절차 1단계 `--all` 출력(`BROKEN_LINK`/`BROKEN_MD_LINK`)이 SSOT
- [ ] ~~frontmatter 필수 필드 누락~~ → 절차 1단계 `--all` 출력(`MISSING_FRONTMATTER`)이 SSOT
### E. Canonical 우회 검사 (§15 위반)
> 참고: 2026-06-10 부터 **쓰기 시점** 결정론 backstop 존재 — claim gate 가 파생 4종의 `## Sources` canonical 링크 + 원천 status 를 Write/Edit 시 차단한다. 본 검사는 *전수 retro* (훅 도입 전 문서·우회 경로 탐지) 용도로 유지.
>
> 경계: cross-doc 모순·위임 동기화(STALE_SUMMARY / CONTRADICTION / RESTATED / DANGLING·BARE 참조)는 `/sync` 의 영역 — 본 검사에서 중복 검사하지 않는다 (`rules/consistency-contract.md`).
파생 산출물(`wiki/interview/`, `wiki/portfolio/`, `wiki/blog/`)에 대해:
- [ ] 문서 Sources에 `[[wiki/concepts/...]]` 또는 `[[wiki/projects/...]]` 링크가 **하나도 없음** → CRITICAL (canonical 우회)
- [ ] `wiki/portfolio/` 문서가 `wiki/projects/`를 Sources에 두지 않음 (concepts 단독 출처) → CRITICAL
- [ ] 파생 문서의 원천 canonical 문서가 `status: reviewed | verified | published-ready`가 아님 → CRITICAL (status 미달 파생)
- [ ] Sources가 `[[raw/...]]` 또는 `[[raw/daily-notes/...]]` 또는 `[[raw/branch-notes/...]]`만 가리킴 (canonical 미경유) → CRITICAL
- [ ] 파생 문서가 원천에 없는 사실을 추가 진술 → WARN (`사실/추론/확인 필요` 분류 누락)
### F. 과장 표현
다음과 같은 표현이 있는지 grep:
- "최적화했다" / "성능을 X배 개선했다" → 측정값과 검증 방법이 같이 있는지 확인
- "운영 중" / "프로덕션에서" → `prod-verified` 등급이고 근거(로그/측정/릴리즈)가 있는지 확인. 없으면 CRITICAL.
- "설계했다" → 실제 구현 여부와 별개임을 명확히 했는지
- "도입했다" / "적용했다" → `actually-implemented` 이상 등급인지
## 출력 형식
검사 결과를 다음 4그룹으로 분류해 보고:
```
[CRITICAL] — 즉시 수정 필요 (과장, 출처 위반, 증거 등급 오류)
[WARN] — 검토 필요 (stale, 누락)
[INFO] — 참고 사항 (포맷, 링크 일관성)
[OK] — 통과
```
각 항목은 파일 경로와 라인 번호(가능하면)로.
Claim traceability 위반은 가능한 경우 `UNSUPPORTED_DECISION`, `BROKEN_CLAIM_REFERENCE`, `MISSING_CLAIMS_EXTRACTED` 같은 명명된 실패 모드로 보고.
## `--fix-plan` 모드 (선택)
`/lint --fix-plan [대상]` 으로 실행하면 위 검사 결과에 더해 **구조화된 수정 계획**을 만든다. 여전히 *무단 자동 수정은 하지 않는다* — 계획을 표로 제시하고 **사용자 승인 후에만** 적용한다. 보고→수동 판단→수정 요청→재검사의 왕복을 줄이는 것이 목적(자동수정 금지 원칙은 유지).
각 CRITICAL / WARN finding 을 다음 행으로 구조화:
| Finding | 필요한 수정 | 대상 파일:line | 위험 | 승인 필요? | 패치 범위 |
|---|---|---|---|---|---|
| `<실패 모드 + 한 줄>` | `<무엇을 어떻게 바꾸는가>` | `path:line` | low / med / high | yes / no | `<몇 줄 / 어느 섹션>` |
위험도·승인 기준:
- **high (승인 필요)**: 본문 의미 변경·삭제·문장 rewrite·파일 rename(wikilink 영향). 개별 승인.
- **med**: frontmatter 값 변경, 섹션 구조 추가. 묶음 승인 가능.
- **low (`승인 필요? = no`)**: 누락 frontmatter 키 추가, placeholder 보강, 깨진 링크 경로 수정. low 항목만 한꺼번에 적용 제안 가능.
- INFO 는 fix-plan 에 넣지 않는다(참고용).
- 적용 후에는 PostToolUse 구조 린터(`wiki_structure_lint.py`)가 자동 재검증한다.
제시 순서: ① fix-plan 표 출력 → ② "low 항목 N개 일괄 적용할까요? high 항목은 개별 확인" 질의 → ③ 승인된 항목만 Edit.
### CRITICAL ≥5건 → 적대 quorum 검증 (락인 전 필수)
CRITICAL finding 이 **5건 이상**이면 fix-plan 을 락인하기 전에 자기확증을 깬다. N=3 은 **cross-vendor 1+1+1** 로 구성한다 (`rules/extraction-tiering.md` T1 — 독립 실패 모드로 falsification 강화 + Claude 토큰 절감):
1. **Claude 1표**: `wiki-adversarial-reviewer` dispatch (findings 목록 + source corpus 경로 + workspace 컨텍스트) → ```wiki-verdict``` 블록을 `/tmp/lint-vote-claude.md` 로 저장.
2. **외부 2표**: findings 목록을 파일로 저장 후 (각 finding 에 ID 포함):
```bash
cd scripts/deep-research && python3 -m deep_research.vote --backend codex \
--findings /tmp/lint-findings.md --context-files <corpus 경로...> --out /tmp/lint-vote-codex.md
cd scripts/deep-research && python3 -m deep_research.vote --backend antigravity \
--findings /tmp/lint-findings.md --context-files <corpus 경로...> --out /tmp/lint-vote-agy.md
```
3. 결정론 합산:
```bash
python3 .claude/hooks/wiki_quorum.py /tmp/lint-vote-claude.md /tmp/lint-vote-codex.md /tmp/lint-vote-agy.md
```
4. per-finding 판정을 fix-plan 에 기계 반영 — **KILL** → fix-plan 에서 제외(오탐), **UNVERIFIED**(정족수 미달) → 적용 보류 + 사용자 보고, **DOWNGRADE** → 위험도 한 단계 하향, **KEEP** → 그대로. 임계값(≥2 REJECT=KILL)은 변경 금지 — `wiki_quorum.py` 가 SSOT.
5. **외부 표 생성 실패 시** (vote.py exit 1) 해당 표만 `wiki-adversarial-reviewer` 추가 dispatch 로 대체 (fallback 사다리) — 어느 표가 어느 엔진인지 funnel 로 보고 (no silent engine swap).
6. CRITICAL <5건이면 기본 N=1 (단일 패스) 유지.
## 투자 트리(invest-*) 추가 검사
- `raw/invest-daily/`·`raw/invest-research/` 의 수치/주장에 **출처 링크 누락** → 플래그.
- `wiki/invest-strategy/` 규칙 중 Supporting Claim 도 `UNSUPPORTED_DECISION` 라벨도 없는 행 → 플래그.
- `wiki/invest-strategy/` 에 ⚠️ 고지 섹션 누락 → 플래그.
- `wiki/invest-plan/` 항목 중 근거 링크 없는 종목/배분 → 플래그.
- 2026 ISA 확대안 등 **미확정 수치를 확정처럼 단정** → 플래그.
## 로그 기록
`wiki/log.md`에 한 줄: `YYYY-MM-DD HH:mm /lint — <대상> → CRITICAL n, WARN n, INFO n` (`--fix-plan` 이면 `→ fix-plan: 적용 a / 보류 b` 추가)
## 규칙
- **무단 자동 수정 금지.** 기본은 보고만. `--fix-plan` 도 *승인된 항목만* 적용하며 사용자 확인 없이 본문을 바꾸지 않는다.
- CRITICAL이 있으면 수정 제안을 같이 제시(`--fix-plan` 없이도).
- `--fix-plan` 의 high 위험 항목은 절대 묶음 적용하지 않는다 — 개별 승인.