chore!: remove ClariDoc harness
.run/의 세 런을 조사한 결과 claridoc run 파이프라인이 한 번도 완주하지 않았다. quality-gate.json 0건, stages/ 및 rounds/ 부재. 실사용 범위는 validate/collect/outline까지였고 글쓰기와 검수는 스킬이 담당했다. 파이썬 패키지, CLI, 스키마, 테스트, 예제, 조사 자료, 빌드·배포 산출물, 하네스 규약 문서를 제거한다. 남는 것은 Agent Skill 세 개, .run/의 문서 세 편, CLAUDE.md, README.md, LICENSE, 제거 결정 문서다. examples/golden의 구버전 초안 두 편(n+1liner.md 1416줄, claridoc-rewrite/document.md 1626줄)과 루트 document.md(.run 판과 md5 동일한 사본)도 함께 지운다. .run/에 더 진행된 판이 있다. 복구: git checkout pre-harness-removal -- <경로> 근거: docs/decisions/2026-08-07-remove-claridoc-harness.md Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
7dae5a9359
commit
ef1f76146e
@@ -1,165 +0,0 @@
|
||||
# Architecture
|
||||
|
||||
## 1. 목표
|
||||
|
||||
ClariDoc은 문장 생성 능력보다 다음 제어 계층을 우선한다.
|
||||
|
||||
1. 독자 과업과 문서 유형 계약
|
||||
2. 프로젝트 근거의 수집과 source hierarchy
|
||||
3. 기술 선택의 rationale completeness
|
||||
4. 독자용 prose와 내부 provenance의 격리
|
||||
5. 결정적 검사와 독립 reviewer
|
||||
6. 재현 가능한 artifact와 hash manifest
|
||||
|
||||
## 2. 구성요소
|
||||
|
||||
```text
|
||||
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/collect/validate/outline/lint/run/doctor
|
||||
```
|
||||
|
||||
## 3. 입력 계층
|
||||
|
||||
### 3.1 Brief
|
||||
|
||||
Brief는 주제보다 독자 과업과 판단 경계를 먼저 고정한다.
|
||||
|
||||
- audience / prior knowledge / needs
|
||||
- reader goal / core message
|
||||
- scope / non-scope
|
||||
- prerequisites / required topics
|
||||
- citation style / date policy / style profile
|
||||
- forbidden claims
|
||||
|
||||
### 3.2 SourcePack
|
||||
|
||||
Source는 단순 URL이 아니라 다음 metadata를 가질 수 있다.
|
||||
|
||||
```json
|
||||
{
|
||||
"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
|
||||
}
|
||||
```
|
||||
|
||||
이 metadata는 내부 reasoning과 audit에 사용된다. `citation_style=hidden`에서는 독자용 문서로 출력되지 않는다.
|
||||
|
||||
## 4. Local corpus retrieval
|
||||
|
||||
`corpus.py`는 다음 순서로 동작한다.
|
||||
|
||||
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으로 변환한다.
|
||||
|
||||
Source precedence:
|
||||
|
||||
```text
|
||||
canonical-project
|
||||
> canonical-concept
|
||||
> branch-note
|
||||
> official-doc
|
||||
> company-tech-blog
|
||||
> local-document
|
||||
```
|
||||
|
||||
이 순서는 절대적인 진실 순위가 아니다. 현재 프로젝트 상태에는 canonical project가 우선이고, 선택 배경에는 branch note가 더 유용할 수 있다. Planner와 reviewer가 claim 종류에 맞게 사용해야 한다.
|
||||
|
||||
## 5. Outline contract
|
||||
|
||||
각 section은 다음 속성을 가진다.
|
||||
|
||||
```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는 제목·질문·근거 배치를 정교화할 수 있지만 intent의 삭제, 추가, 재배열은 할 수 없다.
|
||||
|
||||
## 6. Reader/provenance split
|
||||
|
||||
### Reader-facing surface
|
||||
|
||||
- `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 기록
|
||||
@@ -1,63 +0,0 @@
|
||||
# Extending ClariDoc
|
||||
|
||||
## 새 문서 유형 추가
|
||||
|
||||
1. `DocumentType`에 enum 추가
|
||||
2. `STRUCTURE_SPECS`에 reader-question 순서 정의
|
||||
3. procedural/example/trade-off lint 범주 검토
|
||||
4. JSON Schema enum 업데이트
|
||||
5. 각 intent가 unique하고 최소 section 수를 만족하는 테스트 추가
|
||||
|
||||
## 새 source type 추가
|
||||
|
||||
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 테스트 추가
|
||||
|
||||
## 새 reviewer 추가
|
||||
|
||||
Pipeline config의 reviewer role은 자유 문자열이지만 중복될 수 없다. role-specific prompt가 필요하면 `ROLE_GUIDANCE`에 추가한다.
|
||||
|
||||
추천 role:
|
||||
|
||||
- `editor`: 문장과 heading
|
||||
- `security`: threat model과 secret exposure
|
||||
- `api`: contract compatibility
|
||||
- `domain-owner`: project-specific correctness
|
||||
|
||||
Model review response는 모든 `REVIEW_DIMENSIONS`를 포함해야 한다.
|
||||
|
||||
## 새 provider 추가
|
||||
|
||||
`Provider` interface를 구현한다.
|
||||
|
||||
```python
|
||||
class MyProvider(Provider):
|
||||
def generate(self, request: ProviderRequest) -> ProviderResponse:
|
||||
...
|
||||
|
||||
def check(self) -> dict[str, object]:
|
||||
...
|
||||
```
|
||||
|
||||
요구사항:
|
||||
|
||||
- prompt는 stdin 또는 안전한 API body로 전달
|
||||
- timeout 강제
|
||||
- command/error를 audit event로 남길 수 있음
|
||||
- cwd 복원과 output isolation
|
||||
- credential을 response/event에 기록하지 않음
|
||||
- fake executable 또는 fake SDK unit test
|
||||
|
||||
## Rationale lint 확장
|
||||
|
||||
현재 `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을 함께 추가한다.
|
||||
@@ -1,125 +0,0 @@
|
||||
# Logic model
|
||||
|
||||
## 1. 독자 질문의 순서
|
||||
|
||||
좋은 기술 글은 정보량보다 질문의 순서를 통제한다. 기술 블로그의 기본 질문은 다음과 같다.
|
||||
|
||||
```text
|
||||
무슨 문제가 있었나?
|
||||
왜 단순히 풀 수 없었나?
|
||||
무엇을 검토했나?
|
||||
왜 이 선택을 했나?
|
||||
코드에서는 어떻게 동작하나?
|
||||
무엇으로 확인했나?
|
||||
어떤 비용과 한계가 남았나?
|
||||
내 환경에서 무엇을 판단해야 하나?
|
||||
```
|
||||
|
||||
제목은 이 질문에 대한 표지판이어야 한다. `개요`, `상세`, `기타`처럼 정보 역할을 드러내지 않는 heading은 경고 대상이다.
|
||||
|
||||
## 2. Decision unit
|
||||
|
||||
기술 선택은 다음 6요소를 하나의 논리 단위로 본다.
|
||||
|
||||
| 요소 | 질문 |
|
||||
|---|---|
|
||||
| context/constraint | 어떤 문제와 제약 아래에서 결정했는가 |
|
||||
| choice | 무엇을 선택·허용·금지했는가 |
|
||||
| why | 그 선택이 어떤 비용이나 위험을 줄였는가 |
|
||||
| alternative | 현실적인 다른 선택은 무엇이었는가 |
|
||||
| accepted cost | 선택 때문에 무엇을 감수했는가 |
|
||||
| guardrail | 허용 범위가 넓어지지 않게 무엇이 실패하는가 |
|
||||
|
||||
“X를 의도적으로 사용한다”는 choice 하나만 있다. 이유가 없으면 `RAT001`, 대안·비용·가드레일이 없으면 `RAT002` 후보가 된다.
|
||||
|
||||
## 3. Evidence semantics
|
||||
|
||||
근거는 단어 일치가 아니라 claim role로 배치한다.
|
||||
|
||||
- **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
|
||||
|
||||
공식 문서가 `@Service`의 동작을 설명해도 프로젝트가 왜 그것을 선택했는지는 증명하지 않는다. 반대로 branch note가 선택 이유를 설명해도 현재 구현 상태가 바뀌었다면 canonical source를 확인해야 한다.
|
||||
|
||||
## 4. Status boundary
|
||||
|
||||
다음 status를 서로 바꾸어 쓰지 않는다.
|
||||
|
||||
```text
|
||||
actually implemented
|
||||
locally verified
|
||||
production verified
|
||||
documented only
|
||||
planned
|
||||
needs confirmation
|
||||
unsupported
|
||||
```
|
||||
|
||||
로컬 ArchUnit test 통과는 운영 효과의 증거가 아니다. 다른 회사의 사례는 이 프로젝트가 같은 결과를 얻었다는 증거가 아니다.
|
||||
|
||||
## 5. Concrete example
|
||||
|
||||
예시는 최종 코드 조각만 보여주지 않는다.
|
||||
|
||||
```text
|
||||
initial state
|
||||
→ input
|
||||
→ decision criterion
|
||||
→ selected path
|
||||
→ state/control-flow change
|
||||
→ observable result
|
||||
→ success or recovery criterion
|
||||
```
|
||||
|
||||
독자는 예시에서 추상 모델의 각 요소를 대응시킬 수 있어야 한다.
|
||||
|
||||
## 6. Korean problem-solving blog profile
|
||||
|
||||
`woowahan_tech_blog_ko` profile은 다음을 권장한다.
|
||||
|
||||
- 팀이나 시스템의 구체적 맥락에서 시작
|
||||
- 기술 이름보다 문제와 비용을 먼저 설명
|
||||
- 기존 방식, 실패한 시도, 대안을 숨기지 않음
|
||||
- 선택 기준과 이유를 명시
|
||||
- 구현 세부가 앞에서 세운 문제에 답하도록 구성
|
||||
- 검증 결과를 원래 문제에 다시 연결
|
||||
- project-local 결정을 보편 규칙으로 쓰지 않음
|
||||
- 억지 접속어보다 문단 사이의 실제 논리 관계를 수정
|
||||
- `문제 → 제약 → 대안 → 선택`을 의미 순서로 사용하되 문장 틀로 읽어 주지 않음
|
||||
- 문단을 행위자, 상태, 변화, 결과, 판단에서 시작
|
||||
- 질문형 heading은 바로 다음 문장에서 답하고, 접속어는 실제 인과·역접을 가리키게 함
|
||||
- 순서어는 실제 단계·방법·레이어·도표에 사용하고, 추상 분류는 목록이나 의미 있는 소제목으로 표현
|
||||
|
||||
이는 샘플 글에서 관찰한 패턴을 하네스 규칙으로 번역한 것이며 공식 house style은 아니다.
|
||||
|
||||
특히 `첫 번째 제약은`, `두 번째 제약은`, `세 번째 제약은`처럼 outline의 분류명을 연속 문단 머리에 두는 방식은 정보 구조를 산문으로 노출한다. 한국어 기술 블로그에서 이런 형식이 가까운 문단에 세 번 이상 나타나면 `STYLE001` warning 대상이다. 실제 순서를 설명하는 번호 목록과 단계 문장은 대상이 아니다.
|
||||
|
||||
## 7. Date and citation logic
|
||||
|
||||
- access date는 provenance
|
||||
- version/date가 behavior, compatibility, reproducibility를 바꿀 때만 본문에 사용
|
||||
- hidden citation mode에서는 internal marker 금지
|
||||
- public citation이 필요하면 footnote 또는 inline link 사용
|
||||
|
||||
## 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의 과장 여부
|
||||
@@ -1,58 +0,0 @@
|
||||
# Provider integrations
|
||||
|
||||
## Codex
|
||||
|
||||
기본 command:
|
||||
|
||||
```text
|
||||
codex exec --sandbox read-only --output-last-message <file> -
|
||||
```
|
||||
|
||||
Prompt는 stdin으로 전달한다. planner, logic reviewer, decision reviewer에 사용한다. `skip_git_repo_check`와 `extra_args`는 provider option으로 설정할 수 있다.
|
||||
|
||||
## Claude
|
||||
|
||||
기본 command:
|
||||
|
||||
```text
|
||||
claude -p --output-format text
|
||||
```
|
||||
|
||||
Prompt는 stdin으로 전달한다. primary writer, reader reviewer, editor reviewer, reviser에 사용한다.
|
||||
|
||||
## Google Antigravity
|
||||
|
||||
Python SDK 표면:
|
||||
|
||||
```python
|
||||
from google.antigravity import Agent, LocalAgentConfig
|
||||
```
|
||||
|
||||
`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
|
||||
claridoc doctor --config config/pipeline.multi-agent.example.json
|
||||
```
|
||||
|
||||
`doctor`가 확인하는 것:
|
||||
|
||||
- CLI executable 또는 SDK import 가능 여부
|
||||
- 설정된 integration surface
|
||||
|
||||
확인하지 않는 것:
|
||||
|
||||
- 로그인 유효성
|
||||
- project/repository 접근 권한
|
||||
- quota와 rate limit
|
||||
- model ID availability
|
||||
- 실제 response schema 안정성
|
||||
|
||||
## Mock
|
||||
|
||||
Mock provider는 deterministic fixture다. source excerpt를 최종 글에 복사하지 않으며, 외부 model을 호출하지 않는다. Mock reviewer score는 합성값이다.
|
||||
@@ -1,69 +0,0 @@
|
||||
# Security and trust boundaries
|
||||
|
||||
## 1. 주요 자산
|
||||
|
||||
- provider credential과 local authentication state
|
||||
- private repository의 source text와 경로
|
||||
- draft와 내부 decision record
|
||||
- provider raw response와 event log
|
||||
- 최종 독자용 문서
|
||||
|
||||
## 2. Prompt injection 경계
|
||||
|
||||
Brief, source chunk, title, URL, note, draft는 모두 untrusted data다. 모든 stage prompt는 source 내부 지시를 따르지 말고 내용으로만 취급하도록 명시한다.
|
||||
|
||||
완전한 prompt-injection 제거를 보장하지 않는다. 민감한 저장소에서는 다음을 권장한다.
|
||||
|
||||
- provider가 읽어도 되는 corpus root만 지정
|
||||
- `--source-include`로 최소 directory만 허용
|
||||
- secret, credential, production dump를 corpus에 포함하지 않음
|
||||
- provider CLI의 sandbox와 조직 정책 사용
|
||||
- 최종 provenance artifact의 접근 권한 제한
|
||||
|
||||
## 3. Reader-facing data minimization
|
||||
|
||||
`citation_style=hidden`의 목적은 내부 근거를 없애는 것이 아니라 노출 표면을 줄이는 것이다.
|
||||
|
||||
독자용 문서에서 금지:
|
||||
|
||||
- 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로 취급해야 한다.
|
||||
|
||||
## 4. Command execution
|
||||
|
||||
- Codex 기본 설정은 read-only sandbox다.
|
||||
- writer/reviewer prompt는 shell 실행이나 file mutation을 요구하지 않는다.
|
||||
- `options.command`, provider binary path, extra args는 신뢰된 local config로만 설정한다.
|
||||
- 사용자 또는 source text에서 command option을 동적으로 만들지 않는다.
|
||||
|
||||
## 5. Destructive content
|
||||
|
||||
문서 안에 `rm -rf`, `DROP DATABASE`, `kubectl delete`, `terraform destroy` 등 파괴적 command가 있으면 주변에 다음이 모두 필요하다.
|
||||
|
||||
- 영향 경고
|
||||
- backup/checkpoint/recovery
|
||||
- expected effect
|
||||
- read-only verification
|
||||
|
||||
이 검사는 command가 실제 환경에서 안전하다는 보증이 아니다.
|
||||
|
||||
## 6. Provenance integrity
|
||||
|
||||
`manifest.json`은 run artifact의 byte size와 SHA-256을 기록한다. manifest 생성 이후 파일이 바뀌면 재검산에서 드러난다. 전자서명이나 원격 attestation은 제공하지 않는다.
|
||||
|
||||
## 7. Provider credentials
|
||||
|
||||
Credential을 repository, brief, source pack, event log에 저장하지 않는다. Codex/Claude CLI와 Antigravity SDK의 표준 인증 방식을 사용한다. `doctor`는 설치 가능성만 확인하며 로그인, 권한, quota를 증명하지 않는다.
|
||||
|
||||
## 8. Known limits
|
||||
|
||||
- lexical retrieval이 민감한 문서를 선택할 수 있으므로 corpus scope를 운영자가 통제해야 한다.
|
||||
- model이 source text를 재구성하면서 민감 정보를 노출할 수 있다.
|
||||
- hidden citation lint는 알려진 path와 marker pattern을 검사하지만 모든 비밀 문자열을 탐지하지 않는다.
|
||||
- private source에서 공개 가능한 결론을 만드는 책임은 프로젝트 소유자에게 있다.
|
||||
@@ -1,630 +0,0 @@
|
||||
# Korean Experience-Prose Contract Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Make Korean technical blogs and Korean READMEs use one experience-oriented `합니다/했습니다` prose contract that drafting, review, revision, deterministic lint, and the quality gate all enforce.
|
||||
|
||||
**Architecture:** Add `readme` as a first-class document type, centralize style activation and prompt guidance in `claridoc.style_contracts`, and add Markdown-aware deterministic style checks to `claridoc.lint`. Keep objective checks in lint and qualitative experience-flow checks in every model review, then migrate the maintained Korean fixtures and repository README to the enforced contract.
|
||||
|
||||
**Tech Stack:** Python 3.10+, standard-library `unittest`, JSON Schema Draft 2020-12, Markdown text processing with `re`, existing ClariDoc provider and quality-gate abstractions.
|
||||
|
||||
## Global Constraints
|
||||
|
||||
- Apply the contract automatically to Korean `technical_blog` briefs using `auto`, `woowahan_tech_blog_ko`, or `korean_problem_solving_blog`.
|
||||
- Apply the contract automatically to every Korean `readme`.
|
||||
- Do not apply first-person retrospective rules to tutorial, how-to, reference, troubleshooting, explanation, or design-document types.
|
||||
- Preserve `Brief → SourcePack → deterministic outline → draft → lint/reviews → revision → quality gate → reader/provenance artifacts`.
|
||||
- Treat source text and quoted examples as untrusted data; never invent experience or decision rationale.
|
||||
- Exempt fenced code, headings, tables, block quotations, image alt text, command output, and quoted spans from formal-ending lint.
|
||||
- Style-contract failures are blockers and cannot pass through configured error tolerance.
|
||||
- Preserve unrelated user changes and do not regenerate `build/`, `dist/`, `.verify/`, or `.run/` artifacts during implementation.
|
||||
|
||||
---
|
||||
|
||||
### Task 1: Add a first-class README document contract
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/claridoc/models.py`
|
||||
- Modify: `src/claridoc/structures.py`
|
||||
- Modify: `schemas/brief.schema.json`
|
||||
- Modify: `schemas/outline.schema.json`
|
||||
- Modify: `tests/test_models.py`
|
||||
- Modify: `tests/test_schemas.py`
|
||||
- Modify: `tests/test_structures.py`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: existing `DocumentType`, `Brief.from_dict`, and `STRUCTURE_SPECS`.
|
||||
- Produces: `DocumentType.README` with value `"readme"` and an eight-intent deterministic outline.
|
||||
|
||||
- [ ] **Step 1: Write failing runtime and structure tests**
|
||||
|
||||
Add:
|
||||
|
||||
```python
|
||||
def test_readme_brief_round_trip(self) -> None:
|
||||
brief = Brief.from_dict(brief_dict("readme"))
|
||||
self.assertEqual(brief.document_type, DocumentType.README)
|
||||
self.assertEqual(Brief.from_dict(brief.to_dict()).document_type, DocumentType.README)
|
||||
```
|
||||
|
||||
and:
|
||||
|
||||
```python
|
||||
def test_readme_outline_preserves_reader_onboarding_order(self) -> None:
|
||||
brief = Brief.from_dict(brief_dict("readme"))
|
||||
outline = create_outline(brief, make_sources())
|
||||
self.assertEqual(
|
||||
[section.intent for section in outline.sections],
|
||||
[
|
||||
"problem_value",
|
||||
"principles",
|
||||
"workflow",
|
||||
"installation",
|
||||
"quickstart",
|
||||
"configuration",
|
||||
"verification",
|
||||
"limits_next",
|
||||
],
|
||||
)
|
||||
```
|
||||
|
||||
Extend the schema test to validate a `readme` brief and outline instance with
|
||||
`jsonschema.Draft202012Validator`.
|
||||
|
||||
- [ ] **Step 2: Run the focused tests and verify RED**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
PYTHONPATH=src python3 -m unittest \
|
||||
tests.test_models.ModelTests.test_readme_brief_round_trip \
|
||||
tests.test_structures.StructureTests.test_readme_outline_preserves_reader_onboarding_order \
|
||||
tests.test_schemas.SchemaTests.test_readme_is_accepted_by_brief_and_outline_schemas -v
|
||||
```
|
||||
|
||||
Expected: failures because `"readme"` is not in the runtime enum or schemas.
|
||||
|
||||
- [ ] **Step 3: Implement the README type and deterministic outline**
|
||||
|
||||
Add:
|
||||
|
||||
```python
|
||||
class DocumentType(str, Enum):
|
||||
...
|
||||
README = "readme"
|
||||
```
|
||||
|
||||
Add eight `SectionSpec` entries under `DocumentType.README` using the approved
|
||||
intent order. Each section must have Korean and English titles, reader
|
||||
questions, purposes, and concrete `must_include` fields. Add `"readme"` to the
|
||||
two schema enums.
|
||||
|
||||
- [ ] **Step 4: Run the focused tests and verify GREEN**
|
||||
|
||||
Run the Step 2 command.
|
||||
|
||||
Expected: all three tests pass.
|
||||
|
||||
- [ ] **Step 5: Commit the model contract**
|
||||
|
||||
```bash
|
||||
git add src/claridoc/models.py src/claridoc/structures.py \
|
||||
schemas/brief.schema.json schemas/outline.schema.json \
|
||||
tests/test_models.py tests/test_schemas.py tests/test_structures.py
|
||||
git commit -m "feat: add README document contract"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 2: Centralize the Korean experience-prose prompt contract
|
||||
|
||||
**Files:**
|
||||
- Create: `src/claridoc/style_contracts.py`
|
||||
- Modify: `src/claridoc/prompts.py`
|
||||
- Modify: `tests/test_prompts.py`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: `Brief.is_korean`, `Brief.document_type`, and `constraints.style_profile`.
|
||||
- Produces:
|
||||
|
||||
```python
|
||||
KOREAN_EXPERIENCE_CONTRACT_ID = "korean_first_person_experience_v1"
|
||||
def korean_experience_contract_applies(brief: Brief) -> bool: ...
|
||||
def style_guidance(brief: Brief) -> str: ...
|
||||
def mandatory_style_review_checks(brief: Brief) -> str: ...
|
||||
def revision_style_protocol(brief: Brief) -> str: ...
|
||||
```
|
||||
|
||||
- [ ] **Step 1: Write failing prompt propagation tests**
|
||||
|
||||
Replace the narrow ordinal-only prompt test with separate tests that assert:
|
||||
|
||||
```python
|
||||
for prompt in (draft, review, revision):
|
||||
self.assertIn("korean_first_person_experience_v1", prompt)
|
||||
self.assertIn("저는", prompt)
|
||||
self.assertIn("제가", prompt)
|
||||
self.assertIn("했습니다", prompt)
|
||||
self.assertIn("현재 동작과 기술 설명", prompt)
|
||||
```
|
||||
|
||||
Add a Korean `readme` case with the same assertions, an English technical-blog
|
||||
case that does not contain the contract ID, and a Korean `tutorial` case that
|
||||
does not contain the contract ID. Assert that review asks whether first person
|
||||
represents a real observation and revision asks for a whole-document recheck.
|
||||
|
||||
- [ ] **Step 2: Run prompt tests and verify RED**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
PYTHONPATH=src python3 -m unittest tests.test_prompts -v
|
||||
```
|
||||
|
||||
Expected: contract-ID and README propagation assertions fail.
|
||||
|
||||
- [ ] **Step 3: Implement the shared contract module**
|
||||
|
||||
Move the existing Korean technical-blog profile out of `prompts.py`. Return a
|
||||
single provider-facing contract for the approved activation cases. Include:
|
||||
|
||||
```text
|
||||
concrete starting point
|
||||
→ initial expectation
|
||||
→ observed difference
|
||||
→ immediate term explanation
|
||||
→ author action or decision
|
||||
→ result, cost, or remaining limit
|
||||
```
|
||||
|
||||
Require `했습니다` for performed or observed work and `합니다` for current
|
||||
behavior. State that `저는/제가` must establish a supported experience, not
|
||||
decorate an objective explanation. State that unsupported conversations,
|
||||
emotions, failures, durations, results, and rationales are forbidden.
|
||||
|
||||
- [ ] **Step 4: Inject the shared contract into every provider stage**
|
||||
|
||||
Make planning and drafting call `style_guidance(brief)`. Add
|
||||
`mandatory_style_review_checks(brief)` to the mandatory review section and
|
||||
`revision_style_protocol(brief)` to the revision protocol. Keep ordinal-frame
|
||||
guidance inside the shared contract so no abbreviated duplicate remains in
|
||||
`prompts.py`.
|
||||
|
||||
- [ ] **Step 5: Run prompt tests and verify GREEN**
|
||||
|
||||
Run the Step 2 command.
|
||||
|
||||
Expected: all prompt tests pass.
|
||||
|
||||
- [ ] **Step 6: Commit prompt integration**
|
||||
|
||||
```bash
|
||||
git add src/claridoc/style_contracts.py src/claridoc/prompts.py tests/test_prompts.py
|
||||
git commit -m "feat: propagate Korean prose contract to providers"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 3: Add Markdown-aware deterministic style lint
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/claridoc/style_contracts.py`
|
||||
- Modify: `src/claridoc/lint.py`
|
||||
- Modify: `tests/test_lint.py`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: `korean_experience_contract_applies(brief)` and Markdown text.
|
||||
- Produces:
|
||||
|
||||
```python
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class ReaderProseSegment:
|
||||
text: str
|
||||
line: int
|
||||
h2_title: str | None
|
||||
|
||||
def reader_prose_segments(markdown: str) -> list[ReaderProseSegment]: ...
|
||||
def plain_form_ending_locations(markdown: str) -> list[int]: ...
|
||||
def first_person_metrics(markdown: str) -> dict[str, int | float | bool]: ...
|
||||
```
|
||||
|
||||
and lint codes `STYLE002` and `STYLE003`.
|
||||
|
||||
- [ ] **Step 1: Write a failing formal-ending lint test**
|
||||
|
||||
Create a Korean experience-contract brief and a structurally valid document,
|
||||
then replace one prose sentence with `현재 구현은 이 값을 사용한다.`. Assert:
|
||||
|
||||
```python
|
||||
issues = [issue for issue in report.issues if issue.code == "STYLE002"]
|
||||
self.assertEqual(len(issues), 1)
|
||||
self.assertEqual(issues[0].severity, Severity.BLOCKER)
|
||||
self.assertEqual(report.metrics["plain_form_ending_count"], 1)
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Run the focused test and verify RED**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
PYTHONPATH=src python3 -m unittest \
|
||||
tests.test_lint.LintTests.test_korean_experience_contract_blocks_plain_form_endings -v
|
||||
```
|
||||
|
||||
Expected: `STYLE002` is absent.
|
||||
|
||||
- [ ] **Step 3: Implement minimal Markdown prose extraction and ending lint**
|
||||
|
||||
Track fenced-code state and current H2 while scanning lines. Exclude headings,
|
||||
block quotations, tables, image-only lines, and command-output blocks. Remove
|
||||
inline code, Markdown link targets, and paired quoted spans before matching
|
||||
plain Korean declarative endings with a boundary that does not match `니다.`.
|
||||
Consolidate all matches into one blocker and record the total count.
|
||||
|
||||
- [ ] **Step 4: Run the focused test and verify GREEN**
|
||||
|
||||
Run the Step 2 command.
|
||||
|
||||
Expected: the test passes.
|
||||
|
||||
- [ ] **Step 5: Write failing exclusion tests**
|
||||
|
||||
Build a document whose fenced code, heading, table cell, block quote, image alt
|
||||
text, inline code, and direct quoted example contain `한다.` while reader prose
|
||||
uses `합니다.`. Assert that `STYLE002` is absent and
|
||||
`plain_form_ending_count == 0`.
|
||||
|
||||
- [ ] **Step 6: Run the exclusion test and verify RED**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
PYTHONPATH=src python3 -m unittest \
|
||||
tests.test_lint.LintTests.test_korean_style_lint_exempts_non_reader_prose -v
|
||||
```
|
||||
|
||||
Expected: at least one exempt region is incorrectly counted until all
|
||||
exclusions are implemented.
|
||||
|
||||
- [ ] **Step 7: Complete the exclusion parser and verify GREEN**
|
||||
|
||||
Refine `reader_prose_segments` only as needed for the failing examples. Do not
|
||||
implement a general Markdown parser or add a dependency.
|
||||
|
||||
- [ ] **Step 8: Write failing first-person coverage tests**
|
||||
|
||||
Add tests for:
|
||||
|
||||
- no `저는/제가` in the opening;
|
||||
- fewer than half of substantive H2 sections containing a marker;
|
||||
- table-only and code-only H2 sections not entering the denominator;
|
||||
- opening plus at least half of substantive sections passing.
|
||||
|
||||
Assert `STYLE003` is one consolidated blocker and that the metrics contain the
|
||||
approved contract ID, counts, and coverage.
|
||||
|
||||
- [ ] **Step 9: Run coverage tests and verify RED**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
PYTHONPATH=src python3 -m unittest \
|
||||
tests.test_lint.LintTests.test_korean_style_lint_requires_first_person_opening \
|
||||
tests.test_lint.LintTests.test_korean_style_lint_requires_major_section_coverage \
|
||||
tests.test_lint.LintTests.test_korean_style_lint_ignores_non_prose_sections \
|
||||
tests.test_lint.LintTests.test_korean_style_lint_accepts_compliant_experience_prose -v
|
||||
```
|
||||
|
||||
Expected: missing `STYLE003` and metrics failures.
|
||||
|
||||
- [ ] **Step 10: Implement first-person metrics and verify GREEN**
|
||||
|
||||
Treat the first substantive reader-prose paragraph as the opening. Count each
|
||||
substantive H2 at most once. Require an opening marker and
|
||||
`marked_sections / substantive_sections >= 0.5`. If there are no substantive
|
||||
H2 sections, let existing structure checks handle the empty document while
|
||||
recording zero coverage.
|
||||
|
||||
- [ ] **Step 11: Run all lint tests**
|
||||
|
||||
```bash
|
||||
PYTHONPATH=src python3 -m unittest tests.test_lint -v
|
||||
```
|
||||
|
||||
Expected: style tests pass; fixture-dependent failures, if any, identify the
|
||||
next migration task rather than being hidden.
|
||||
|
||||
- [ ] **Step 12: Commit deterministic enforcement**
|
||||
|
||||
```bash
|
||||
git add src/claridoc/style_contracts.py src/claridoc/lint.py tests/test_lint.py
|
||||
git commit -m "feat: block Korean prose contract violations"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 4: Make maintained fixtures satisfy the enforced contract
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/claridoc/providers/mock.py`
|
||||
- Modify: `examples/golden/application-core-spring-di-boundary.md`
|
||||
- Modify: `tests/test_lint.py`
|
||||
- Modify: `tests/test_pipeline.py`
|
||||
- Modify: `src/claridoc/report.py`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: new style metrics and existing mock `draft`/`revise` stages.
|
||||
- Produces: contract-compliant mock Korean technical-blog prose and quality
|
||||
reports that expose the active style contract and metrics.
|
||||
|
||||
- [ ] **Step 1: Add failing mock-pipeline and report assertions**
|
||||
|
||||
In `test_end_to_end_mock_run_creates_auditable_artifacts`, assert:
|
||||
|
||||
```python
|
||||
self.assertEqual(
|
||||
result.rounds[-1].lint_report.metrics["style_contract"],
|
||||
"korean_first_person_experience_v1",
|
||||
)
|
||||
self.assertIn("korean_first_person_experience_v1", report_text)
|
||||
```
|
||||
|
||||
Add a pipeline test that supplies a provider document with a `STYLE002`
|
||||
violation and sets `max_errors` above zero; assert `result.passed` is false and
|
||||
the blocker appears in `quality-gate.json`.
|
||||
|
||||
- [ ] **Step 2: Run pipeline and golden tests and verify RED**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
PYTHONPATH=src python3 -m unittest \
|
||||
tests.test_pipeline \
|
||||
tests.test_lint.LintTests.test_golden_application_core_example_has_no_material_lint_issue -v
|
||||
```
|
||||
|
||||
Expected: the report omits style metrics and maintained fixtures fail the new
|
||||
blockers.
|
||||
|
||||
- [ ] **Step 3: Update mock prose without weakening lint**
|
||||
|
||||
Revise the mock technical-blog generator so its opening and at least half of
|
||||
its H2 sections use supported `저는/제가` experience transitions and all
|
||||
reader-facing Korean sentences use `합니다/했습니다`. Preserve synthetic
|
||||
fixture warnings and never describe mock prose as quality evidence.
|
||||
|
||||
- [ ] **Step 4: Migrate the golden document**
|
||||
|
||||
Use the `revising-korean-technical-prose` skill to revise the golden document
|
||||
in place. Preserve its exact H1/H2 contract, technical claims, decision
|
||||
rationale, code block, evidence boundaries, and length intent.
|
||||
|
||||
- [ ] **Step 5: Render style metrics in the run report**
|
||||
|
||||
Add a `Reader-prose contract` subsection when
|
||||
`final.lint_report.metrics["style_contract"] != "none"`. Render contract ID,
|
||||
plain-ending count, first-person marker count, substantive-section count, and
|
||||
coverage.
|
||||
|
||||
- [ ] **Step 6: Run pipeline and lint tests and verify GREEN**
|
||||
|
||||
Run the Step 2 command.
|
||||
|
||||
Expected: all tests pass and the report contains contract evidence.
|
||||
|
||||
- [ ] **Step 7: Commit fixture and report integration**
|
||||
|
||||
```bash
|
||||
git add src/claridoc/providers/mock.py src/claridoc/report.py \
|
||||
examples/golden/application-core-spring-di-boundary.md \
|
||||
tests/test_lint.py tests/test_pipeline.py
|
||||
git commit -m "test: migrate maintained Korean prose fixtures"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 5: Restore the technical-document authoring skill
|
||||
|
||||
**Files:**
|
||||
- Create: `.agents/skills/technical-document-author/SKILL.md`
|
||||
- Create: `.agents/skills/technical-document-author/references/logic-contract.md`
|
||||
- Create: `.agents/skills/technical-document-author/references/review-rubric.md`
|
||||
- Create: `.agents/skills/technical-document-author/agents/openai.yaml`
|
||||
- Create: `tests/test_repository_contracts.py`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: repository `AGENTS.md`, the ClariDoc pipeline, and
|
||||
`revising-korean-technical-prose`.
|
||||
- Produces: the authoring skill path already required by `AGENTS.md`, with a
|
||||
validation-artifact completion contract.
|
||||
|
||||
- [ ] **Step 1: Invoke the skill-writing guidance**
|
||||
|
||||
Read and follow both `skill-creator` and `superpowers:writing-skills` before
|
||||
creating the skill files.
|
||||
|
||||
- [ ] **Step 2: Write a failing repository-contract test**
|
||||
|
||||
Assert that the four skill files exist and that `SKILL.md` contains:
|
||||
|
||||
```text
|
||||
Brief
|
||||
SourcePack
|
||||
STRUCTURE_SPECS
|
||||
revising-korean-technical-prose
|
||||
quality-gate.json
|
||||
provenance
|
||||
```
|
||||
|
||||
Also assert that the skill tells authors not to claim completion without lint,
|
||||
independent review, and quality-gate artifacts.
|
||||
|
||||
- [ ] **Step 3: Run the repository-contract test and verify RED**
|
||||
|
||||
```bash
|
||||
PYTHONPATH=src python3 -m unittest \
|
||||
tests.test_repository_contracts.RepositoryContractTests.test_technical_author_skill_is_complete -v
|
||||
```
|
||||
|
||||
Expected: failure because the required skill path is absent.
|
||||
|
||||
- [ ] **Step 4: Create the authoring skill and references**
|
||||
|
||||
The skill must route every document through the repository sequence, treat
|
||||
inputs as untrusted data, keep provenance out of reader prose, and invoke the
|
||||
Korean revision skill for Korean technical blogs and READMEs. The review rubric
|
||||
must separate deterministic findings from model judgment. The logic contract
|
||||
must preserve context, choice, reason, alternative, accepted cost, guardrail,
|
||||
verification, and evidence status.
|
||||
|
||||
- [ ] **Step 5: Run the repository-contract test and verify GREEN**
|
||||
|
||||
Run the Step 3 command.
|
||||
|
||||
Expected: pass.
|
||||
|
||||
- [ ] **Step 6: Commit the restored skill**
|
||||
|
||||
```bash
|
||||
git add .agents/skills/technical-document-author tests/test_repository_contracts.py
|
||||
git commit -m "feat: restore technical document author skill"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 6: Revise and document the repository README
|
||||
|
||||
**Files:**
|
||||
- Modify: `README.md`
|
||||
- Create: `examples/briefs/claridoc-readme.json`
|
||||
- Modify: `tests/test_schemas.py`
|
||||
- Modify: `tests/test_cli.py`
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: `DocumentType.README`, shared prompt contract, and CLI
|
||||
`validate`/`outline` behavior.
|
||||
- Produces: a schema-valid README brief, documented usage, and a repository
|
||||
README written in the enforced style.
|
||||
|
||||
- [ ] **Step 1: Write failing example and CLI tests**
|
||||
|
||||
Add tests that load `examples/briefs/claridoc-readme.json`, validate it through
|
||||
`Brief.from_dict`, and run the CLI `validate` and `outline` commands. Assert
|
||||
that the outline reports type `readme` and the eight approved intents.
|
||||
|
||||
- [ ] **Step 2: Run the focused tests and verify RED**
|
||||
|
||||
```bash
|
||||
PYTHONPATH=src python3 -m unittest \
|
||||
tests.test_schemas.SchemaTests.test_examples_match_runtime_contracts \
|
||||
tests.test_cli.CliTests.test_readme_brief_validates_and_outlines -v
|
||||
```
|
||||
|
||||
Expected: failure because the README brief does not yet exist.
|
||||
|
||||
- [ ] **Step 3: Add the README brief fixture**
|
||||
|
||||
Create a Korean `readme` brief for ClariDoc with hidden citations,
|
||||
`style_profile: "auto"`, the current project scope, and no invented operational
|
||||
claims.
|
||||
|
||||
- [ ] **Step 4: Run the focused tests and verify GREEN**
|
||||
|
||||
Run the Step 2 command.
|
||||
|
||||
Expected: pass.
|
||||
|
||||
- [ ] **Step 5: Revise README in place**
|
||||
|
||||
Use `revising-korean-technical-prose` and its sentence-pattern reference.
|
||||
Preserve commands, tables, links, diagrams, versions, source hierarchy,
|
||||
provider descriptions, and safety statements. Convert reader-facing Korean
|
||||
prose to `합니다/했습니다`, add supported `저는/제가` experience transitions,
|
||||
and add a section describing:
|
||||
|
||||
- automatic activation for Korean technical blogs and READMEs;
|
||||
- `STYLE002` and `STYLE003`;
|
||||
- model-review responsibilities;
|
||||
- a `readme` brief example and validation command.
|
||||
|
||||
- [ ] **Step 6: Scan the README contract**
|
||||
|
||||
Run a read-only scanner using `reader_prose_segments` and assert:
|
||||
|
||||
```text
|
||||
plain_form_ending_count = 0
|
||||
opening_has_first_person = true
|
||||
experience_section_coverage >= 0.5
|
||||
```
|
||||
|
||||
Review the diff to confirm facts, code blocks, links, and information order
|
||||
remain intact.
|
||||
|
||||
- [ ] **Step 7: Commit README migration**
|
||||
|
||||
```bash
|
||||
git add README.md examples/briefs/claridoc-readme.json \
|
||||
tests/test_schemas.py tests/test_cli.py
|
||||
git commit -m "docs: apply Korean prose contract to README"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 7: Run regression validation and review the implementation
|
||||
|
||||
**Files:**
|
||||
- Modify only files required by verified failures in the preceding tasks.
|
||||
|
||||
**Interfaces:**
|
||||
- Consumes: all implemented tasks.
|
||||
- Produces: test and review evidence with no regenerated user-owned build or
|
||||
distribution artifacts.
|
||||
|
||||
- [ ] **Step 1: Run the full unit and integration suite**
|
||||
|
||||
```bash
|
||||
PYTHONPATH=src python3 -m unittest discover -s tests -v
|
||||
```
|
||||
|
||||
Expected: all tests pass.
|
||||
|
||||
- [ ] **Step 2: Run non-destructive contract commands**
|
||||
|
||||
```bash
|
||||
PYTHONPATH=src python3 -m claridoc validate \
|
||||
--brief examples/briefs/claridoc-readme.json \
|
||||
--sources examples/sources/retry-policy-sources.json
|
||||
|
||||
PYTHONPATH=src python3 -m claridoc outline \
|
||||
--brief examples/briefs/claridoc-readme.json \
|
||||
--sources examples/sources/retry-policy-sources.json \
|
||||
--output /tmp/claridoc-readme-outline.json
|
||||
```
|
||||
|
||||
Expected: both commands succeed and the output uses `document_type: readme`.
|
||||
|
||||
- [ ] **Step 3: Inspect destructive verification scope**
|
||||
|
||||
Do not run `scripts/verify.sh` because it removes and rebuilds `.verify`,
|
||||
`build`, `dist`, egg-info, and demo outputs that already contain user changes.
|
||||
Run its non-destructive validation portions through the unit suite, schema
|
||||
tests, CLI tests, JSON parsing, local-link scan, and an isolated wheel build in
|
||||
`/tmp`.
|
||||
|
||||
- [ ] **Step 4: Run independent code review**
|
||||
|
||||
Use `superpowers:requesting-code-review` to inspect the final diff against the
|
||||
design and plan. Resolve every blocker and error through a new failing test
|
||||
before changing production code.
|
||||
|
||||
- [ ] **Step 5: Run verification-before-completion**
|
||||
|
||||
Use `superpowers:verification-before-completion`, rerun the full test suite,
|
||||
README style scan, schema validation, and isolated package build, and record
|
||||
the exact results.
|
||||
|
||||
- [ ] **Step 6: Finish the development branch**
|
||||
|
||||
Use `superpowers:finishing-a-development-branch`. Because the user explicitly
|
||||
requested uninterrupted inline implementation on the current branch, do not
|
||||
merge, push, or open a PR without a new explicit request.
|
||||
@@ -1,292 +0,0 @@
|
||||
# Korean Experience-Prose Contract Design
|
||||
|
||||
## Goal
|
||||
|
||||
ClariDoc must apply one enforceable Korean prose contract when it writes or
|
||||
reviews a Korean technical blog or Korean README. The contract must preserve
|
||||
facts and document structure while making the reader follow the author's
|
||||
experience in consistent `합니다/했습니다` prose.
|
||||
|
||||
The change closes the gap between a skill file that describes the desired
|
||||
style and a harness that currently neither passes that style to providers nor
|
||||
checks it before returning `PASS`.
|
||||
|
||||
## Scope
|
||||
|
||||
The contract applies automatically to:
|
||||
|
||||
- a Korean `technical_blog` using `auto`, `woowahan_tech_blog_ko`, or
|
||||
`korean_problem_solving_blog`;
|
||||
- every Korean `readme`.
|
||||
|
||||
It does not force first-person retrospective prose onto tutorials, how-to
|
||||
guides, references, troubleshooting guides, explanations, or design documents.
|
||||
Those document types keep their existing style behavior.
|
||||
|
||||
The current repository `README.md` is part of the migration. Its factual
|
||||
content, commands, links, tables, and overall information order remain intact,
|
||||
but its reader-facing Korean prose is revised to the same experience-oriented
|
||||
`합니다/했습니다` style.
|
||||
|
||||
## Considered Approaches
|
||||
|
||||
### Prompt-only guidance
|
||||
|
||||
Copy the skill text into the drafting prompt. This has the smallest code
|
||||
change, but it leaves no objective proof that the writer or reviser kept the
|
||||
rules. It would preserve the current failure mode in which one correction
|
||||
causes another part of the document to regress.
|
||||
|
||||
### Opt-in style profile only
|
||||
|
||||
Require README authors to select a special `style_profile`. This avoids adding
|
||||
a document type, but a missing configuration value silently disables the
|
||||
contract. It also makes README structure masquerade as another document type.
|
||||
|
||||
### Shared contract with a first-class README type
|
||||
|
||||
Add `readme` to the document model and define one shared prose contract used by
|
||||
prompts, lint, reviews, revisions, reports, and tests. This is the selected
|
||||
approach because it makes activation explicit and lets deterministic and model
|
||||
judgment checks cover different parts of the same contract.
|
||||
|
||||
## Architecture
|
||||
|
||||
### First-class README document type
|
||||
|
||||
`DocumentType.README` is added to the model and JSON schemas. Its deterministic
|
||||
outline contains these intents in order:
|
||||
|
||||
1. `problem_value`: the concrete problem and why the project exists;
|
||||
2. `principles`: the project behavior and boundaries readers must understand;
|
||||
3. `workflow`: the end-to-end operating flow;
|
||||
4. `installation`: prerequisites and installation;
|
||||
5. `quickstart`: the smallest useful execution path and expected result;
|
||||
6. `configuration`: the main configuration choices and their effects;
|
||||
7. `verification`: how to verify success and diagnose common failure;
|
||||
8. `limits_next`: evidence limits, unsupported claims, and the next relevant
|
||||
action.
|
||||
|
||||
The planner may refine titles and evidence allocation, but it must preserve
|
||||
these intents and their order just as it does for existing document types.
|
||||
|
||||
### Shared prose contract
|
||||
|
||||
A focused `claridoc.style_contracts` module owns activation and provider-facing
|
||||
guidance. It exposes:
|
||||
|
||||
```python
|
||||
def korean_experience_contract_applies(brief: Brief) -> bool: ...
|
||||
|
||||
def style_guidance(brief: Brief) -> str: ...
|
||||
```
|
||||
|
||||
The returned guidance includes the same rules in every provider stage:
|
||||
|
||||
- open the document and major transitions from a concrete code, screen,
|
||||
request, or problem the author encountered;
|
||||
- show the initial expectation, then the observed difference;
|
||||
- explain an unfamiliar term where it first becomes necessary;
|
||||
- show what the author checked, selected, or changed;
|
||||
- close the thread with the result, accepted cost, or remaining problem;
|
||||
- use `저는` or `제가` where it establishes the experience, without repeating
|
||||
it mechanically in every sentence;
|
||||
- use `했습니다` for observed or performed work and `합니다` for current
|
||||
behavior and technical explanation;
|
||||
- never invent an emotion, conversation, failure, duration, result, or
|
||||
technical rationale that the evidence does not support;
|
||||
- preserve code, commands, identifiers, numbers, links, tables, diagrams,
|
||||
claims, evidence status, and outline order.
|
||||
|
||||
The guidance describes the canonical paragraph pattern as form, not as facts
|
||||
to copy:
|
||||
|
||||
```text
|
||||
concrete starting point
|
||||
→ initial expectation
|
||||
→ observed difference
|
||||
→ immediate term explanation
|
||||
→ author action or decision
|
||||
→ result, cost, or remaining limit
|
||||
```
|
||||
|
||||
`drafting_prompt`, `review_prompt`, and `revision_prompt` all call this shared
|
||||
module. No stage keeps a separate abbreviated version.
|
||||
|
||||
### Deterministic checks
|
||||
|
||||
Deterministic lint checks only properties that can be recognized without
|
||||
guessing the author's intent.
|
||||
|
||||
`STYLE002` reports a blocker when reader-facing prose mixes plain declarative
|
||||
endings such as `한다.`, `있다.`, `아니다.`, or `~했다.` into a document whose
|
||||
contract requires `합니다/했습니다`. Fenced code, headings, Markdown tables,
|
||||
block quotations, image alt text, command output, and quoted spans are excluded.
|
||||
The report consolidates matches and records their count and first locations.
|
||||
|
||||
`STYLE003` reports a blocker when the opening has no explicit `저는` or `제가`
|
||||
marker, or when fewer than half of substantive H2 sections contain an explicit
|
||||
first-person experience marker. A substantive section is an H2 section with at
|
||||
least one reader-facing prose paragraph; code-only and table-only sections do
|
||||
not count.
|
||||
|
||||
The lint report adds:
|
||||
|
||||
- `style_contract`: `korean_first_person_experience_v1` or `none`;
|
||||
- `plain_form_ending_count`;
|
||||
- `first_person_marker_count`;
|
||||
- `experience_section_count`;
|
||||
- `experience_section_coverage`.
|
||||
|
||||
Because both style issues are blockers, configured error tolerances cannot turn
|
||||
them into a passing result.
|
||||
|
||||
Deterministic lint does not try to decide whether a paragraph contains a
|
||||
genuine discovery, whether a term is unfamiliar, or whether the prose sounds
|
||||
natural. Those require model judgment.
|
||||
|
||||
### Independent review and revision
|
||||
|
||||
Every reviewer role receives mandatory prose checks when the contract applies:
|
||||
|
||||
- the opening and major transitions follow an experience rather than listing
|
||||
settled facts;
|
||||
- the paragraph presents an actual expectation or observation rather than
|
||||
inserting `저는` as decoration;
|
||||
- unfamiliar terms are explained at first need;
|
||||
- contrasts name the actual component and behavior that differ;
|
||||
- the document does not manufacture personal history or project rationale;
|
||||
- `합니다/했습니다` remains consistent outside exempt Markdown regions.
|
||||
|
||||
The revision prompt requires a whole-document contract audit after resolving
|
||||
individual findings. This prevents a local rewrite from regressing another
|
||||
section. Each revision round already runs lint and independent reviews again,
|
||||
so the shared contract is re-evaluated before the quality gate can pass.
|
||||
|
||||
### Skill entry point
|
||||
|
||||
The dangling `.agents/skills/technical-document-author/SKILL.md` reference is
|
||||
replaced with a real authoring skill. It preserves the repository sequence:
|
||||
|
||||
```text
|
||||
Brief
|
||||
→ SourcePack
|
||||
→ deterministic outline
|
||||
→ draft
|
||||
→ lint and independent reviews
|
||||
→ revision
|
||||
→ quality gate
|
||||
→ reader document and provenance artifacts
|
||||
```
|
||||
|
||||
For Korean technical blogs and Korean READMEs, the authoring skill requires the
|
||||
Korean prose contract and its sentence-pattern reference. It may not claim
|
||||
completion without lint, review, and quality-gate artifacts. The existing
|
||||
`revising-korean-technical-prose` skill remains the focused in-place revision
|
||||
skill.
|
||||
|
||||
## Data Flow
|
||||
|
||||
```text
|
||||
Brief(document_type, language, style_profile)
|
||||
→ style-contract activation
|
||||
→ planner keeps deterministic document structure
|
||||
→ writer receives shared prose guidance
|
||||
→ deterministic lint checks endings and first-person coverage
|
||||
→ every reviewer checks experience quality and factual boundaries
|
||||
→ reviser receives the same guidance plus all findings
|
||||
→ lint and reviews run again
|
||||
→ blockers prevent PASS
|
||||
→ report records style metrics and findings
|
||||
```
|
||||
|
||||
## README Migration
|
||||
|
||||
The repository `README.md` is revised in place with the
|
||||
`revising-korean-technical-prose` skill:
|
||||
|
||||
- existing facts, code blocks, commands, paths, links, tables, and diagrams are
|
||||
preserved;
|
||||
- Korean reader-facing prose uses `합니다/했습니다`;
|
||||
- the opening and major transitions explain how the harness's failure modes
|
||||
were encountered and how the implemented workflow addresses them;
|
||||
- no unverified personal event, advice, measurement, or project rationale is
|
||||
added;
|
||||
- a section documents the activation scope, lint codes, review behavior, and
|
||||
`readme` brief usage.
|
||||
|
||||
The migration is checked separately from generated documents because the
|
||||
repository README is not itself a pipeline output artifact.
|
||||
|
||||
## Error Handling
|
||||
|
||||
- Invalid `document_type: readme` handling disappears once the enum and schemas
|
||||
are updated; other unknown types remain validation errors.
|
||||
- Style lint returns actionable locations and correction guidance rather than
|
||||
rewriting content.
|
||||
- Empty or structure-only documents still fail existing structure and length
|
||||
checks; style metrics do not mask those failures.
|
||||
- Quoted evidence and code are excluded from deterministic ending checks so
|
||||
original material is not altered to satisfy prose style.
|
||||
- A model review cannot override a deterministic style blocker.
|
||||
|
||||
## Testing
|
||||
|
||||
Tests are added before production changes.
|
||||
|
||||
### Model and structure tests
|
||||
|
||||
- `readme` is accepted by `Brief` and outline schemas;
|
||||
- `readme` receives eight unique required intents in the specified order;
|
||||
- all existing document types retain their current outlines.
|
||||
|
||||
### Prompt tests
|
||||
|
||||
- Korean technical-blog and README draft, review, and revision prompts contain
|
||||
the same contract identifier and required rules;
|
||||
- English and unrelated Korean document types do not receive the contract;
|
||||
- the revision prompt requires a whole-document recheck.
|
||||
|
||||
### Lint tests
|
||||
|
||||
- mixed `한다/합니다` prose is a blocker;
|
||||
- fenced code, headings, tables, block quotations, image alt text, and quoted
|
||||
examples do not cause false positives;
|
||||
- missing opening first person is a blocker;
|
||||
- insufficient substantive-section coverage is a blocker;
|
||||
- a representative experience-oriented technical blog passes;
|
||||
- a representative Korean README passes;
|
||||
- unrelated document types retain existing lint behavior.
|
||||
|
||||
### Pipeline tests
|
||||
|
||||
- a style blocker prevents the quality gate from passing even when configured
|
||||
error tolerance is nonzero;
|
||||
- revision rounds receive the blocker and rerun the contract checks;
|
||||
- final artifacts record the style contract and findings.
|
||||
|
||||
### Repository validation
|
||||
|
||||
- targeted unit tests are run after each TDD cycle;
|
||||
- `PYTHONPATH=src python3 -m unittest discover -s tests -v` is run;
|
||||
- `bash scripts/verify.sh` is run if it can preserve the user's unrelated
|
||||
working-tree changes; otherwise its destructive build steps are inspected
|
||||
and an equivalent non-destructive validation set is reported explicitly;
|
||||
- the revised `README.md` is scanned outside code and quoted regions for plain
|
||||
declarative endings and reviewed against the experience-flow checklist.
|
||||
|
||||
## Success Criteria
|
||||
|
||||
The implementation is complete only when:
|
||||
|
||||
- Korean technical blogs and Korean READMEs receive the contract in every model
|
||||
stage;
|
||||
- omitting `합니다/했습니다` consistency or first-person experience coverage
|
||||
creates a deterministic blocker;
|
||||
- qualitative experience flow is a mandatory independent-review concern;
|
||||
- a revision cannot pass without rerunning the checks;
|
||||
- `readme` is a supported contract-first document type;
|
||||
- the missing technical-author skill entry point exists and requires validation
|
||||
artifacts;
|
||||
- the repository README follows and documents the same contract;
|
||||
- all targeted and full regression tests pass.
|
||||
@@ -1,46 +0,0 @@
|
||||
# Runtime Call / Source Dependency SVG Split Design
|
||||
|
||||
## Brief
|
||||
|
||||
Split the two panels in `runtime-call-source-dependency.svg` into two standalone SVG assets. Do not change reader-facing Markdown or remove the existing combined SVG.
|
||||
|
||||
## Local evidence
|
||||
|
||||
- The combined SVG is a `1400 × 660` canvas with an upper runtime-call panel and a lower source-dependency panel.
|
||||
- Identical assets exist in the generated run output and the golden fixture.
|
||||
- Both corresponding documents currently reference the combined SVG.
|
||||
- No maintained generator source for this asset exists in the repository; the metadata only names a historical `_work/regenerate-technical-assets.py` path.
|
||||
|
||||
## Output
|
||||
|
||||
Create these files in both asset directories:
|
||||
|
||||
- `runtime-call.svg`: the upper “실행 시점 관계” panel.
|
||||
- `source-dependency.svg`: the lower “계약 소유·소스 의존” panel.
|
||||
|
||||
Each file will be a complete, independently renderable SVG with:
|
||||
|
||||
- a tightly fitted canvas and `viewBox`;
|
||||
- its own accessible `<title>` and `<desc>`;
|
||||
- only the marker definitions it uses;
|
||||
- the same typography, colors, labels, nodes, and relationships as its source panel.
|
||||
|
||||
The existing `runtime-call-source-dependency.svg` remains unchanged for compatibility. Markdown references and alt text remain unchanged.
|
||||
|
||||
## Geometry
|
||||
|
||||
The panels will retain their original `1400`-unit width so horizontal proportions do not change. Vertical coordinates will be translated upward to remove the unused space belonging to the other panel. A small outer margin will be preserved around each panel.
|
||||
|
||||
The runtime-call asset will contain only `FeedController → GetFeedUseCase → SpringTransactionPort` and its solid-arrow labels. The source-dependency asset will contain only the interface, implementation, and dashed dependency relationships from the lower panel.
|
||||
|
||||
## Validation
|
||||
|
||||
- Parse all four new files as XML.
|
||||
- Confirm each SVG has the expected root dimensions, `viewBox`, title, description, and referenced marker definitions.
|
||||
- Confirm the runtime asset excludes lower-panel labels and the source-dependency asset excludes upper-panel labels.
|
||||
- Confirm the golden and run-output copies are byte-identical for each new asset.
|
||||
- Render or inspect both assets to catch clipping and layout regressions.
|
||||
|
||||
## Scope boundary
|
||||
|
||||
This change does not revise document prose, document image references, the existing combined asset, the technical-writing pipeline, or the asset-generation system.
|
||||
Reference in New Issue
Block a user