chore: 문서를 작성할 때 한국어의 표현 작성 스킬 추가 및 1인칭 관점의 글 작성 검증 테스트 추가
This commit is contained in:
+128
-93
@@ -1,130 +1,165 @@
|
||||
# Architecture
|
||||
|
||||
## 1. 설계 목표
|
||||
## 1. 목표
|
||||
|
||||
ClariDoc의 핵심 목표는 생성 모델의 문장 능력보다 **정보 구조, 근거 추적, 검토 독립성, 재현 가능한 품질 판정**을 상위 제어 계층에 두는 것이다.
|
||||
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 실패는 숨기지 않는다.
|
||||
1. 독자 과업과 문서 유형 계약
|
||||
2. 프로젝트 근거의 수집과 source hierarchy
|
||||
3. 기술 선택의 rationale completeness
|
||||
4. 독자용 prose와 내부 provenance의 격리
|
||||
5. 결정적 검사와 독립 reviewer
|
||||
6. 재현 가능한 artifact와 hash manifest
|
||||
|
||||
## 2. 구성요소
|
||||
|
||||
```text
|
||||
models.py 입력/출력 계약과 검증
|
||||
structures.py 문서 유형별 필수 section intent와 순서
|
||||
prompts.py planner/writer/reviewer/reviser 출력 계약
|
||||
providers/ Codex, Claude, Antigravity, Mock 어댑터
|
||||
lint.py 모델과 독립적인 Markdown/논리 프록시 검사
|
||||
pipeline.py 단계 실행, 수정 루프, 품질 게이트, 감사 산출물
|
||||
models.py brief/source/outline/review/pipeline 계약
|
||||
corpus.py 로컬 문서 탐색, heading chunk, ranking, source-pack 생성
|
||||
structures.py 문서 유형별 필수 section intent와 decision requirements
|
||||
prompts.py planner/writer/reviewer/reviser 경계와 출력 계약
|
||||
providers/ Codex, Claude, Antigravity, Mock adapter
|
||||
lint.py 구조, 메타 누출, rationale, 안전성의 결정적 검사
|
||||
provenance.py evidence-map.json과 provenance.md 생성
|
||||
pipeline.py 단계 실행, 리뷰, 수정 루프, quality gate, manifest
|
||||
report.py 사람이 읽는 품질 보고서
|
||||
cli.py init/validate/outline/lint/run/doctor 명령
|
||||
cli.py init/collect/validate/outline/lint/run/doctor
|
||||
```
|
||||
|
||||
## 3. 단계별 상태 전이
|
||||
## 3. 입력 계층
|
||||
|
||||
### 3.1 계약 입력
|
||||
### 3.1 Brief
|
||||
|
||||
- `Brief`: 독자, 목표, 핵심 메시지, 범위, 비범위, 선행지식, 필수 주제, 버전 맥락, 금지 주장
|
||||
- `SourcePack`: 출처 식별자와 출처가 실제로 지지하는 사실 단위
|
||||
- `PipelineConfig`: 각 역할의 provider, timeout, 옵션, 품질 게이트
|
||||
Brief는 주제보다 독자 과업과 판단 경계를 먼저 고정한다.
|
||||
|
||||
입력은 정규화되어 `inputs/`에 기록된다.
|
||||
- audience / prior knowledge / needs
|
||||
- reader goal / core message
|
||||
- scope / non-scope
|
||||
- prerequisites / required topics
|
||||
- citation style / date policy / style profile
|
||||
- forbidden claims
|
||||
|
||||
### 3.2 결정적 기본 outline
|
||||
### 3.2 SourcePack
|
||||
|
||||
`structures.py`가 `document_type`에 따라 필수 intent를 만든다. 각 section은 다음 계약을 가진다.
|
||||
Source는 단순 URL이 아니라 다음 metadata를 가질 수 있다.
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "04-mechanism",
|
||||
"intent": "mechanism",
|
||||
"title": "해결 방식이 동작하는 과정",
|
||||
"reader_question": "구성요소와 데이터 흐름은 어떻게 연결되는가?",
|
||||
"purpose": "메커니즘을 단계적 인과 사슬로 설명한다.",
|
||||
"must_include": ["구성요소", "데이터 또는 제어 흐름", "불변조건"],
|
||||
"evidence_ids": ["S1"],
|
||||
"transition_to_next": "다음 독자 질문으로 연결한다."
|
||||
"id": "L1234abcd",
|
||||
"title": "...",
|
||||
"url": "repo:///raw/branch-notes/example.md",
|
||||
"facts": ["heading chunk text"],
|
||||
"source_type": "branch-note",
|
||||
"status": "verified",
|
||||
"path": "raw/branch-notes/example.md",
|
||||
"heading": "결정 사항",
|
||||
"line_start": 120,
|
||||
"line_end": 150,
|
||||
"claim_ids": ["TX-C1"],
|
||||
"decision_ids": ["D13"],
|
||||
"priority": 21.7
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 Planner 정교화
|
||||
이 metadata는 내부 reasoning과 audit에 사용된다. `citation_style=hidden`에서는 독자용 문서로 출력되지 않는다.
|
||||
|
||||
Planner는 section 제목, 질문, 목적, `must_include`, 근거 배치, 전환을 개선한다. `reconcile_outline`은 다음을 거부한다.
|
||||
## 4. Local corpus retrieval
|
||||
|
||||
- 문서 유형 변경
|
||||
- 필수 intent 삭제
|
||||
- intent 중복
|
||||
- 필수 순서 변경
|
||||
- 존재하지 않는 source ID
|
||||
`corpus.py`는 다음 순서로 동작한다.
|
||||
|
||||
Planner 실행 또는 JSON 파싱이 실패하면 기본 outline을 사용하고 경고를 기록한다.
|
||||
1. configured include directory를 순회한다.
|
||||
2. Markdown frontmatter에서 title/status를 읽는다.
|
||||
3. heading 단위로 chunk를 만든다.
|
||||
4. query와 각 chunk를 BM25 계열 점수로 비교한다.
|
||||
5. source type, status, decision/rationale 용어에 가중한다.
|
||||
6. 파일별 최대 chunk 수와 전체 top-k를 적용한다.
|
||||
7. repository-relative provenance를 포함한 SourcePack으로 변환한다.
|
||||
|
||||
### 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 품질 게이트와 수정
|
||||
Source precedence:
|
||||
|
||||
```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
|
||||
canonical-project
|
||||
> canonical-concept
|
||||
> branch-note
|
||||
> official-doc
|
||||
> company-tech-blog
|
||||
> local-document
|
||||
```
|
||||
|
||||
FAIL이고 수정 한도가 남으면 reviser가 lint와 모든 리뷰를 받아 전체 문서를 다시 작성한다. 수정된 초안은 동일한 린트와 리뷰를 처음부터 통과해야 한다.
|
||||
이 순서는 절대적인 진실 순위가 아니다. 현재 프로젝트 상태에는 canonical project가 우선이고, 선택 배경에는 branch note가 더 유용할 수 있다. Planner와 reviewer가 claim 종류에 맞게 사용해야 한다.
|
||||
|
||||
## 4. 신뢰 경계
|
||||
## 5. Outline contract
|
||||
|
||||
| 경계 | 신뢰 수준 | 처리 |
|
||||
|---|---|---|
|
||||
| pipeline config | 로컬 운영자가 승인한 코드 수준 설정 | command 실행 가능하므로 반드시 신뢰된 파일만 사용 |
|
||||
| brief/source pack | 비신뢰 데이터 | prompt 내부에서 data로 구획, 지시 무시 명시 |
|
||||
| model response | 비신뢰 출력 | JSON 파싱·계약 검증·lint·review 수행 |
|
||||
| URL | 메타데이터 | 자동 방문/실행하지 않음 |
|
||||
| final document | 검토 후보 | PASS여도 도메인 사실·코드 실행을 별도 검증 |
|
||||
각 section은 다음 속성을 가진다.
|
||||
|
||||
## 5. 실패 정책
|
||||
```json
|
||||
{
|
||||
"id": "04-decision-rationale",
|
||||
"intent": "decision_rationale",
|
||||
"title": "선택의 이유와 지킨 경계",
|
||||
"reader_question": "왜 이 선택을 했고 무엇을 포기했는가?",
|
||||
"purpose": "선택을 이유, 대안, 비용, 가드레일과 함께 설명한다.",
|
||||
"must_include": ["선택", "이유", "대안", "수용한 비용", "가드레일"],
|
||||
"evidence_ids": ["L..."],
|
||||
"decision_requirements": [
|
||||
"context_or_constraint",
|
||||
"choice",
|
||||
"why",
|
||||
"alternative",
|
||||
"accepted_cost",
|
||||
"guardrail"
|
||||
],
|
||||
"transition_to_next": "코드와 흐름으로 연결한다."
|
||||
}
|
||||
```
|
||||
|
||||
| 단계 | 기본 실패 처리 | 이유 |
|
||||
|---|---|---|
|
||||
| planner | 결정적 outline 폴백 + 경고 | 구조의 안전한 기본값이 존재 |
|
||||
| writer | 실행 중단 | 내용 없는 대체 초안은 유효하지 않음 |
|
||||
| reviewer | 실행 중단 | 독립 검토가 구성 계약의 일부 |
|
||||
| reviewer, fail-open 설정 | blocker/0점 리뷰로 기록 | 산출물 보존이 필요한 실험 환경 |
|
||||
| reviser | 실행 중단 | 수정 실패를 이전 초안 통과로 위장하지 않음 |
|
||||
| quality gate fail | final 산출물은 남기되 exit code 4 | 사람이 결함을 분석할 수 있도록 보존 |
|
||||
Planner는 제목·질문·근거 배치를 정교화할 수 있지만 intent의 삭제, 추가, 재배열은 할 수 없다.
|
||||
|
||||
## 6. 재현성과 감사
|
||||
## 6. Reader/provenance split
|
||||
|
||||
- provider 요청의 stage/provider/model/status/duration을 JSONL로 기록
|
||||
- 각 모델의 raw response와 parsed JSON을 모두 보존
|
||||
- 입력을 정규화해 실행 시점 계약을 고정
|
||||
- 최종 산출물을 포함한 파일별 SHA-256 매니페스트 생성
|
||||
- Mock provider로 외부 네트워크 없이 파이프라인 배선 재현
|
||||
### Reader-facing surface
|
||||
|
||||
모델 자체의 비결정성까지 제거하지는 않는다. 운영에서 모델 ID, CLI/SDK 버전, 실행 날짜를 `version_context`, provider `model`, 별도 배포 메타데이터에 고정해야 한다.
|
||||
- `final/document.md`
|
||||
- 선택 이유와 기술 설명
|
||||
- 공개 citation policy에 따른 citation만 포함
|
||||
|
||||
### Internal surface
|
||||
|
||||
- `final/provenance.md`
|
||||
- `final/evidence-map.json`
|
||||
- normalized source pack
|
||||
- raw provider responses
|
||||
- review JSON과 lint report
|
||||
- provider event log
|
||||
|
||||
Hidden mode에서 internal source ID, repository path, access date가 `document.md`에 보이면 quality gate error다.
|
||||
|
||||
## 7. Review topology
|
||||
|
||||
- logic: 전제, 인과, 결론
|
||||
- decision: context, why, alternative, cost, guardrail
|
||||
- reader: orientation, cognitive load, natural prose
|
||||
- evidence: claim/source fit, hierarchy, status
|
||||
- operations: prerequisites, safety, verification, rollback
|
||||
- editor: 문장 흐름과 표현, 질문-답 연결, 정보 구조가 반복 문장 틀로 노출되는지 검사
|
||||
|
||||
Writer와 logic·decision·reader·editor·evidence·operations reviewer를 분리해 self-review 편향을 줄이지만, 여러 모델의 일치는 사실 검증을 대신하지 않는다.
|
||||
|
||||
## 8. Quality gate
|
||||
|
||||
```text
|
||||
composite = deterministic_lint × deterministic_weight
|
||||
+ model_review_mean × model_weight
|
||||
```
|
||||
|
||||
통과 조건은 점수와 함께 blocker/error 개수를 검사한다. revision loop가 최대 횟수에 도달하면 실패 상태와 artifact를 그대로 보존한다.
|
||||
|
||||
## 9. Failure behavior
|
||||
|
||||
- invalid input contract: 실행 전 실패
|
||||
- planner invalid JSON/contract: deterministic base outline으로 안전 폴백
|
||||
- writer/provider failure: 숨기지 않고 pipeline failure
|
||||
- reviewer failure: config에 따라 failure 또는 blocker review
|
||||
- revision no-op: warning 기록
|
||||
- output path traversal in reviewer role: slug sanitize
|
||||
- final artifact: manifest로 크기와 SHA-256 기록
|
||||
|
||||
+43
-46
@@ -1,66 +1,63 @@
|
||||
# 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을 검증한다.
|
||||
1. `DocumentType`에 enum 추가
|
||||
2. `STRUCTURE_SPECS`에 reader-question 순서 정의
|
||||
3. procedural/example/trade-off lint 범주 검토
|
||||
4. JSON Schema enum 업데이트
|
||||
5. 각 intent가 unique하고 최소 section 수를 만족하는 테스트 추가
|
||||
|
||||
새 유형을 만들기 전에 기존 유형의 하위 section으로 충분한지 확인한다. 유형이 늘수록 분류 실패 비용도 커진다.
|
||||
## 새 source type 추가
|
||||
|
||||
## 새로운 lint rule
|
||||
1. `corpus._classify_source`에 path rule 추가
|
||||
2. `_SOURCE_WEIGHTS`에 기본 weight 추가
|
||||
3. prompt의 source hierarchy에 claim role 정의
|
||||
4. canonical/current state와 rationale/history 충돌 규칙 작성
|
||||
5. ranking과 provenance 테스트 추가
|
||||
|
||||
좋은 결정적 rule은 다음 조건을 만족한다.
|
||||
## 새 reviewer 추가
|
||||
|
||||
- 모델 없이 같은 입력에 같은 결과
|
||||
- 결함 위치와 수정 방향을 설명
|
||||
- false positive가 관리 가능
|
||||
- blocker/error/warning/info의 위험 수준이 명확
|
||||
- 자연어 의미 전체를 안다고 가장하지 않음
|
||||
Pipeline config의 reviewer role은 자유 문자열이지만 중복될 수 없다. role-specific prompt가 필요하면 `ROLE_GUIDANCE`에 추가한다.
|
||||
|
||||
`LintIssue`의 code prefix를 기존 범주에 맞춘다.
|
||||
추천 role:
|
||||
|
||||
- `MD`: Markdown 무결성
|
||||
- `STR`: 구조
|
||||
- `AUD`: 독자/오프닝
|
||||
- `READ`: 가독성 proxy
|
||||
- `TYPE`: 문서 유형 계약
|
||||
- `EVD`: 근거
|
||||
- `SAFE`: 안전
|
||||
- `VER`: 버전
|
||||
- `LEN`: 길이
|
||||
- `FIN`: 미완료 표시
|
||||
- `editor`: 문장과 heading
|
||||
- `security`: threat model과 secret exposure
|
||||
- `api`: contract compatibility
|
||||
- `domain-owner`: project-specific correctness
|
||||
|
||||
## 새로운 reviewer role
|
||||
Model review response는 모든 `REVIEW_DIMENSIONS`를 포함해야 한다.
|
||||
|
||||
1. `prompts.py`의 `ROLE_GUIDANCE`에 실패 함수를 정의한다.
|
||||
2. pipeline config reviewers에 role/provider를 추가한다.
|
||||
3. 공통 9개 dimension을 유지하거나 조직용 dimension을 parser와 보고서에 명시적으로 확장한다.
|
||||
4. 다른 reviewer와 중복되는 일반 교정이 아니라 독립적인 결함 탐지 관점을 제공한다.
|
||||
## 새 provider 추가
|
||||
|
||||
예: accessibility, localization, API consistency, security threat modeling.
|
||||
`Provider` interface를 구현한다.
|
||||
|
||||
## 출처 자동 수집기
|
||||
```python
|
||||
class MyProvider(Provider):
|
||||
def generate(self, request: ProviderRequest) -> ProviderResponse:
|
||||
...
|
||||
|
||||
Core pipeline은 URL을 자동 방문하지 않는다. 수집기를 추가할 때는 별도 단계로 분리한다.
|
||||
|
||||
```text
|
||||
retriever → immutable evidence snapshot → fact extractor → human/source-owner approval → SourcePack
|
||||
def check(self) -> dict[str, object]:
|
||||
...
|
||||
```
|
||||
|
||||
최종 source pack에는 원문 snapshot hash, 추출 위치, 접근 날짜, 허용된 fact를 남기는 것이 바람직하다. 검색 결과 요약을 바로 source truth로 쓰지 않는다.
|
||||
요구사항:
|
||||
|
||||
## 실행 가능한 코드 검증
|
||||
- prompt는 stdin 또는 안전한 API body로 전달
|
||||
- timeout 강제
|
||||
- command/error를 audit event로 남길 수 있음
|
||||
- cwd 복원과 output isolation
|
||||
- credential을 response/event에 기록하지 않음
|
||||
- fake executable 또는 fake SDK unit test
|
||||
|
||||
코드 블록을 테스트하려면 document generation과 별도의 verifier를 둔다.
|
||||
## Rationale lint 확장
|
||||
|
||||
1. 언어 태그와 fixture를 추출한다.
|
||||
2. 격리된 container/sandbox에서 실행한다.
|
||||
3. expected output과 비교한다.
|
||||
4. 결과와 로그를 evidence artifact로 저장한다.
|
||||
5. 문서의 예시 section과 artifact hash를 연결한다.
|
||||
현재 `RAT001`과 `RAT002`는 lexical heuristic이다. 특정 조직의 decision record가 structured field를 갖고 있다면 다음 확장이 가능하다.
|
||||
|
||||
문서 모델에게 “코드가 맞다”고 평가하게 하는 것만으로 실행 검증을 대체하지 않는다.
|
||||
- decision ID별 required claim type
|
||||
- alternative/accepted-cost/guardrail field validation
|
||||
- source heading과 claim ID 기반 completeness score
|
||||
- canonical implementation state와 branch rationale join
|
||||
|
||||
Score를 높이기 위해 heuristic을 약화하지 않는다. false positive를 줄일 때는 regression fixture와 golden example을 함께 추가한다.
|
||||
|
||||
+91
-134
@@ -1,168 +1,125 @@
|
||||
# Logic model for comprehensible technical documents
|
||||
# Logic model
|
||||
|
||||
## 1. 문서는 질문 그래프다
|
||||
## 1. 독자 질문의 순서
|
||||
|
||||
좋은 기술 문서를 “서론-본론-결론”이라는 형식만으로 설명하면 부족하다. 실제 독자는 순차적으로 다음 질문을 해결한다.
|
||||
좋은 기술 글은 정보량보다 질문의 순서를 통제한다. 기술 블로그의 기본 질문은 다음과 같다.
|
||||
|
||||
```text
|
||||
왜 읽어야 하는가?
|
||||
↓
|
||||
정확히 무엇을 다루는가?
|
||||
↓
|
||||
무엇을 이미 알아야 하는가?
|
||||
↓
|
||||
핵심 답 또는 결과는 무엇인가?
|
||||
↓
|
||||
그 답이 성립하는 이유와 메커니즘은 무엇인가?
|
||||
↓
|
||||
구체적인 사례에서 어떻게 보이는가?
|
||||
↓
|
||||
어떻게 확인하는가?
|
||||
↓
|
||||
언제 실패하거나 선택하지 않아야 하는가?
|
||||
↓
|
||||
그래서 무엇을 해야 하는가?
|
||||
무슨 문제가 있었나?
|
||||
왜 단순히 풀 수 없었나?
|
||||
무엇을 검토했나?
|
||||
왜 이 선택을 했나?
|
||||
코드에서는 어떻게 동작하나?
|
||||
무엇으로 확인했나?
|
||||
어떤 비용과 한계가 남았나?
|
||||
내 환경에서 무엇을 판단해야 하나?
|
||||
```
|
||||
|
||||
모든 문서가 이 질문을 동일한 비중으로 다루지는 않는다. 문서 유형은 **독자의 현재 상태와 목적**에 따라 필요한 질문 부분을 선택하고 순서를 최적화한 것이다.
|
||||
제목은 이 질문에 대한 표지판이어야 한다. `개요`, `상세`, `기타`처럼 정보 역할을 드러내지 않는 heading은 경고 대상이다.
|
||||
|
||||
## 2. 문서 유형을 섞을 때의 규칙
|
||||
## 2. Decision unit
|
||||
|
||||
한 페이지에 여러 유형이 존재할 수 있지만 주된 목적은 하나여야 한다.
|
||||
기술 선택은 다음 6요소를 하나의 논리 단위로 본다.
|
||||
|
||||
- Tutorial 안의 짧은 explanation은 현재 단계를 이해시키는 데 필요한 만큼만 둔다.
|
||||
- How-to 안의 reference table은 절차 수행에 필요한 조회 표면으로 제한한다.
|
||||
- Technical blog 안의 code example은 전체 API reference가 아니라 인과 관계를 보여준다.
|
||||
- Reference 안의 장황한 배경 설명은 별도 explanation으로 분리한다.
|
||||
- Troubleshooting 안의 fix는 확인된 cause branch에만 연결한다.
|
||||
| 요소 | 질문 |
|
||||
|---|---|
|
||||
| context/constraint | 어떤 문제와 제약 아래에서 결정했는가 |
|
||||
| choice | 무엇을 선택·허용·금지했는가 |
|
||||
| why | 그 선택이 어떤 비용이나 위험을 줄였는가 |
|
||||
| alternative | 현실적인 다른 선택은 무엇이었는가 |
|
||||
| accepted cost | 선택 때문에 무엇을 감수했는가 |
|
||||
| guardrail | 허용 범위가 넓어지지 않게 무엇이 실패하는가 |
|
||||
|
||||
판정 질문:
|
||||
“X를 의도적으로 사용한다”는 choice 하나만 있다. 이유가 없으면 `RAT001`, 대안·비용·가드레일이 없으면 `RAT002` 후보가 된다.
|
||||
|
||||
> 이 부분이 독자의 현재 목표를 직접 전진시키는가, 아니면 다른 문서 유형의 목표를 새로 시작하는가?
|
||||
## 3. Evidence semantics
|
||||
|
||||
후자라면 분리하거나 링크한다.
|
||||
근거는 단어 일치가 아니라 claim role로 배치한다.
|
||||
|
||||
## 3. 논리 구조의 최소 단위
|
||||
- **current state**: canonical project가 우선
|
||||
- **decision history and rationale**: branch note가 유용
|
||||
- **vendor/protocol behavior**: official docs
|
||||
- **precedent**: company tech blog
|
||||
- **general explanation**: canonical concept 또는 안정적인 background knowledge
|
||||
|
||||
### Section contract
|
||||
공식 문서가 `@Service`의 동작을 설명해도 프로젝트가 왜 그것을 선택했는지는 증명하지 않는다. 반대로 branch note가 선택 이유를 설명해도 현재 구현 상태가 바뀌었다면 canonical source를 확인해야 한다.
|
||||
|
||||
각 section은 다음을 가진다.
|
||||
## 4. Status boundary
|
||||
|
||||
1. **Reader question**: 독자가 이 시점에 묻는 질문
|
||||
2. **Purpose**: 이 절이 수행할 정보 작업
|
||||
3. **Claim/answer**: 질문에 대한 명시적 답
|
||||
4. **Support**: 근거, 메커니즘, 예시 또는 절차
|
||||
5. **Boundary**: 답이 유효한 범위와 예외
|
||||
6. **Transition**: 다음 질문이 왜 생기는지 연결
|
||||
|
||||
### Paragraph contract
|
||||
|
||||
문단은 보통 다음 순서를 사용한다.
|
||||
다음 status를 서로 바꾸어 쓰지 않는다.
|
||||
|
||||
```text
|
||||
중심 문장 → 이유/근거 → 구체화/예시 → 다음 문장으로의 연결
|
||||
actually implemented
|
||||
locally verified
|
||||
production verified
|
||||
documented only
|
||||
planned
|
||||
needs confirmation
|
||||
unsupported
|
||||
```
|
||||
|
||||
문단이 두 개의 독립 결론을 갖거나, 첫 문장이 뒤의 내용을 예고하지 못하거나, 마지막 문장이 새 주제를 시작하면 분리 후보로 본다.
|
||||
로컬 ArchUnit test 통과는 운영 효과의 증거가 아니다. 다른 회사의 사례는 이 프로젝트가 같은 결과를 얻었다는 증거가 아니다.
|
||||
|
||||
## 4. 이해를 돕는 인과 구조
|
||||
## 5. Concrete example
|
||||
|
||||
기술 설명에서 목록만 나열하면 독자는 구성요소를 기억해도 시스템을 예측하지 못한다. 메커니즘 section은 다음 중 하나의 명시적 순서를 사용한다.
|
||||
|
||||
- 시간: 요청 전 → 요청 중 → 응답 후
|
||||
- 데이터 흐름: 입력 → 변환 → 저장 → 출력
|
||||
- 제어 흐름: 조건 → 분기 → 행동 → 상태 전이
|
||||
- 장애 흐름: 트리거 → 증상 → 전파 → 완화 → 복구
|
||||
- 결정 흐름: 제약 → 비교 기준 → 대안 평가 → 선택 → 수용 비용
|
||||
|
||||
각 화살표에는 “왜 다음 상태가 되는가”가 있어야 한다. 단순히 컴포넌트 이름을 이어 붙이지 않는다.
|
||||
|
||||
## 5. 점진 공개
|
||||
|
||||
독자가 세부사항을 이해하기 위한 구조를 먼저 제공한다.
|
||||
|
||||
1. 핵심 답/결과
|
||||
2. 범위와 전제
|
||||
3. 가장 단순한 모델
|
||||
4. 정상 메커니즘
|
||||
5. 완주하는 예시
|
||||
6. 검증
|
||||
7. 예외·실패·트레이드오프
|
||||
8. 운영 세부사항
|
||||
|
||||
예외를 너무 일찍 넣으면 기본 모델을 형성하기 어렵고, 너무 늦게 숨기면 과도한 확신을 준다. 기본 모델을 제시한 직후 “어디까지 유효한가”를 명시하고, 상세 예외는 뒤에서 확장한다.
|
||||
|
||||
## 6. Worked example 계약
|
||||
|
||||
예시는 코드 조각의 존재가 아니라 **시작 상태부터 검증 결과까지의 연결**이다.
|
||||
|
||||
필수 요소:
|
||||
|
||||
- 초기 상태와 입력
|
||||
- 각 단계의 행동 또는 상태 변화
|
||||
- 단계의 이유
|
||||
- 예상 관측
|
||||
- 최종 결과
|
||||
- 성공 기준
|
||||
- 실패했을 때 되돌아갈 지점
|
||||
|
||||
초보 독자에게는 중간 추론을 더 많이 보이고, 숙련 독자용 문서에서는 자명한 단계를 줄인다. 브리프의 `prior_knowledge`가 이 깊이를 결정한다.
|
||||
|
||||
## 7. 근거와 주장 수준
|
||||
|
||||
문장은 다음 네 종류 중 하나로 분류할 수 있어야 한다.
|
||||
|
||||
| 종류 | 예 | 처리 |
|
||||
|---|---|---|
|
||||
| 관측 사실 | 특정 로그가 발생했다 | 출처·실험·측정 연결 |
|
||||
| 일반 기술 사실 | 프로토콜 의미, API 계약 | 권위 있는 reference 연결 |
|
||||
| 가정/가상 예시 | 설명을 위한 단순 모델 | 가정/예시임을 표시 |
|
||||
| 권고/판단 | 이 조건에서는 A를 선택 | 기준·대안·비용을 공개 |
|
||||
|
||||
“관련된 출처”와 “그 주장을 지지하는 출처”는 다르다. Source pack의 `facts`는 허용된 주장 범위를 줄이는 역할을 한다.
|
||||
|
||||
## 8. 트레이드오프 구조
|
||||
|
||||
좋은 기술 글은 선택을 미화하지 않는다.
|
||||
예시는 최종 코드 조각만 보여주지 않는다.
|
||||
|
||||
```text
|
||||
선택한 접근
|
||||
├── 얻는 것
|
||||
├── 지불하는 비용
|
||||
├── 대안
|
||||
├── 선택 기준
|
||||
├── 실패 조건
|
||||
└── 선택하지 말아야 하는 상황
|
||||
initial state
|
||||
→ input
|
||||
→ decision criterion
|
||||
→ selected path
|
||||
→ state/control-flow change
|
||||
→ observable result
|
||||
→ success or recovery criterion
|
||||
```
|
||||
|
||||
대안을 비교할 때는 같은 기준을 사용한다. 한 대안은 성능으로, 다른 대안은 구현 편의성으로만 설명하면 비교가 성립하지 않는다.
|
||||
독자는 예시에서 추상 모델의 각 요소를 대응시킬 수 있어야 한다.
|
||||
|
||||
## 9. 절차 안전성
|
||||
## 6. Korean problem-solving blog profile
|
||||
|
||||
절차 문서의 단계는 다음 상태 머신으로 본다.
|
||||
`woowahan_tech_blog_ko` profile은 다음을 권장한다.
|
||||
|
||||
```text
|
||||
PRECONDITION_CHECKED
|
||||
→ CHECKPOINT_CREATED
|
||||
→ CHANGE_APPLIED
|
||||
→ EXPECTED_RESULT_OBSERVED
|
||||
→ VERIFIED
|
||||
```
|
||||
- 팀이나 시스템의 구체적 맥락에서 시작
|
||||
- 기술 이름보다 문제와 비용을 먼저 설명
|
||||
- 기존 방식, 실패한 시도, 대안을 숨기지 않음
|
||||
- 선택 기준과 이유를 명시
|
||||
- 구현 세부가 앞에서 세운 문제에 답하도록 구성
|
||||
- 검증 결과를 원래 문제에 다시 연결
|
||||
- project-local 결정을 보편 규칙으로 쓰지 않음
|
||||
- 억지 접속어보다 문단 사이의 실제 논리 관계를 수정
|
||||
- `문제 → 제약 → 대안 → 선택`을 의미 순서로 사용하되 문장 틀로 읽어 주지 않음
|
||||
- 문단을 행위자, 상태, 변화, 결과, 판단에서 시작
|
||||
- 질문형 heading은 바로 다음 문장에서 답하고, 접속어는 실제 인과·역접을 가리키게 함
|
||||
- 순서어는 실제 단계·방법·레이어·도표에 사용하고, 추상 분류는 목록이나 의미 있는 소제목으로 표현
|
||||
|
||||
어느 단계에서든 불일치하면 다음으로 진행하지 않고 `STOPPED → ROLLED_BACK → RECOVERY_VERIFIED`로 이동해야 한다. 파괴적 명령은 경고 문구만으로 충분하지 않으며 백업/복구점, 영향 범위, 확인 명령이 함께 있어야 한다.
|
||||
이는 샘플 글에서 관찰한 패턴을 하네스 규칙으로 번역한 것이며 공식 house style은 아니다.
|
||||
|
||||
## 10. 품질 평가 차원
|
||||
특히 `첫 번째 제약은`, `두 번째 제약은`, `세 번째 제약은`처럼 outline의 분류명을 연속 문단 머리에 두는 방식은 정보 구조를 산문으로 노출한다. 한국어 기술 블로그에서 이런 형식이 가까운 문단에 세 번 이상 나타나면 `STYLE001` warning 대상이다. 실제 순서를 설명하는 번호 목록과 단계 문장은 대상이 아니다.
|
||||
|
||||
모델 reviewer는 다음 차원을 각각 검사한다.
|
||||
## 7. Date and citation logic
|
||||
|
||||
- `reader_goal_alignment`: 약속한 결과를 실제로 제공하는가
|
||||
- `information_architecture`: 문서 유형과 section 역할이 맞는가
|
||||
- `logical_flow`: 전제·인과·결론·전환이 끊기지 않는가
|
||||
- `cognitive_load`: 선행지식에 맞고 세부사항이 점진적으로 공개되는가
|
||||
- `evidence_traceability`: 확인 가능한 주장이 근거와 연결되는가
|
||||
- `example_verifiability`: 예시가 끝까지 실행·검증 가능한가
|
||||
- `scannability`: heading과 첫 문장만 읽어도 구조가 보이는가
|
||||
- `operational_safety`: 절차·변경·실패·복구가 안전한가
|
||||
- `completeness_and_limits`: 범위, 비범위, 예외, 트레이드오프가 있는가
|
||||
- access date는 provenance
|
||||
- version/date가 behavior, compatibility, reproducibility를 바꿀 때만 본문에 사용
|
||||
- hidden citation mode에서는 internal marker 금지
|
||||
- public citation이 필요하면 footnote 또는 inline link 사용
|
||||
|
||||
한 차원의 평균이 전체 결함을 숨기지 않도록 blocker/error 개수를 점수와 별도로 게이트한다.
|
||||
## 8. Lint와 model review의 역할 분리
|
||||
|
||||
Deterministic lint가 잘하는 것:
|
||||
|
||||
- heading 계약
|
||||
- source marker/path/date/meta 문자열 누출
|
||||
- 명시적 choice 뒤 rationale 어휘 부재
|
||||
- 반복된 서수 문단처럼 형식적으로 식별 가능한 문장 scaffolding
|
||||
- 절차 구조와 파괴적 command safety
|
||||
|
||||
Model review가 필요한 것:
|
||||
|
||||
- 이유가 실제로 선택을 정당화하는가
|
||||
- 대안 비교가 공정한가
|
||||
- source chunk가 claim을 충분히 지지하는가
|
||||
- 문단 흐름과 독자 인지 부하
|
||||
- 질문이 바로 답을 얻고 접속어가 실제 관계를 가리키는가
|
||||
- 정보 구조가 기계적인 문장 틀로 노출됐는가
|
||||
- project-local policy의 과장 여부
|
||||
|
||||
+27
-124
@@ -1,155 +1,58 @@
|
||||
# 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에서 수행한다.
|
||||
# Provider integrations
|
||||
|
||||
## Codex
|
||||
|
||||
기본 command 개념:
|
||||
기본 command:
|
||||
|
||||
```text
|
||||
codex exec
|
||||
--sandbox read-only
|
||||
--skip-git-repo-check
|
||||
[--model MODEL]
|
||||
--output-last-message TEMP_FILE
|
||||
-
|
||||
codex exec --sandbox read-only --output-last-message <file> -
|
||||
```
|
||||
|
||||
프롬프트는 stdin으로 전달한다. `-`는 비대화형 입력을 의미하고, 마지막 메시지는 임시 파일에서 읽는다. 문서 생성은 로컬 파일 변경이 필요 없으므로 기본 sandbox를 read-only로 둔다.
|
||||
Prompt는 stdin으로 전달한다. planner, logic reviewer, decision reviewer에 사용한다. `skip_git_repo_check`와 `extra_args`는 provider option으로 설정할 수 있다.
|
||||
|
||||
설정 예:
|
||||
## Claude
|
||||
|
||||
```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 개념:
|
||||
기본 command:
|
||||
|
||||
```text
|
||||
claude -p --output-format text [--model MODEL] "Read the piped task..."
|
||||
claude -p --output-format text
|
||||
```
|
||||
|
||||
긴 프롬프트는 운영체제 argument 길이 제한을 피하기 위해 stdin으로 전달한다. 마지막 고정 query는 piped task의 출력 계약만 수행하도록 지시한다.
|
||||
|
||||
설정 예:
|
||||
|
||||
```json
|
||||
{
|
||||
"provider": "claude",
|
||||
"model": "",
|
||||
"timeout_seconds": 600,
|
||||
"options": {
|
||||
"binary": "claude",
|
||||
"extra_args": []
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
환경 변수 `CLARIDOC_CLAUDE_BIN` 또는 신뢰된 `options.command`를 사용할 수 있다.
|
||||
Prompt는 stdin으로 전달한다. primary writer, reader reviewer, editor reviewer, reviser에 사용한다.
|
||||
|
||||
## Google Antigravity
|
||||
|
||||
Antigravity는 Python SDK를 사용한다.
|
||||
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()
|
||||
```
|
||||
|
||||
설치:
|
||||
`LocalAgentConfig`로 model과 config를 전달하고 async `chat` 결과의 text를 읽는다. evidence와 operations reviewer에 사용한다.
|
||||
|
||||
## Model IDs
|
||||
|
||||
예제 config는 model ID를 비워 provider 계정의 기본 선택을 사용한다. 조직에서 허용된 model ID가 있다면 각 provider object의 `model`에 지정한다. 모델 이름과 availability는 계정·시점마다 달라질 수 있으므로 `doctor`와 live smoke test로 확인한다.
|
||||
|
||||
## Doctor
|
||||
|
||||
```bash
|
||||
python -m pip install -e '.[antigravity]'
|
||||
claridoc doctor --config config/pipeline.multi-agent.example.json
|
||||
```
|
||||
|
||||
설정 예:
|
||||
`doctor`가 확인하는 것:
|
||||
|
||||
```json
|
||||
{
|
||||
"provider": "antigravity",
|
||||
"model": "",
|
||||
"timeout_seconds": 300,
|
||||
"options": {
|
||||
"config": {}
|
||||
}
|
||||
}
|
||||
```
|
||||
- CLI executable 또는 SDK import 가능 여부
|
||||
- 설정된 integration surface
|
||||
|
||||
`model`이 지정되고 `options.config`에 model이 없으면 하네스가 config 인수로 전달한다. SDK 버전에 따라 지원 인수가 다를 수 있으므로 잘못된 config는 명시적 오류로 종료한다.
|
||||
확인하지 않는 것:
|
||||
|
||||
SDK가 로컬 환경을 기준으로 동작하므로 provider는 실행 중 임시로 run directory를 current working directory로 사용한다. 프로세스 전체 cwd가 공유 상태이므로 lock으로 직렬화한다.
|
||||
- 로그인 유효성
|
||||
- project/repository 접근 권한
|
||||
- quota와 rate limit
|
||||
- model ID availability
|
||||
- 실제 response schema 안정성
|
||||
|
||||
## 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에서 유지한다.
|
||||
Mock provider는 deterministic fixture다. source excerpt를 최종 글에 복사하지 않으며, 외부 model을 호출하지 않는다. Mock reviewer score는 합성값이다.
|
||||
|
||||
+46
-87
@@ -1,110 +1,69 @@
|
||||
# Security and trust model
|
||||
# Security and trust boundaries
|
||||
|
||||
## 보호 대상
|
||||
## 1. 주요 자산
|
||||
|
||||
- provider 인증 정보와 로컬 계정
|
||||
- 실행 호스트의 파일·명령·네트워크 권한
|
||||
- 비공개 brief, source pack, draft
|
||||
- 출처 진실성과 최종 문서 정확성
|
||||
- 품질 게이트의 무결성
|
||||
- provider credential과 local authentication state
|
||||
- private repository의 source text와 경로
|
||||
- draft와 내부 decision record
|
||||
- provider raw response와 event log
|
||||
- 최종 독자용 문서
|
||||
|
||||
## 위협과 완화
|
||||
## 2. Prompt injection 경계
|
||||
|
||||
### 1. Source/brief prompt injection
|
||||
Brief, source chunk, title, URL, note, draft는 모두 untrusted data다. 모든 stage prompt는 source 내부 지시를 따르지 말고 내용으로만 취급하도록 명시한다.
|
||||
|
||||
위협: title, fact, note, URL, draft 안에 “이전 지시를 무시하라” 같은 문장이 들어간다.
|
||||
완전한 prompt-injection 제거를 보장하지 않는다. 민감한 저장소에서는 다음을 권장한다.
|
||||
|
||||
완화:
|
||||
- provider가 읽어도 되는 corpus root만 지정
|
||||
- `--source-include`로 최소 directory만 허용
|
||||
- secret, credential, production dump를 corpus에 포함하지 않음
|
||||
- provider CLI의 sandbox와 조직 정책 사용
|
||||
- 최종 provenance artifact의 접근 권한 제한
|
||||
|
||||
- 모든 prompt에서 입력 블록을 명시적으로 untrusted data로 선언
|
||||
- 출력 스키마와 stage 역할을 입력 블록 밖에 정의
|
||||
- planner의 구조 변경을 코드로 검증
|
||||
- reviewer 결과도 JSON 파싱과 severity 계약으로 제한
|
||||
- 최종 출력에 결정적 린트와 독립 리뷰 적용
|
||||
## 3. Reader-facing data minimization
|
||||
|
||||
잔여 위험: 언어 모델이 경계를 무시할 수 있다. 고위험 입력은 별도 sanitization, 제공자 정책, 인간 검토가 필요하다.
|
||||
`citation_style=hidden`의 목적은 내부 근거를 없애는 것이 아니라 노출 표면을 줄이는 것이다.
|
||||
|
||||
### 2. Command injection
|
||||
독자용 문서에서 금지:
|
||||
|
||||
위협: provider command가 외부 입력으로 조작된다.
|
||||
- source ID와 claim/decision ID
|
||||
- absolute/local repository path
|
||||
- access date
|
||||
- frontmatter와 status field
|
||||
- prompt tag
|
||||
- evidence-processing narration
|
||||
|
||||
완화:
|
||||
내부 audit artifact에는 이 metadata가 남으므로, run directory 자체는 private data로 취급해야 한다.
|
||||
|
||||
- subprocess는 shell 없이 argument list로 실행
|
||||
- brief/source 값을 command에 삽입하지 않고 stdin으로 전달
|
||||
- `options.command`는 로컬 운영자가 승인한 config만 허용한다고 문서화
|
||||
- 인증 비밀을 command line에 넣지 않음
|
||||
## 4. Command execution
|
||||
|
||||
잔여 위험: 악의적인 pipeline config 자체는 임의의 로컬 executable을 실행할 수 있다. config를 코드와 같은 신뢰 수준으로 관리해야 한다.
|
||||
- Codex 기본 설정은 read-only sandbox다.
|
||||
- writer/reviewer prompt는 shell 실행이나 file mutation을 요구하지 않는다.
|
||||
- `options.command`, provider binary path, extra args는 신뢰된 local config로만 설정한다.
|
||||
- 사용자 또는 source text에서 command option을 동적으로 만들지 않는다.
|
||||
|
||||
### 3. 모델의 파일/명령 부작용
|
||||
## 5. Destructive content
|
||||
|
||||
위협: 에이전트 도구가 파일을 수정하거나 command를 실행한다.
|
||||
문서 안에 `rm -rf`, `DROP DATABASE`, `kubectl delete`, `terraform destroy` 등 파괴적 command가 있으면 주변에 다음이 모두 필요하다.
|
||||
|
||||
완화:
|
||||
- 영향 경고
|
||||
- backup/checkpoint/recovery
|
||||
- expected effect
|
||||
- read-only verification
|
||||
|
||||
- Codex 기본 sandbox `read-only`
|
||||
- 작성 prompt는 파일 수정이나 shell 사용을 요구하지 않음
|
||||
- Claude는 print mode 텍스트 출력을 사용
|
||||
- Antigravity에는 문서 생성 prompt만 전달
|
||||
이 검사는 command가 실제 환경에서 안전하다는 보증이 아니다.
|
||||
|
||||
잔여 위험: provider 자체 설정이나 조직 wrapper가 더 넓은 권한을 부여할 수 있다. 최소 권한과 격리 환경을 별도로 적용한다.
|
||||
## 6. Provenance integrity
|
||||
|
||||
### 4. 근거 세탁과 허위 인용
|
||||
`manifest.json`은 run artifact의 byte size와 SHA-256을 기록한다. manifest 생성 이후 파일이 바뀌면 재검산에서 드러난다. 전자서명이나 원격 attestation은 제공하지 않는다.
|
||||
|
||||
위협: 모델이 관련만 있는 출처를 주장 근거처럼 붙이거나 source ID를 지어낸다.
|
||||
## 7. Provider credentials
|
||||
|
||||
완화:
|
||||
Credential을 repository, brief, source pack, event log에 저장하지 않는다. Codex/Claude CLI와 Antigravity SDK의 표준 인증 방식을 사용한다. `doctor`는 설치 가능성만 확인하며 로그인, 권한, quota를 증명하지 않는다.
|
||||
|
||||
- source pack에 출처가 지지하는 `facts`를 명시
|
||||
- 존재하지 않는 source ID를 error로 처리
|
||||
- evidence reviewer가 claim-marker fit를 검사
|
||||
- 원문 model response와 source pack을 보존
|
||||
## 8. Known limits
|
||||
|
||||
잔여 위험: 하네스는 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 문서를 자동 게시하지 말고, 위험도에 맞는 승인 단계를 둔다.
|
||||
- lexical retrieval이 민감한 문서를 선택할 수 있으므로 corpus scope를 운영자가 통제해야 한다.
|
||||
- model이 source text를 재구성하면서 민감 정보를 노출할 수 있다.
|
||||
- hidden citation lint는 알려진 path와 marker pattern을 검사하지만 모든 비밀 문자열을 탐지하지 않는다.
|
||||
- private source에서 공개 가능한 결론을 만드는 책임은 프로젝트 소유자에게 있다.
|
||||
|
||||
Reference in New Issue
Block a user