8.8 KiB
rules/consistency-contract — 문서 간 일관성 계약 (Single-Owner + Reference-Only)
rules/의 방법론 규칙. 문서 간 모순의 근원은 재진술(복제) 이다 — 같은 정책이 두 곳에 적혀 있으면 owner 쪽만 갱신될 때 모순이 생산된다. 본 계약은 재진술을 금지하고, 참조를 기계 검증하며, owner 변경을 역참조에 전파한다. 집행 3층: ① 결정론 검사기.claude/hooks/wiki_consistency_check.py(Layer 1) ②wiki-consistency-auditor의미 대조 (Layer 2) ③/sync수거 명령 (Layer 3).
원칙
| 원칙 | 내용 |
|---|---|
| Single-Owner | 모든 결정·관심사는 정확히 1개의 owner 문서를 가진다 — branch-note 의 Decision Evidence Map D<n> 행, 또는 project-note 의 §<n> 섹션. 같은 관심사를 두 branch 가 covered-here 주장하면 DUAL_OWNERSHIP. |
| Reference-Only | 타 문서는 owner 를 포인터 + 1줄 요약으로만 인용한다: [[raw/branch-notes/<owner>]] D<n> — <1줄 요약>. 정책 세부(임계값·메커니즘·예외 목록)의 재진술 금지 — 재진술은 owner 진화 시 낡은 복제본이 된다 (RESTATED_FOREIGN_DECISION). |
Project contract v2 에서는 project-note 의 Project Decision Registry 가 project-wide 결정 owner 다. ID 는 DEC-<PROJECT>-<DOMAIN>-NNN, revision 은 양의 정수이며 branch 참조는 항상 DEC-...@revision 으로 pin 한다. <PROJECT>·<DOMAIN> 은 uppercase kebab-case 다.
참조 형식 표준 (검사기 파싱 규약)
| 대상 | 형식 | 금지 |
|---|---|---|
| branch 결정 | [[raw/branch-notes/<slug>]] D<n> — wikilink 종료 후 같은 줄 100자 이내에 D<n> |
bare 슬러그 + D (예: feature-x-contract D7) → BARE_DECISION_REF |
| project 섹션 | [[raw/project-notes/<slug>]] §<n> — 같은 줄 100자 이내 |
부재하는 § 번호 → DANGLING_SECTION_REF |
| Coverage delegated owner | owner 셀에 wikilink 필수 | bare 이름 → BARE_OWNER_REF |
| project 결정 | DEC-<PROJECT>-<DOMAIN>-NNN@<positive-revision> + [[raw/project-notes/<slug>]] |
revision 없는 ID, 결정 상세 복제 |
| project Work Item | WI-<PROJECT>-NNN |
branch slug 만으로 project handoff 식별 |
D<n>토큰이 wikilink 에서 같은 줄 100자를 넘으면 검사기가 참조 엣지로 인식하지 못한다 — 링크 직후에 쓴다.- fenced code block 내부는 검사 대상 아님 (예시/템플릿 허용).
명명된 실패 모드
| 코드 | 층 | 의미 |
|---|---|---|
DANGLING_DECISION_REF |
결정론 (wiki_consistency_check.py) |
[[feature-B]] D17 인데 B 의 결정 표에 D17 부재 (B 실존 시 — 노트 부재는 BROKEN_LINK 몫) |
BARE_DECISION_REF |
결정론 | wikilink 없는 bare 슬러그 + D<n> — 기계 추적 불가 |
BARE_OWNER_REF |
결정론 | Coverage delegated 행의 owner 셀에 wikilink 없음 |
DUAL_OWNERSHIP |
결정론 | 같은 관심사(정규화 exact)를 두 branch 가 covered-here 주장 |
DANGLING_SECTION_REF |
결정론 | [[project-note]] §34 인데 해당 § 헤더 부재 |
STALE_SUMMARY |
의미 (wiki-consistency-auditor) |
참조의 1줄 요약이 owner D-row 의 현재 내용과 어긋남 (owner 진화 후 무통보 낡음) |
CONTRADICTION |
의미 | 두 문서가 같은 사안에 대해 양립 불가한 진술 |
RESTATED_FOREIGN_DECISION |
의미 | 타 owner 의 결정 세부를 포인터 없이/포인터와 함께 본문에 재진술 (복제) |
MISSING_PROJECT_BINDING |
결정론 | project-work-item의 slug가 WI row와 다르거나, branch-child의 parent·project·work_item 상속이 누락/불일치/순환임 |
MISSING_INHERITED_DECISION |
결정론 | Work Item Applies Decisions 의 pinned ref 가 branch inherits 또는 Contract Packet 에 없음 |
STALE_INHERITANCE_REVISION |
결정론 | branch 의 pinned revision 이 project registry 의 현재 decision revision 과 다르고 migration/override 로 설명되지 않음 |
CONFLICTS_WITH_PROJECT_DECISION |
의미 | branch-local 결정·적용 요약이 inherited project decision 과 양립 불가하며 유효한 override 도 없음 |
UNDECLARED_OVERRIDE |
결정론 + 의미 | project 결정과 다른 동작을 취하면서 overrides 와 Declared Overrides 표에 같은 pinned ref·이유·승인을 선언하지 않음 |
MISSING_EXPECTED_EDGE |
결정론 | project→Work Item→branch, Work Item dependency, decision→branch inheritance 중 registry 가 기대하는 edge 가 없음 |
DUPLICATE_DECISION_OWNER |
결정론 + 의미 | 같은 stable Decision ID 또는 같은 정규화 관심사를 둘 이상의 project/branch owner 가 소유함 |
DUPLICATE_BRANCH_ID |
결정론 | 같은 stable Branch ID를 둘 이상의 v2 branch가 선언함 |
Project → Work Item → Branch 상속 계약
- project-note 가
project_revision, Project Decision Registry, Work Item Registry 를 소유한다. - Work Item row 는 적용 결정을
DEC-...@revision으로 pin 하고 dependency 를WI-...로 가리킨다. - project 직접 자식 branch 는
/branch-from-project로 만들며 frontmatterproject·work_item·inherits·depends_on과## Branch Contract Packet을 가진다. - branch 는 inherited 결정의 상세를 복제하지 않는다. project wikilink + pinned ref + project summary + branch application 만 기록한다.
- branch-local 결정은
D<n>owner row 로 유지한다. project 결정을 refine 하면refines, 다르게 적용하면overrides와 Declared Overrides row 를 함께 기록한다. kind: project-work-item은 자기 slug가 Work Item Registry의branch slug와 exact match여야 한다.kind: branch-child는parent_branch가 필수이며 parent가 실존하고 cycle이 없어야 한다. child는 parent와 같은project·work_item을 상속하고, Work Item row의branch slug는 child가 아니라 parentproject-work-itemslug와 match한다.branch-child.inherits는 parent inheritance + Work ItemApplies Decisions의 superset이어야 한다. 제외는 같은 pinned ref가 frontmatteroverrides와 승인된 Declared Overrides row 양쪽에 선언된 경우만 허용한다.- 직접 branch의
id는 Work Item ID의WI-를BR-로 바꾼 값이다. child는BR-<PROJECT>-CHILD-<SHA256(slug) 앞 8자리>를 사용하며 rename 뒤에도 ID를 재사용한다. planned·backlog·proposed·documented-onlyWork Item은 branch 파일이 아직 없어도 expected-edge 실패로 보지 않는다.in-progress이상 상태에서만 branch 실존을 요구한다.
archive로 격리한 문서는 active graph 검사에서 제외한다. active project/branch는 v2 계약을 적용하며 legacy 문서가 발견되면 LEGACY_GRAPH_CONTRACT로 이관 대상임을 보고한다.
전파
owner 노트의 D-row (결정 표) 가 변경되면:
- PostToolUse 훅이 역참조 목록을 비차단 알림 — 쓰기는 이미 완료, 모델에 "이 결정을 참조하는 문서 N개" 정보만 전달.
- 같은 세션에서 참조 요약 갱신을 권장. 변경이 D-row 의 의미를 바꿨다면 참조 측 1줄 요약이 낡았을 가능성이 높다.
- 같은 세션에서 못 갱신한 항목은
/sync가 수거 (Layer 2 의미 대조 → fix-plan).
신규 참조 작성 시에는 PreToolUse 가 DANGLING_DECISION_REF/DANGLING_SECTION_REF 를 쓰기 차단 — owner 의 실제 Decision ID 를 확인하거나, 결정이 아직 없으면 owner 노트에 먼저 기록한다.
충돌 해소 우선순위
- owner 문서 우선 — 위임한 쪽(참조자)이 요약을 갱신한다. owner 본문을 참조자에 맞춰 고치지 않는다.
- hub(project-note) vs branch 충돌은 자동 적용 금지 — fix-plan 으로 사용자 판정. 보통 branch 가 더 최신·구체이므로 "project-note 갱신 제안" 형태가 기본이지만, 어느 쪽이 옳은지는 사용자가 정한다.
- 적용은 항상 승인 후 — 어떤 해소도 사용자 확인 없이 본문을 바꾸지 않는다.
retro 정책
- 기존 재진술·bare 참조는
/sync의 fix-plan 으로 점진 수거 — 일괄 자동 수정 금지. (2026-06 전수 dry-run: findings 190건 =BARE_DECISION_REF129 ·BARE_OWNER_REF60 · 실제DANGLING_DECISION_REF1건 — D14 오귀속.) - 신규 작성은 본 규약 준수 — 작성 시 참조 형식 가이드는 capture 계열(
/branch-spec등)이 본 문서를 참조한다.
한계 — 귀속 모호성
검사기는 외부 링크 후방 윈도의 D<n> 이 인용자 자신의 DEM 에도 존재하면 침묵한다 — 자기-결정 언급일 수 있기 때문 (실코퍼스: "X 에 의존 — 우회(D13)" 의 D13 이 인용자 자신의 D13). 따라서 결정론 층은 이런 케이스의 오귀속을 잡지 못하며, 의미 귀속 판정은 Layer 2 wiki-consistency-auditor 의 몫이다.