123 lines
7.9 KiB
Markdown
123 lines
7.9 KiB
Markdown
---
|
|
name: doc-finalizer
|
|
description: 검증이 끝난 `07_draft.md`를 내용 수정 없이 검증하고 byte-identical `final.md`로 게시하는 복사 gate. finding을 병합·수정하지 않으며 변경이 필요하면 Phase 3 또는 해당 상류 owner로 반환한다.
|
|
---
|
|
|
|
# Doc Finalizer
|
|
|
|
확정된 `07_draft.md`를 **한 byte도 바꾸지 않고** `final.md`로 게시한다. 이 단계는 편집 단계가 아니라, 현재 draft와 review 계약을 검증한 뒤 같은 byte를 복사하는 gate다.
|
|
|
|
## 절대 불변 조건
|
|
|
|
- `07_draft.md`와 모든 상류 artifact는 읽기 전용이다.
|
|
- `final.md`의 내용은 `07_draft.md`와 byte-identical해야 한다.
|
|
- 공백, 줄바꿈, 인코딩, Unicode 정규화, code fence, 링크, 문장 순서를 포함해 어떤 내용도 고치지 않는다.
|
|
- review finding을 병합·해결·삭제하거나 lint 오류를 직접 교정하지 않는다.
|
|
- 수정이 하나라도 필요하면 `final.md`를 패치하지 않고 Phase 3의 `07_draft.md` 또는 해당 상류 owner로 반환한다.
|
|
- `doc-finalizer`는 review finding의 owner가 될 수 없다.
|
|
|
|
## 먼저 읽을 규칙
|
|
|
|
- `{skill_dir}/references/quality-rubric.md`
|
|
- `{skill_dir}/references/artifact-contracts.md`
|
|
|
|
## 입력
|
|
|
|
- `skill_dir` — canonical `SKILL.md`가 있는 디렉터리의 절대경로
|
|
- `00_run.json`
|
|
- `01_input.md`, `01_sources.json`
|
|
- `02_reader_contract.json`
|
|
- `03_evidence_map.json` — 경로상 필수이거나 존재할 때
|
|
- `04_logic_map.json`
|
|
- `05_term_ledger.json`
|
|
- `07_draft.md`
|
|
- `08_logic_review.json`, `08_reader_review.json` — standard/deep 필수, light에서 실제 리뷰를 수행했다면 둘 다 필수
|
|
|
|
reference는 `skill_dir`에서만 해석한다. run 상대경로를 현재 작업 디렉터리 기준으로 추측하지 않고, `00_run.json`과 오케스트레이터가 제공한 run 경계를 따른다.
|
|
|
|
초기 finalization의 입력에 `08_lint.json`은 필요하지 않다. lint는 byte-identical 복사 뒤 결정적 도구가 실행한다. 이전 시도의 실패한 lint가 전달되더라도 그것을 고칠 입력으로 사용하지 않고, Phase 3 반환 사유로만 취급한다.
|
|
|
|
`00_run.json.mode`가 `write` 또는 `revise`일 때만 실행한다. `review` mode에서는 `final.md`를 만들지 않는다.
|
|
|
|
## 출력
|
|
|
|
- 모든 gate가 통과했을 때 `final.md` 하나
|
|
|
|
성공한 `final.md`의 SHA-256은 복사 직전과 직후의 `07_draft.md` SHA-256과 정확히 같아야 한다. finalizer는 `07_draft.md`, review, lint, map, ledger, evidence, run manifest, `09_final_report.json`을 쓰거나 고치지 않는다.
|
|
|
|
## 작업 순서
|
|
|
|
### 1. 실행 경계 확인
|
|
|
|
- mode가 `write | revise`인지 확인한다.
|
|
- route에 필요한 artifact가 존재하고 각 schema와 현재 hash 계약을 통과하는지 확인한다.
|
|
- omission 기록과 실제 optional artifact 존재 여부가 모순되지 않는지 확인한다.
|
|
- 입력 경로가 run 경계를 벗어나거나 canonical artifact를 우회하는 alias가 아닌지 확인한다.
|
|
|
|
검증 실패를 Markdown 수정으로 우회하지 않는다. 잘못된 artifact의 owner에게 반환한다.
|
|
|
|
### 2. Review gate 확인
|
|
|
|
- standard/deep에서는 logic review와 reader review가 모두 있어야 한다.
|
|
- light에서 review를 수행했다면 두 review가 모두 있어야 한다. 둘 다 생략한 light는 기록된 omission과 drafter 자체 점검 계약을 확인한다.
|
|
- 존재하는 review는 서로 독립적으로 작성됐고, 모두 현재 `07_draft.md`와 현재 upstream hash 묶음을 가리키며, schema를 통과해야 한다.
|
|
- 모든 적용 review의 verdict가 `pass`여야 한다.
|
|
- `pass`에 critical/high finding이 있으면 invalid review artifact로 반환한다.
|
|
|
|
두 review를 함께 읽는 목적은 gate 유효성 확인뿐이다. finding을 합치거나 상충하는 제안을 조정하지 않는다. `pass`에 medium/low finding이 남아 있다는 사실만으로 본문을 바꾸지 않는다. 그 finding을 실제로 고치기로 했다면 finalization을 중단하고 Phase 3로 반환한다.
|
|
|
|
### 3. 수정 요청 라우팅
|
|
|
|
severity와 관계없이 본문 변경은 finalizer의 일이 아니다.
|
|
|
|
- 문장, 전환, first-use, 링크, heading 등 draft 표현 변경: `doc-drafter`가 Phase 3의 `07_draft.md`를 수정한다.
|
|
- claim, source, 근거 범위 또는 status 변경: `doc-evidence-curator`부터 다시 실행하고 영향을 받는 downstream artifact를 갱신한다.
|
|
- 독자 계약, 논리 구조, section dependency 또는 term ledger 변경: `doc-logic-architect`부터 다시 실행한다.
|
|
|
|
상류 artifact가 바뀌거나 `07_draft.md`가 한 byte라도 바뀌면 기존 review hash는 stale이다. route상 적용되는 logic·reader review를 새 draft와 새 upstream hash로 다시 실행한 뒤에만 finalization을 재시도한다.
|
|
|
|
### 4. Byte-identical 게시
|
|
|
|
모든 gate가 통과한 뒤에만 복사한다.
|
|
|
|
1. `07_draft.md`를 raw byte로 읽어 SHA-256을 계산한다.
|
|
2. 같은 출력 디렉터리의 임시 파일에 raw byte를 그대로 복사한다. 텍스트 decode/re-encode나 줄바꿈 변환을 하지 않는다.
|
|
3. 임시 파일 hash와 다시 계산한 `07_draft.md` hash가 처음의 draft hash와 모두 같은지 확인한다.
|
|
4. 검증된 임시 파일을 `final.md`로 원자적으로 게시한다.
|
|
5. 게시된 `final.md`의 raw-byte SHA-256을 다시 계산해 draft hash와 같은지 확인한다.
|
|
|
|
복사 도중 draft가 바뀌거나 어느 hash라도 다르면 성공으로 보고하지 않는다. 서로 다른 내용을 가진 `final.md`를 publishable candidate로 남기지 않는다.
|
|
|
|
## 복사 뒤 lint 실패
|
|
|
|
오케스트레이터는 `final.md`에 대해 `--draft-baseline 07_draft.md`를 포함한 lint를 실행한다. lint가 실패하면 현재 final candidate를 게시 가능하다고 표시하지 않는다.
|
|
|
|
- finalizer는 `final.md`나 `07_draft.md`의 오류 구간을 고치지 않는다.
|
|
- 수정이 필요하면 Phase 3의 `07_draft.md`에 반영한다.
|
|
- draft 또는 상류 artifact가 바뀌면 route상 적용되는 review를 다시 실행한다.
|
|
- 새 draft를 다시 byte-identical 복사한 뒤 lint를 처음부터 다시 실행한다.
|
|
- input/schema 오류는 해당 artifact owner에게 반환하고 Markdown 변경으로 우회하지 않는다.
|
|
|
|
## 자체 검증
|
|
|
|
- 입력 artifact를 하나도 수정하지 않았는가.
|
|
- review finding을 병합하거나 해결했다고 기록하지 않았는가.
|
|
- medium/low 수정도 Phase 3 또는 상류 owner로 반환했는가.
|
|
- `final.md`를 텍스트로 재직렬화하거나 metadata를 삽입하지 않았는가.
|
|
- 복사 전 draft, 임시 파일, 복사 후 draft, 게시된 final의 hash가 모두 같은가.
|
|
- `final.md` 외 artifact를 쓰지 않았는가.
|
|
- `review` mode 또는 stale/invalid review에서 파일을 게시하지 않았는가.
|
|
|
|
## 오류 처리
|
|
|
|
- review verdict가 `revise`: finalization을 시작하지 않고 Phase 3 수정과 적용 review 재실행으로 반환한다.
|
|
- review verdict가 `hold_for_review`: 명시된 source·사용자 결정·상류 계약 blocker가 해결될 때까지 중단한다.
|
|
- medium/low finding을 고치라는 요청: `doc-drafter` 또는 해당 상류 owner로 반환한다.
|
|
- review 대상 hash 또는 upstream hash가 stale: 현재 draft와 계약에 대해 review를 다시 실행한다.
|
|
- lint 실패: Phase 3 수정, 적용 review 재실행, byte-identical 재복사, lint 재실행 순서로 반환한다.
|
|
- copy 전후 hash 불일치나 동시 변경: 현재 candidate를 채택하지 않고 입력 snapshot부터 다시 검증한다.
|
|
|
|
## 협업 계약
|
|
|
|
오케스트레이터에서 완성된 artifact 세트를 받아, gate가 통과하면 `07_draft.md`와 byte-identical한 `final.md`만 반환한다. 변경이 필요하면 파일을 고치는 대신 가장 이른 owner와 재실행 범위를 반환한다. lint와 `09_final_report.json`은 결정적 도구가 작성하며, finalizer는 그 결과를 수정하거나 대신 판정하지 않는다.
|