Files
document-haness/skills/technical-doc-flow/references/evidence-policy.md
T

154 lines
9.7 KiB
Markdown

# 근거 정책
사실, 측정값, 실제 코드, 기술 결정을 다루는 문서는 이 정책을 따른다. 목표는 인용 수를 늘리는 것이 아니라, 중요한 주장을 추적 가능하게 만들고 관찰·추론·권고를 구분하는 것이다.
## 목차
- 주장 상태와 시간 범위
- 소스 선택과 근거 한계
- 보존 항목
- `01_sources.json``03_evidence_map.json`
- 경로별 동작, 실패 처리, 통과 조건
## 모든 주장에 상태를 부여한다
각 주장에는 안정적인 `id`, 허용 상태 하나, 문서 결론을 지탱하는지 나타내는 `load_bearing` boolean을 부여한다.
| status | 뜻 | 게시 조건 |
| --- | --- | --- |
| `source_backed` | 인용한 소스가 주장을 직접 뒷받침한다. | 정확한 source ID와 그 안의 유효 위치를 함께 사용한다. |
| `observed` | 특정 입력 또는 환경에서 직접 확인했다. | 확인한 source와 위치, 관찰 범위를 밝히고 일반화하지 않는다. |
| `measured` | 재현 가능한 측정이 뒷받침한다. | source 위치, 방법, 환경, 결과를 함께 둔다. |
| `derived` | 식별된 전제에서 주장을 도출했다. | 전제와 추론 관계를 드러낸다. |
| `recommended` | 문서가 결정 또는 미래 상태를 권한다. | 현재 사실과 구분해 표시한다. |
| `assumption` | 진행을 위해 검증되지 않은 전제를 둔다. | 전제와 영향을 명시하고 사실처럼 쓰지 않는다. |
약한 근거에 맞추려고 주장 문구를 교묘하게 바꾸지 않는다. 근거가 허용하는 범위로 주장을 좁히거나 공백을 보고한다. 근거 없는 사실 주장을 `assumption`으로 바꾸기만 해서 게시하지 않는다.
## 시간과 확실성을 분리한다
혼동 가능성이 있는 문장은 다음 범위를 문장 자체에서 드러낸다.
- `current`: 이름 붙인 버전이나 환경에서 현재 관찰한 상태
- `historical`: 명시한 과거 날짜나 버전의 상태
- `recommended`: 문서가 선호하는 결정
- `conditional`: 나열한 선행 조건에서만 성립하는 상태
- `hypothetical`: 관찰이 아닌 설명용 가정
- `future`: proposed, approved, in progress, planned 중 정확한 상태
예시 설정과 샘플 코드를 현재 시스템 동작의 증거로 사용하지 않는다.
## 1차 소스와 고정된 버전을 우선한다
다른 소스가 주장 자체의 대상인 경우를 제외하고 다음 순서로 선택한다.
1. 대상 시스템의 실행 결과, 소스 코드, 설정, 테스트, 버전 관리 자료
2. 공식 명세, 제품 문서, 표준, 릴리스 노트
3. 유지관리자가 작성한 설계 기록과 이슈 논의
4. 신뢰할 수 있는 2차 설명
바뀔 수 있는 소스에는 version, commit, date, environment, retrieval time 중 가능한 값을 기록한다. claim에서는 `source_ids`만 적고 끝내지 않고 `source_locations``{source_id, locator}`로 파일과 줄, section anchor, query와 row, command와 output slice처럼 가장 작은 유효 위치를 가리킨다. 런타임이 지원하면 content hash도 기록한다.
## 근거의 한계를 함께 쓴다
각 claim은 다음 두 가지를 분리한다.
- `statement`: 실제로 주장하는 정확한 명제
- `does_not_support`: 연결된 소스나 관찰이 허용하지 않는 인접 결론
소스 하나가 여러 주장을 지원하거나, 주장 하나가 여러 소스를 필요로 할 수 있다. 관계를 ID로 보존한다. 한 문단 끝의 인용 하나가 문단의 모든 문장을 자동으로 뒷받침하지는 않는다.
검증 블록에서 `proves``does_not_prove`를 사용하는 경우, claim의 `statement``does_not_support`보다 범위를 넓히지 않는다.
## 정확성 민감 항목을 보존한다
기초 소스가 정정되지 않는 한 다음을 임의 변경하지 않는다.
- 숫자·범위·단위 조합, 임계값, 날짜, 버전, 개수와 그 주변 의미 연결
- fenced·indented code block 전체, inline code 식별자·명령·플래그·인수, API path, header, status code, config key, environment variable
- 큰따옴표·blockquote 인용과 http·https·ftp·ftps·file·mailto·ssh·git 절대 URI·Markdown link/citation target
- class, function, package, field, table, topic, queue, error identifier
- 요구사항, 결정, 문서화된 예외
drafter는 옆에 쉬운 설명을 추가할 수 있지만, 정규화·반올림·개명·수정·현대화를 몰래 해서는 안 된다. 오류가 의심되면 review finding으로 남긴다.
## `01_sources.json`
이 파일은 오케스트레이터가 모든 route에서 만드는 source registry이며 evidence curator에게는 읽기 전용이다. source가 없으면 유효한 빈 목록을 사용한다. 각 항목은 스키마가 요구하는 `id`, `path`, `sha256`과 snapshot 메타데이터를 가진다. source-level `locator``version`은 입력 수집기가 실제로 제공했고 schema가 허용할 때만 선택적으로 기록한다. claim을 뒷받침하는 구체적 위치는 이 registry가 아니라 `03_evidence_map.json.claims[].source_locations`에 반드시 기록한다.
```json
{
"id": "SRC-001",
"role": "source",
"path": "src/test/.../ArchitectureTest.java",
"resolved_path": "/absolute/path/src/test/.../ArchitectureTest.java",
"size_bytes": 1234,
"sha256": "0000000000000000000000000000000000000000000000000000000000000000"
}
```
실제 필드명은 `{skill_dir}/schemas/sources.schema.json`을 따른다. 이 schema가 claim별 locator를 요구한다고 해석하지 않는다. 접근할 수 없는 소스를 읽었다고 표시하거나 누락 메타데이터를 만들어 내지 않는다.
## `03_evidence_map.json`
필수 최상위 필드는 `schema_version``claims`다.
```json
{
"schema_version": "1.0",
"claims": [
{
"id": "CLM-001",
"statement": "이름 붙인 테스트가 선언된 모듈 의존 규칙을 검사한다.",
"status": "source_backed",
"load_bearing": true,
"source_ids": ["SRC-001"],
"source_locations": [
{
"source_id": "SRC-001",
"locator": "ArchitectureTest.java:42-57"
}
],
"does_not_support": [
"이 테스트가 reflection 또는 생성된 의존까지 발견한다.",
"모든 runtime path가 이 규칙을 따른다."
]
}
]
}
```
각 claim에는 `id`, `statement`, `status`, `load_bearing`, `source_ids`, `source_locations`, `does_not_support`가 필요하다. `source_locations`의 각 항목은 정확히 `source_id`와 비어 있지 않은 `locator`만 가진다. status는 `source_backed`, `observed`, `measured`, `derived`, `recommended`, `assumption` 중 하나다. 사용 위치는 `04_logic_map.json.sections[].claim_ids`에서 연결한다.
- `source_backed`, `observed`, `measured``source_ids``source_locations`가 모두 비어 있지 않아야 한다.
- `source_locations[].source_id`의 집합은 `source_ids`의 집합과 정확히 같아야 한다. 모든 source ID에는 하나 이상의 구체적 locator가 있어야 하며, 목록 한쪽에만 있는 ID나 중복 `{source_id, locator}` 쌍은 허용하지 않는다.
- `derived`, `recommended`, `assumption`도 필수 필드인 `source_locations`를 가지며 직접 소스를 쓰지 않으면 유효한 빈 배열로 둔다. source를 연결했다면 두 필드의 ID 집합 일치 규칙은 그대로 적용한다.
- `derived``premise_ids`로 이미 등록된 claim을 하나 이상 연결한다. 등록된 근거 전제가 없으면 `derived`로 분류하지 않는다.
- `recommended`, `assumption`은 독자가 상태를 바로 알 수 있도록 `label`을 사용한다.
- `load_bearing: true`인 사실형 claim은 source 또는 premise와 비어 있지 않은 `does_not_support` 경계가 hard gate다.
## 경로별 동작
- `light`: `01_sources.json`은 source 0건이어도 항상 존재한다. `03_evidence_map.json`은 생략할 수 있다. 생략해도 citation이나 사실을 만들지 않고 검증하지 않은 범위를 초안에 표시한다.
- `standard`: 두 근거 artifact가 필요하다. load-bearing claim과 정확성 민감 항목을 모두 감사한다.
- `deep`: standard에 version·staleness·중요 counterevidence·limitation 검사를 추가한다.
## 실패 처리
- 소스 접근 불가: locator를 보존하고 검증했다고 말하지 않는다.
- 소스 충돌: 충돌 명제와 범위를 기록한다. 거짓 합의로 합치지 않는다.
- 근거 stale: claim을 고정된 version 범위로 좁히거나 refresh를 요구한다.
- `load_bearing: true`인 사실형 claim 미지원: 그 공백을 자연스러운 산문으로 채우지 않고 run을 `hold_for_review`로 둔다.
- secret 또는 personal data 포함: 민감 내용을 복사하지 않고 안전한 pointer와 redacted description만 사용한다.
## 근거 통과 조건
다음을 모두 만족해야 한다.
- `source_backed`, `observed`, `measured` claim이 비어 있지 않은 `source_ids`와 구체적인 `source_locations`로 추적된다. `derived` claim은 등록된 `premise_ids`로 추적할 수 있다.
- 모든 claim에서 `source_ids``source_locations[].source_id`의 집합이 정확히 대응한다.
- `load_bearing: true`인 사실형 claim을 source 위치 또는 명시된 전제로 추적할 수 있고 `does_not_support`로 경계를 확인할 수 있다.
- current와 future, example과 observation을 구분할 수 있다.
- fenced·indented code block, inline code 식별자·명령·플래그·인수, http·https·ftp·ftps·file·mailto·ssh·git 절대 URI·Markdown link/citation target, 숫자·범위·단위·날짜·버전의 의미 연결, 큰따옴표·blockquote 인용이 원본과 일치한다.
- 모든 claim이 확대 해석하면 안 되는 범위를 `does_not_support`로 밝힌다.