init: llm-wiki-haness 하네스 설계
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
문서 간 모순·위임 동기화를 검사하고 수거합니다. (계약: `rules/consistency-contract.md` — Single-Owner + Reference-Only)
|
||||
|
||||
**대상:** {{arguments}} (지정 안 하면 `raw/branch-notes/` + `raw/project-notes/` 전수)
|
||||
|
||||
## 작업 절차 — 결정론 선행 (LLM 수기 재연 금지)
|
||||
|
||||
1. **결정론 검사기 (필수 1단계)**
|
||||
|
||||
```
|
||||
python3 .claude/hooks/wiki_consistency_check.py --all
|
||||
```
|
||||
|
||||
`--impact <slug>` 가 주어지면 대신 `python3 .claude/hooks/wiki_consistency_check.py --impact <slug>` (해당 노트의 결정을 참조하는 문서 역추적).
|
||||
- `--all`은 `.claude/hooks/wiki_graph_contract_check.py`의 v2 structured graph 검사를 이미 병합한다. 디버깅은 독립 CLI `python3 .claude/hooks/wiki_graph_contract_check.py --all`로 재현한다.
|
||||
- 신규 validation output 8종: `AMBIGUOUS_WIKILINK`(동명 basename은 full path 필수) + graph `MISSING_PROJECT_BINDING` / `MISSING_INHERITED_DECISION` / `STALE_INHERITANCE_REVISION` / `CONFLICTS_WITH_PROJECT_DECISION` / `UNDECLARED_OVERRIDE` / `MISSING_EXPECTED_EDGE` / `DUPLICATE_DECISION_OWNER`. Link ambiguity는 structure lint, graph 7종은 consistency `--all`이 각각 수거한다.
|
||||
- Parent edge는 child의 structured `project` / `parent_branch` 또는 `Branch Contract Packet`이 canonical이다. Hub의 `<!-- GENERATED: children:start -->`…`<!-- GENERATED: children:end -->` 블록은 reverse view로만 대조하며, `MISSING_EXPECTED_EDGE`는 batch/post-sync에서만 판정한다.
|
||||
- marker/table 없는 legacy 문서는 strict failure가 아닌 `LEGACY_GRAPH_CONTRACT` migration warning + skip으로 보존한다.
|
||||
- findings 를 그대로 흡수: `DANGLING_DECISION_REF` / `DANGLING_SECTION_REF` / `DUAL_OWNERSHIP` → **CRITICAL**, `BARE_DECISION_REF` / `BARE_OWNER_REF` → **WARN**.
|
||||
- 이 검사들을 LLM 이 수기로 재연하지 않는다 — 검사기 출력이 결정론 SSOT.
|
||||
|
||||
2. **typed contract 검사**
|
||||
|
||||
```
|
||||
python3 harness/runtime/typed_contract_check.py --root .
|
||||
```
|
||||
|
||||
owner/revision/import/delegation/projection findings를 별도 `typed findings`로 수거한다. 실패해도 의미 결과로 덮어쓰지 않으며 explicit blocking으로 통합한다.
|
||||
|
||||
2-b. **투영 drift · 레이아웃 · MOC · branch postflight (필수 — 위 두 검사가 보지 못하는 축)**
|
||||
|
||||
```
|
||||
python3 harness/runtime/contract_projection.py --check --root .
|
||||
python3 harness/runtime/layout_check.py --root .
|
||||
python3 harness/runtime/moc_indexer.py --check
|
||||
for f in raw/branch-notes/*.md; do
|
||||
python3 harness/runtime/branch_contract_check.py "$f" --postflight --root .
|
||||
done
|
||||
```
|
||||
|
||||
> **이 검사들이 `/sync` 에 없던 동안 무슨 일이 있었나** (2026-07-21~22 실측):
|
||||
> `branch_contract_check` 는 vault cutover 이후 심링크를 resolve 한 경로로 위치를 판정해
|
||||
> **모든 branch 를 거부**했고(status=ERROR), 아무도 그것을 돌리지 않아 `contract_packet_sha256`
|
||||
> drift 가 두 프로젝트 **82건** 쌓이는 동안 sweep 은 계속 `findings 0` 을 반환했다.
|
||||
> `contract_projection --check` 는 셀 정규화 버그로 깨진 코드스팬 15곳을 들고 있었고,
|
||||
> `moc_indexer --check` 는 hub reverse-view 3건이 낡은 상태였다.
|
||||
> 즉 "consistency + typed 통과 = 깨끗하다"는 성립하지 않는다 — 축들이 서로를 못 본다.
|
||||
>
|
||||
> 비용은 전부 합쳐 ~6.5초다(2026-07-22 실측: consistency 0.56s · typed 0.29s ·
|
||||
> projection 0.40s · layout 1.41s · structure lint 2.32s). 느려서 뺄 이유가 없다.
|
||||
|
||||
- `contract_projection` / `moc_indexer` 가 `DRIFT` 면 **수기로 고치지 말고** `--write` 로 재생성한다. 생성기가 SSOT 이므로 수기 수정은 다음 재생성에서 되돌아온다.
|
||||
- `layout_check` 의 `MIGRATION_LEGACY_EXTRA` / `INVALID_COMPATIBILITY_SYMLINK` 는 호환 심링크가 실파일로 대체됐다는 신호다(writer 가 정본 대신 링크를 덮어쓴 경우). 정본과 링크가 갈라진 split-brain 이므로 CRITICAL.
|
||||
- postflight 는 `GENERATED_REGION_DRIFT` / `CONFLICTS_WITH_PROJECT_DECISION` / `STALE_INHERITANCE_REVISION` / `INHERITED_DECISION_MISMATCH` 를 branch 단위로 판정한다. `status: ERROR` 는 "통과"가 아니라 **검사가 실행조차 못 했다**는 뜻이니 findings 0 으로 세지 말 것.
|
||||
|
||||
3. **팩킷 준비 (T0 결정론 발췌 — 0토큰, `rules/extraction-tiering.md`)**
|
||||
|
||||
```
|
||||
python3 .claude/hooks/wiki_consistency_check.py --packets [slug] > /tmp/sync-packets.md
|
||||
```
|
||||
|
||||
참조 엣지 양쪽(citing ±2줄 / owner D-row)의 맥락을 결정론 추출. auditor 는 corpus 대신 이 팩킷 파일을 **1차 입력**으로 소비한다 — 판결이 모호한 엣지만 원문 해당 라인을 Read.
|
||||
|
||||
4. **명시 참조 엣지 의미 대조 — `wiki-consistency-auditor` dispatch**
|
||||
|
||||
- 입력: 1단계 검사기 출력 + **팩킷 파일 경로**(`/tmp/sync-packets.md`) + **대조할 참조 엣지 목록** (엣지 = citing 문서 / owner 문서 / D-id·§-id + 양 노트 경로).
|
||||
- 기본 슬라이스: DANGLING / DUAL_OWNERSHIP 관련 엣지 + 사용자가 지정한 대상 경로의 엣지. **전수 대조는 엣지 수를 먼저 보고하고 사용자 확인 후에만.**
|
||||
- 엣지 **>20개면 슬라이스로 분할해 병렬 dispatch**.
|
||||
- 출력: 엣지별 `CONSISTENT` / `STALE_SUMMARY` / `CONTRADICTION` / `RESTATED_FOREIGN_DECISION` verdict (+ wiki-verdict/wiki-stats 블록).
|
||||
|
||||
5. **local/hub semantic certificate 수거 + impact audit**
|
||||
|
||||
- `semantic_certificate.py --root . --check`로 stale/missing certificate를 수거한다.
|
||||
- project 변경은 full `hub`, branch 변경은 `local + typed graph direct impact`로 `wiki-semantic-coherence-auditor`를 실행한다. direct impact는 imported owner/consumer, 직접 dependency, delegation 상대이며 sibling 전체는 포함하지 않는다.
|
||||
- `semantic_surface_extractor.py` → assertion → `semantic_candidate_builder.py` → verdict → proof → `semantic_audit.py validate` 순서를 지키고, `typed findings`, `edge-semantic findings`, `local-semantic findings`, `hub-semantic findings`를 서로 섞지 않고 집계한다.
|
||||
- hub `AMBIGUOUS_AUTHORITY`, 모든 `CONTRADICTION`, `RESTATEMENT_DRIFT`, hub dropped candidate는 fix 전까지 blocking이다.
|
||||
|
||||
6. **fix-plan 표** — `/lint --fix-plan` 과 동일 규율 (위험도·승인 필요·패치 범위):
|
||||
|
||||
| Finding | 필요한 수정 | 대상 파일:line | 위험 | 승인 필요? | 패치 범위 |
|
||||
|---|---|---|---|---|---|
|
||||
| `<실패 모드 + 한 줄>` | `<무엇을 어떻게 바꾸는가>` | `path:line` | low / med / high | yes / no | `<몇 줄 / 어느 섹션>` |
|
||||
|
||||
- **owner-우선 해소 원칙** (`rules/consistency-contract.md` §충돌 해소): 위임한 쪽(참조자)이 요약을 갱신한다. owner 본문을 참조자에 맞춰 고치지 않는다.
|
||||
- `RESTATED_FOREIGN_DECISION` → **"참조 + 1줄 요약으로 교체" 제안** (세부 내용은 owner 로 이관 또는 삭제를 명시).
|
||||
- **hub(project-note) vs branch 충돌은 항상 개별 승인** — 자동 적용 금지. 보통 branch 가 더 최신·구체 → "project-note 갱신 제안" 형태가 기본이나, 판정은 사용자 몫.
|
||||
- `BARE_DECISION_REF` / `BARE_OWNER_REF` 수정(wikilink 화)은 low 위험 — 묶음 승인 제안 가능.
|
||||
|
||||
7. **승인된 항목만 Edit**
|
||||
|
||||
- 재진술 수거 시 **기존 본문 의미 보존** — 세부 내용을 owner 로 이관했는지, 중복이라 삭제했는지 fix-plan 에 명시한 대로만.
|
||||
- high 위험(본문 의미 변경·hub 갱신)은 절대 묶음 적용 금지 — 개별 승인.
|
||||
- 적용 중 owner D-row 를 건드리면 PostToolUse 훅(`wiki_consistency_check.py --post`)이 역참조 충격을 비차단 알림 — 같은 세션에서 반영.
|
||||
|
||||
8. **재검사 + 로그 + 요약**
|
||||
|
||||
- 적용 후 `python3 .claude/hooks/wiki_consistency_check.py --all` 재실행. **루프 천장 2회** — 2회 후 잔여 findings 는 보고 후 종료 (다음 `/sync` 로 이월).
|
||||
- `wiki/log.md` 한 줄: `YYYY-MM-DD HH:mm /sync — <대상> → findings n (CRITICAL c / WARN w), 적용 a / 보류 b`
|
||||
- 최종 요약 funnel:
|
||||
|
||||
```wiki-stats
|
||||
agent: sync
|
||||
found: <검출 findings 수>
|
||||
processed: <적용 + 보류 수>
|
||||
dropped: <제외 수 + 사유>
|
||||
```
|
||||
|
||||
## 규칙
|
||||
|
||||
- **무단 자동 수정 금지.** fix-plan 의 *승인된 항목만* 적용하며 사용자 확인 없이 본문을 바꾸지 않는다.
|
||||
- `/lint` 와의 경계: 단일 문서 품질(과장/stale/canonical 우회)은 `/lint`, **cross-doc 모순·위임 동기화는 `/sync`** — 서로 중복 검사하지 않는다.
|
||||
- 검사기가 침묵하는 귀속 모호 케이스(인용자 자신의 DEM 에 있는 D-id)는 Layer 2 의미 대조가 판정한다 — 결정론 출력만으로 "깨끗하다" 단정 금지.
|
||||
|
||||
## Proof Artifact Contract (HARD)
|
||||
|
||||
finding/인용 draft는 exact UTF-8 quote 전부를 포함한 `proof-request/v1` JSON으로 조립한다. controller는 `python3 harness/runtime/proof_runner.py <proof-request.json> --repo-root . --output <report-dir>/proof-manifest.json`을 실행한다. exit 0, `schema_version: proof-runner-result/v1`, `status: PASS`, manifest `schema_version: proof-manifest/v1` 확인 전에는 workflow 완료를 선언하지 않는다.
|
||||
|
||||
보고서에는 `manifest_path`, `manifest_sha256`, `proof_count`, `pass_count`, `fail_count`를 기록한다. 실패 proof와 라인 정정은 전부, PASS proof는 대표 1~3개만 펼치고 나머지는 manifest를 참조한다. `fail_count != 0` 또는 count 불일치면 완료 판정을 차단한다.
|
||||
Reference in New Issue
Block a user