init: document-haness 하네스 설계

This commit is contained in:
DongHyeonka
2026-07-24 13:58:08 +09:00
parent d6f78f92a0
commit c39406bbdd
219 changed files with 7010 additions and 20052 deletions
+130
View File
@@ -0,0 +1,130 @@
# Architecture
## 1. 설계 목표
ClariDoc의 핵심 목표는 생성 모델의 문장 능력보다 **정보 구조, 근거 추적, 검토 독립성, 재현 가능한 품질 판정**을 상위 제어 계층에 두는 것이다.
설계 원칙:
1. **Contract before prose**: 초안보다 브리프와 문서 유형 계약을 먼저 검증한다.
2. **Reader-question chain**: 각 절은 하나의 독자 질문에 답한다.
3. **Deterministic minimums**: 모델이 놓치기 쉬운 형식·안전·인용 조건은 코드로 검사한다.
4. **Role separation**: 작성자와 리뷰 관점을 분리한다.
5. **Evidence boundary**: 출처의 사실과 모델의 설명·추천을 구분한다.
6. **Auditability**: 원문 응답, 정규화 입력, 결과, 이벤트, 해시를 보존한다.
7. **Safe degradation**: planner가 실패하면 결정적 구조로 폴백하지만 writer 실패는 숨기지 않는다.
## 2. 구성요소
```text
models.py 입력/출력 계약과 검증
structures.py 문서 유형별 필수 section intent와 순서
prompts.py planner/writer/reviewer/reviser 출력 계약
providers/ Codex, Claude, Antigravity, Mock 어댑터
lint.py 모델과 독립적인 Markdown/논리 프록시 검사
pipeline.py 단계 실행, 수정 루프, 품질 게이트, 감사 산출물
report.py 사람이 읽는 품질 보고서
cli.py init/validate/outline/lint/run/doctor 명령
```
## 3. 단계별 상태 전이
### 3.1 계약 입력
- `Brief`: 독자, 목표, 핵심 메시지, 범위, 비범위, 선행지식, 필수 주제, 버전 맥락, 금지 주장
- `SourcePack`: 출처 식별자와 출처가 실제로 지지하는 사실 단위
- `PipelineConfig`: 각 역할의 provider, timeout, 옵션, 품질 게이트
입력은 정규화되어 `inputs/`에 기록된다.
### 3.2 결정적 기본 outline
`structures.py``document_type`에 따라 필수 intent를 만든다. 각 section은 다음 계약을 가진다.
```json
{
"id": "04-mechanism",
"intent": "mechanism",
"title": "해결 방식이 동작하는 과정",
"reader_question": "구성요소와 데이터 흐름은 어떻게 연결되는가?",
"purpose": "메커니즘을 단계적 인과 사슬로 설명한다.",
"must_include": ["구성요소", "데이터 또는 제어 흐름", "불변조건"],
"evidence_ids": ["S1"],
"transition_to_next": "다음 독자 질문으로 연결한다."
}
```
### 3.3 Planner 정교화
Planner는 section 제목, 질문, 목적, `must_include`, 근거 배치, 전환을 개선한다. `reconcile_outline`은 다음을 거부한다.
- 문서 유형 변경
- 필수 intent 삭제
- intent 중복
- 필수 순서 변경
- 존재하지 않는 source ID
Planner 실행 또는 JSON 파싱이 실패하면 기본 outline을 사용하고 경고를 기록한다.
### 3.4 Writer
Writer는 exact H1과 exact H2 순서를 지켜 전체 Markdown을 반환해야 한다. 브리프와 출처는 지시가 아닌 untrusted data로 경계 표시된다. Writer 실패는 대체 텍스트로 숨기지 않고 실행 오류로 종료한다.
### 3.5 결정적 린트
린터는 모델 응답과 독립적으로 구조, 형식, 절차, 안전, 근거 표식을 검사한다. 자연어 의미를 완전히 판단하지 않으며 **최소 품질 바닥**을 제공한다.
### 3.6 독립 리뷰
각 reviewer는 동일한 초안을 다른 실패 함수로 검사한다.
- logic: 전제→결론, 인과 단절, 모순, section 역할
- reader: 선행지식, 방향 감각, 점진 공개, 예시, scan path
- evidence: 출처 적합성, 지원되지 않은 확신, 버전 민감성
- operations: 절차 순서, 검증, 파괴적 조작, 복구, 관측
- editor: 문장·문단 초점, 용어, 중복
리뷰 응답은 고정 JSON 스키마로 파싱된다. 필수 reviewer가 실패하면 기본적으로 실행이 실패한다. `fail_on_reviewer_error: false`는 실패 리뷰를 blocker/0점으로 기록해 산출물을 남긴다.
### 3.7 품질 게이트와 수정
```text
model_mean = mean(review.score)
composite = lint.score * deterministic_weight + model_mean * model_weight
PASS = composite >= minimum_score
AND blockers <= max_blockers
AND errors <= max_errors
```
FAIL이고 수정 한도가 남으면 reviser가 lint와 모든 리뷰를 받아 전체 문서를 다시 작성한다. 수정된 초안은 동일한 린트와 리뷰를 처음부터 통과해야 한다.
## 4. 신뢰 경계
| 경계 | 신뢰 수준 | 처리 |
|---|---|---|
| pipeline config | 로컬 운영자가 승인한 코드 수준 설정 | command 실행 가능하므로 반드시 신뢰된 파일만 사용 |
| brief/source pack | 비신뢰 데이터 | prompt 내부에서 data로 구획, 지시 무시 명시 |
| model response | 비신뢰 출력 | JSON 파싱·계약 검증·lint·review 수행 |
| URL | 메타데이터 | 자동 방문/실행하지 않음 |
| final document | 검토 후보 | PASS여도 도메인 사실·코드 실행을 별도 검증 |
## 5. 실패 정책
| 단계 | 기본 실패 처리 | 이유 |
|---|---|---|
| planner | 결정적 outline 폴백 + 경고 | 구조의 안전한 기본값이 존재 |
| writer | 실행 중단 | 내용 없는 대체 초안은 유효하지 않음 |
| reviewer | 실행 중단 | 독립 검토가 구성 계약의 일부 |
| reviewer, fail-open 설정 | blocker/0점 리뷰로 기록 | 산출물 보존이 필요한 실험 환경 |
| reviser | 실행 중단 | 수정 실패를 이전 초안 통과로 위장하지 않음 |
| quality gate fail | final 산출물은 남기되 exit code 4 | 사람이 결함을 분석할 수 있도록 보존 |
## 6. 재현성과 감사
- provider 요청의 stage/provider/model/status/duration을 JSONL로 기록
- 각 모델의 raw response와 parsed JSON을 모두 보존
- 입력을 정규화해 실행 시점 계약을 고정
- 최종 산출물을 포함한 파일별 SHA-256 매니페스트 생성
- Mock provider로 외부 네트워크 없이 파이프라인 배선 재현
모델 자체의 비결정성까지 제거하지는 않는다. 운영에서 모델 ID, CLI/SDK 버전, 실행 날짜를 `version_context`, provider `model`, 별도 배포 메타데이터에 고정해야 한다.
+66
View File
@@ -0,0 +1,66 @@
# Extending ClariDoc
## 새로운 문서 유형
1. `DocumentType` enum에 값을 추가한다.
2. `STRUCTURE_SPECS`에 독자 질문 순서와 section intent를 정의한다.
3. 각 section에 title, reader question, purpose, must-include를 한국어/영어로 제공한다.
4. `lint.py`에 해당 유형의 최소 계약을 추가한다.
5. 모든 intent가 고유하고 최소 section 수를 만족하는 테스트를 추가한다.
6. Mock writer에 새 intent의 fixture body를 추가하거나 명시적 fallback을 검증한다.
새 유형을 만들기 전에 기존 유형의 하위 section으로 충분한지 확인한다. 유형이 늘수록 분류 실패 비용도 커진다.
## 새로운 lint rule
좋은 결정적 rule은 다음 조건을 만족한다.
- 모델 없이 같은 입력에 같은 결과
- 결함 위치와 수정 방향을 설명
- false positive가 관리 가능
- blocker/error/warning/info의 위험 수준이 명확
- 자연어 의미 전체를 안다고 가장하지 않음
`LintIssue`의 code prefix를 기존 범주에 맞춘다.
- `MD`: Markdown 무결성
- `STR`: 구조
- `AUD`: 독자/오프닝
- `READ`: 가독성 proxy
- `TYPE`: 문서 유형 계약
- `EVD`: 근거
- `SAFE`: 안전
- `VER`: 버전
- `LEN`: 길이
- `FIN`: 미완료 표시
## 새로운 reviewer role
1. `prompts.py``ROLE_GUIDANCE`에 실패 함수를 정의한다.
2. pipeline config reviewers에 role/provider를 추가한다.
3. 공통 9개 dimension을 유지하거나 조직용 dimension을 parser와 보고서에 명시적으로 확장한다.
4. 다른 reviewer와 중복되는 일반 교정이 아니라 독립적인 결함 탐지 관점을 제공한다.
예: accessibility, localization, API consistency, security threat modeling.
## 출처 자동 수집기
Core pipeline은 URL을 자동 방문하지 않는다. 수집기를 추가할 때는 별도 단계로 분리한다.
```text
retriever → immutable evidence snapshot → fact extractor → human/source-owner approval → SourcePack
```
최종 source pack에는 원문 snapshot hash, 추출 위치, 접근 날짜, 허용된 fact를 남기는 것이 바람직하다. 검색 결과 요약을 바로 source truth로 쓰지 않는다.
## 실행 가능한 코드 검증
코드 블록을 테스트하려면 document generation과 별도의 verifier를 둔다.
1. 언어 태그와 fixture를 추출한다.
2. 격리된 container/sandbox에서 실행한다.
3. expected output과 비교한다.
4. 결과와 로그를 evidence artifact로 저장한다.
5. 문서의 예시 section과 artifact hash를 연결한다.
문서 모델에게 “코드가 맞다”고 평가하게 하는 것만으로 실행 검증을 대체하지 않는다.
+168
View File
@@ -0,0 +1,168 @@
# Logic model for comprehensible technical documents
## 1. 문서는 질문 그래프다
좋은 기술 문서를 “서론-본론-결론”이라는 형식만으로 설명하면 부족하다. 실제 독자는 순차적으로 다음 질문을 해결한다.
```text
왜 읽어야 하는가?
정확히 무엇을 다루는가?
무엇을 이미 알아야 하는가?
핵심 답 또는 결과는 무엇인가?
그 답이 성립하는 이유와 메커니즘은 무엇인가?
구체적인 사례에서 어떻게 보이는가?
어떻게 확인하는가?
언제 실패하거나 선택하지 않아야 하는가?
그래서 무엇을 해야 하는가?
```
모든 문서가 이 질문을 동일한 비중으로 다루지는 않는다. 문서 유형은 **독자의 현재 상태와 목적**에 따라 필요한 질문 부분을 선택하고 순서를 최적화한 것이다.
## 2. 문서 유형을 섞을 때의 규칙
한 페이지에 여러 유형이 존재할 수 있지만 주된 목적은 하나여야 한다.
- Tutorial 안의 짧은 explanation은 현재 단계를 이해시키는 데 필요한 만큼만 둔다.
- How-to 안의 reference table은 절차 수행에 필요한 조회 표면으로 제한한다.
- Technical blog 안의 code example은 전체 API reference가 아니라 인과 관계를 보여준다.
- Reference 안의 장황한 배경 설명은 별도 explanation으로 분리한다.
- Troubleshooting 안의 fix는 확인된 cause branch에만 연결한다.
판정 질문:
> 이 부분이 독자의 현재 목표를 직접 전진시키는가, 아니면 다른 문서 유형의 목표를 새로 시작하는가?
후자라면 분리하거나 링크한다.
## 3. 논리 구조의 최소 단위
### Section contract
각 section은 다음을 가진다.
1. **Reader question**: 독자가 이 시점에 묻는 질문
2. **Purpose**: 이 절이 수행할 정보 작업
3. **Claim/answer**: 질문에 대한 명시적 답
4. **Support**: 근거, 메커니즘, 예시 또는 절차
5. **Boundary**: 답이 유효한 범위와 예외
6. **Transition**: 다음 질문이 왜 생기는지 연결
### Paragraph contract
문단은 보통 다음 순서를 사용한다.
```text
중심 문장 → 이유/근거 → 구체화/예시 → 다음 문장으로의 연결
```
문단이 두 개의 독립 결론을 갖거나, 첫 문장이 뒤의 내용을 예고하지 못하거나, 마지막 문장이 새 주제를 시작하면 분리 후보로 본다.
## 4. 이해를 돕는 인과 구조
기술 설명에서 목록만 나열하면 독자는 구성요소를 기억해도 시스템을 예측하지 못한다. 메커니즘 section은 다음 중 하나의 명시적 순서를 사용한다.
- 시간: 요청 전 → 요청 중 → 응답 후
- 데이터 흐름: 입력 → 변환 → 저장 → 출력
- 제어 흐름: 조건 → 분기 → 행동 → 상태 전이
- 장애 흐름: 트리거 → 증상 → 전파 → 완화 → 복구
- 결정 흐름: 제약 → 비교 기준 → 대안 평가 → 선택 → 수용 비용
각 화살표에는 “왜 다음 상태가 되는가”가 있어야 한다. 단순히 컴포넌트 이름을 이어 붙이지 않는다.
## 5. 점진 공개
독자가 세부사항을 이해하기 위한 구조를 먼저 제공한다.
1. 핵심 답/결과
2. 범위와 전제
3. 가장 단순한 모델
4. 정상 메커니즘
5. 완주하는 예시
6. 검증
7. 예외·실패·트레이드오프
8. 운영 세부사항
예외를 너무 일찍 넣으면 기본 모델을 형성하기 어렵고, 너무 늦게 숨기면 과도한 확신을 준다. 기본 모델을 제시한 직후 “어디까지 유효한가”를 명시하고, 상세 예외는 뒤에서 확장한다.
## 6. Worked example 계약
예시는 코드 조각의 존재가 아니라 **시작 상태부터 검증 결과까지의 연결**이다.
필수 요소:
- 초기 상태와 입력
- 각 단계의 행동 또는 상태 변화
- 단계의 이유
- 예상 관측
- 최종 결과
- 성공 기준
- 실패했을 때 되돌아갈 지점
초보 독자에게는 중간 추론을 더 많이 보이고, 숙련 독자용 문서에서는 자명한 단계를 줄인다. 브리프의 `prior_knowledge`가 이 깊이를 결정한다.
## 7. 근거와 주장 수준
문장은 다음 네 종류 중 하나로 분류할 수 있어야 한다.
| 종류 | 예 | 처리 |
|---|---|---|
| 관측 사실 | 특정 로그가 발생했다 | 출처·실험·측정 연결 |
| 일반 기술 사실 | 프로토콜 의미, API 계약 | 권위 있는 reference 연결 |
| 가정/가상 예시 | 설명을 위한 단순 모델 | 가정/예시임을 표시 |
| 권고/판단 | 이 조건에서는 A를 선택 | 기준·대안·비용을 공개 |
“관련된 출처”와 “그 주장을 지지하는 출처”는 다르다. Source pack의 `facts`는 허용된 주장 범위를 줄이는 역할을 한다.
## 8. 트레이드오프 구조
좋은 기술 글은 선택을 미화하지 않는다.
```text
선택한 접근
├── 얻는 것
├── 지불하는 비용
├── 대안
├── 선택 기준
├── 실패 조건
└── 선택하지 말아야 하는 상황
```
대안을 비교할 때는 같은 기준을 사용한다. 한 대안은 성능으로, 다른 대안은 구현 편의성으로만 설명하면 비교가 성립하지 않는다.
## 9. 절차 안전성
절차 문서의 단계는 다음 상태 머신으로 본다.
```text
PRECONDITION_CHECKED
→ CHECKPOINT_CREATED
→ CHANGE_APPLIED
→ EXPECTED_RESULT_OBSERVED
→ VERIFIED
```
어느 단계에서든 불일치하면 다음으로 진행하지 않고 `STOPPED → ROLLED_BACK → RECOVERY_VERIFIED`로 이동해야 한다. 파괴적 명령은 경고 문구만으로 충분하지 않으며 백업/복구점, 영향 범위, 확인 명령이 함께 있어야 한다.
## 10. 품질 평가 차원
모델 reviewer는 다음 차원을 각각 검사한다.
- `reader_goal_alignment`: 약속한 결과를 실제로 제공하는가
- `information_architecture`: 문서 유형과 section 역할이 맞는가
- `logical_flow`: 전제·인과·결론·전환이 끊기지 않는가
- `cognitive_load`: 선행지식에 맞고 세부사항이 점진적으로 공개되는가
- `evidence_traceability`: 확인 가능한 주장이 근거와 연결되는가
- `example_verifiability`: 예시가 끝까지 실행·검증 가능한가
- `scannability`: heading과 첫 문장만 읽어도 구조가 보이는가
- `operational_safety`: 절차·변경·실패·복구가 안전한가
- `completeness_and_limits`: 범위, 비범위, 예외, 트레이드오프가 있는가
한 차원의 평균이 전체 결함을 숨기지 않도록 blocker/error 개수를 점수와 별도로 게이트한다.
+155
View File
@@ -0,0 +1,155 @@
# Provider integration
## 공통 계약
모든 provider는 다음 인터페이스를 구현한다.
```python
Provider.generate(ProviderRequest) -> ProviderResponse
Provider.check() -> dict
```
`ProviderRequest``stage`, `prompt`, `workdir`, `metadata`를 가진다. `ProviderResponse`는 모델의 텍스트, provider/model 이름, 실제 command 또는 실행 메타데이터를 반환한다.
Provider는 초안의 의미를 해석하지 않는다. 호출·timeout·출력 수집만 담당하며 JSON/Markdown 계약 검증은 pipeline에서 수행한다.
## Codex
기본 command 개념:
```text
codex exec
--sandbox read-only
--skip-git-repo-check
[--model MODEL]
--output-last-message TEMP_FILE
-
```
프롬프트는 stdin으로 전달한다. `-`는 비대화형 입력을 의미하고, 마지막 메시지는 임시 파일에서 읽는다. 문서 생성은 로컬 파일 변경이 필요 없으므로 기본 sandbox를 read-only로 둔다.
설정 예:
```json
{
"provider": "codex",
"model": "",
"timeout_seconds": 300,
"options": {
"binary": "codex",
"sandbox": "read-only",
"skip_git_repo_check": true,
"extra_args": []
}
}
```
환경 변수 `CLARIDOC_CODEX_BIN`으로 실행 파일을 지정할 수도 있다.
조직 래퍼:
```json
{
"provider": "codex",
"options": {
"command": ["/trusted/path/company-codex-wrapper", "--batch"]
}
}
```
custom command는 stdout을 최종 응답으로 사용한다.
## Claude Code
기본 command 개념:
```text
claude -p --output-format text [--model MODEL] "Read the piped task..."
```
긴 프롬프트는 운영체제 argument 길이 제한을 피하기 위해 stdin으로 전달한다. 마지막 고정 query는 piped task의 출력 계약만 수행하도록 지시한다.
설정 예:
```json
{
"provider": "claude",
"model": "",
"timeout_seconds": 600,
"options": {
"binary": "claude",
"extra_args": []
}
}
```
환경 변수 `CLARIDOC_CLAUDE_BIN` 또는 신뢰된 `options.command`를 사용할 수 있다.
## Google Antigravity
Antigravity는 Python SDK를 사용한다.
```python
from google.antigravity import Agent, LocalAgentConfig
config = LocalAgentConfig(**options["config"])
async with Agent(config) as agent:
response = await agent.chat(prompt)
text = await response.text()
```
설치:
```bash
python -m pip install -e '.[antigravity]'
```
설정 예:
```json
{
"provider": "antigravity",
"model": "",
"timeout_seconds": 300,
"options": {
"config": {}
}
}
```
`model`이 지정되고 `options.config`에 model이 없으면 하네스가 config 인수로 전달한다. SDK 버전에 따라 지원 인수가 다를 수 있으므로 잘못된 config는 명시적 오류로 종료한다.
SDK가 로컬 환경을 기준으로 동작하므로 provider는 실행 중 임시로 run directory를 current working directory로 사용한다. 프로세스 전체 cwd가 공유 상태이므로 lock으로 직렬화한다.
## Mock
Mock은 외부 모델이 아니다. 다음을 위한 결정적 fixture다.
- planner JSON 계약 검증
- writer Markdown 배선 검증
- review JSON 파싱 검증
- revision loop 및 산출물 테스트
- CI에서 네트워크·인증 없이 회귀 테스트
Mock 점수는 실제 품질 판단으로 사용하면 안 된다.
## `doctor`
```bash
claridoc doctor --config config/pipeline.multi-agent.example.json --json
```
- Codex/Claude: 실행 파일 경로 존재 확인
- Antigravity: Python module import 가능 여부 확인
- Mock: 항상 available
`doctor`는 로그인·권한·quota·실제 모델 응답까지 확인하지 않는다. 그것은 live invocation에서만 확인된다.
## Provider 추가
1. `src/claridoc/providers/``Provider` 구현을 추가한다.
2. stdout/SDK 응답을 문자열로 반환하고 timeout과 오류를 `ProviderError` 계열로 변환한다.
3. `registry.py`에 이름을 등록한다.
4. command/SDK를 가짜 구현으로 대체한 단위 테스트를 작성한다.
5. 인증 비밀은 config나 event log에 넣지 않는다.
6. 모델 출력 계약은 provider가 아니라 `prompts.py`와 pipeline parser에서 유지한다.
+110
View File
@@ -0,0 +1,110 @@
# Security and trust model
## 보호 대상
- provider 인증 정보와 로컬 계정
- 실행 호스트의 파일·명령·네트워크 권한
- 비공개 brief, source pack, draft
- 출처 진실성과 최종 문서 정확성
- 품질 게이트의 무결성
## 위협과 완화
### 1. Source/brief prompt injection
위협: title, fact, note, URL, draft 안에 “이전 지시를 무시하라” 같은 문장이 들어간다.
완화:
- 모든 prompt에서 입력 블록을 명시적으로 untrusted data로 선언
- 출력 스키마와 stage 역할을 입력 블록 밖에 정의
- planner의 구조 변경을 코드로 검증
- reviewer 결과도 JSON 파싱과 severity 계약으로 제한
- 최종 출력에 결정적 린트와 독립 리뷰 적용
잔여 위험: 언어 모델이 경계를 무시할 수 있다. 고위험 입력은 별도 sanitization, 제공자 정책, 인간 검토가 필요하다.
### 2. Command injection
위협: provider command가 외부 입력으로 조작된다.
완화:
- subprocess는 shell 없이 argument list로 실행
- brief/source 값을 command에 삽입하지 않고 stdin으로 전달
- `options.command`는 로컬 운영자가 승인한 config만 허용한다고 문서화
- 인증 비밀을 command line에 넣지 않음
잔여 위험: 악의적인 pipeline config 자체는 임의의 로컬 executable을 실행할 수 있다. config를 코드와 같은 신뢰 수준으로 관리해야 한다.
### 3. 모델의 파일/명령 부작용
위협: 에이전트 도구가 파일을 수정하거나 command를 실행한다.
완화:
- Codex 기본 sandbox `read-only`
- 작성 prompt는 파일 수정이나 shell 사용을 요구하지 않음
- Claude는 print mode 텍스트 출력을 사용
- Antigravity에는 문서 생성 prompt만 전달
잔여 위험: provider 자체 설정이나 조직 wrapper가 더 넓은 권한을 부여할 수 있다. 최소 권한과 격리 환경을 별도로 적용한다.
### 4. 근거 세탁과 허위 인용
위협: 모델이 관련만 있는 출처를 주장 근거처럼 붙이거나 source ID를 지어낸다.
완화:
- source pack에 출처가 지지하는 `facts`를 명시
- 존재하지 않는 source ID를 error로 처리
- evidence reviewer가 claim-marker fit를 검사
- 원문 model response와 source pack을 보존
잔여 위험: 하네스는 URL의 실제 내용이 `facts`와 일치하는지 자동 검증하지 않는다. source pack 작성자의 검증이 필요하다.
### 5. 위험한 절차
위협: 문서가 `rm -rf`, `DROP TABLE`, `kubectl delete`, `terraform destroy` 같은 명령을 안전장치 없이 제공한다.
완화:
- 대표 파괴 패턴을 blocker로 검사
- 주변에 경고, 백업/복구, 롤백 문맥 요구
- operations reviewer로 절차 상태 전이 검사
잔여 위험: 패턴 목록은 완전하지 않으며 도메인별 위험 명령을 모두 알 수 없다. 조직별 lint rule 확장이 필요하다.
### 6. 점수 조작
위협: 모델 reviewer가 근거 없이 높은 점수를 주거나 초안 내부 지시를 따른다.
완화:
- 결정적 lint 점수와 모델 평균을 혼합
- blocker/error 개수를 별도 gate
- 여러 provider와 역할을 분리 가능
- raw review를 보존
잔여 위험: 여러 reviewer가 같은 모델 계열·학습 편향을 공유할 수 있다. 고위험 문서는 인간 reviewer와 실행 가능한 검증을 추가한다.
### 7. 민감 정보 유출
위협: brief/source/draft가 외부 모델 제공자에 전송된다.
완화:
- 하네스가 실제로 전송하는 prompt를 raw artifact로 확인 가능
- provider별 조직 정책과 계정을 사용
- Mock으로 로컬 배선 테스트 가능
잔여 위험: live provider를 사용하면 해당 제공자의 처리 경계로 데이터가 이동한다. 비밀·개인정보·규제 데이터를 넣기 전에 조직 정책을 확인하고 필요한 경우 로컬 모델 adapter를 추가한다.
## 운영 권고
- pipeline config는 코드 리뷰와 버전 관리를 적용한다.
- provider model ID와 CLI/SDK 버전을 배포 메타데이터에 고정한다.
- run directory 접근 권한과 보존 기간을 정의한다.
- 고위험 문서는 source pack 작성자와 최종 승인자를 분리한다.
- 실제 명령과 코드는 sandbox/CI에서 실행해 결과를 source pack 또는 별도 evidence artifact로 연결한다.
- PASS 문서를 자동 게시하지 말고, 위험도에 맞는 승인 단계를 둔다.