--- description: "wiki 품질 검사 (과장/혼동/stale/누락). `--fix-plan` 으로 수정 계획 구조화" --- 사용자가 `/lint [--fix-plan] ` 를 입력하면 아래 절차를 수행한다. wiki 품질을 검사합니다. **대상:** [--fix-plan] (지정 안 하면 `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` — 형식: `-C`, `/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` 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 강화): 1. **1표 (본 플랫폼)**: `wiki-adversarial-reviewer` subagent 를 실행 (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 --out /tmp/lint-vote-codex.md cd scripts/deep-research && python3 -m deep_research.vote --backend antigravity \ --findings /tmp/lint-findings.md --context-files --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` 추가 실행으로 대체 (fallback 사다리) — 어느 표가 어느 엔진인지 funnel 로 보고 (no silent engine swap). 6. CRITICAL <5건이면 기본 N=1 (단일 패스) 유지. ## 로그 기록 `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 위험 항목은 절대 묶음 적용하지 않는다 — 개별 승인.