/output/
+ entrypoint: index.html
+ manifest: manifest.yaml
+ condition: reviewed publication draft or accepted integration-ready ArtifactSet
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: packages/workflow-runtime/README.md
+ line-start: 216
+ line-end: 221
+ source-kind: runtime-documentation
+ - path: tests/runtime/test_output_bundle.py
+ line-start: 176
+ line-end: 204
+ symbol: test_bundle_is_portable_and_manifest_hashes_match
+ source-kind: runtime-test
+
+ - id: F-LOCAL-CROSS-HARNESS-OUTPUT
+ category: artifacts
+ key: local-cross-harness-test-output
+ value:
+ root: runs/p6-all-harness-quality-executable-clean-architecture-20260717/output
+ generated-document: [README.md, final-document.md, index.html, preview.png]
+ technical-visualization: [assets/dependency-directions.document.svg, assets/dependency-directions.presentation.svg]
+ image-generation: [assets/editorial-workbench.document.png, assets/editorial-workbench.presentation.png, assets/image-candidates.png]
+ validation: validation-summary.yaml
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: runs/p6-all-harness-quality-executable-clean-architecture-20260717/output/manifest.yaml
+ line-start: 1
+ line-end: 35
+ source-kind: local-generated-output-manifest
+ - path: runs/p6-all-harness-quality-executable-clean-architecture-20260717/output/README.md
+ line-start: 1
+ line-end: 12
+ source-kind: local-generated-document
+ - path: runs/p6-all-harness-quality-executable-clean-architecture-20260717/output/preview.png
+ source-kind: local-generated-preview
+
+ - id: F-LOCAL-DOCUMENT-VISUALIZATION
+ category: artifacts
+ key: local-document-visualization-test-output
+ value:
+ root: runs/docvis-20260716-executable-clean-architecture-part1
+ document-output: document/part1-integrated.html
+ figures: [fig-invisible-shortcut, fig-enforcement-gradient]
+ formats: [desktop-SVG, mobile-SVG, PNG-fallback]
+ previews: [integrated-previews/part1-desktop.png, integrated-previews/part1-mobile-v2.png]
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: runs/docvis-20260716-executable-clean-architecture-part1/delivery/delivery-manifest.yaml
+ line-start: 1
+ line-end: 24
+ source-kind: local-delivery-manifest
+ - path: runs/docvis-20260716-executable-clean-architecture-part1/figures/fig-enforcement-gradient/asset-manifest.yaml
+ line-start: 1
+ line-end: 30
+ source-kind: local-figure-manifest
+
+ - id: F-LOCAL-IMAGE-OUTPUT
+ category: artifacts
+ key: local-best-of-three-image-test-output
+ value:
+ root: runs/img-20260716-japanese-animation-test
+ generation-candidates: 3
+ selected-attempt: 2
+ selected-output: outputs/final-selected.png
+ selection-label: BEST_OF_N_PASS
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: runs/img-20260716-japanese-animation-test/selection.json
+ line-start: 1
+ line-end: 64
+ source-kind: local-selection-record
+ - path: runs/img-20260716-japanese-animation-test/outputs/final-selected.png
+ source-kind: local-generated-image
+
+ - id: F-RUNS-NONCANONICAL
+ category: limitation
+ key: local-run-durability
+ value: runs/** is ignored local operational data, not a cache or source of truth; reusable examples belong under examples, regression oracles under tests/golden, and evaluation corpora under benchmarks
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: .gitignore
+ line-start: 5
+ line-end: 7
+ source-kind: ignore-policy
+ - path: runs/README.md
+ line-start: 1
+ line-end: 7
+ source-kind: runtime-workspace-policy
+ - path: docs/README.md
+ line-start: 23
+ line-end: 35
+ source-kind: documentation-policy
+
+ - id: F-PREREQUISITES
+ category: prerequisites
+ key: runtime-tools
+ value:
+ language: Python 3
+ python-packages: [PyYAML, jsonschema, Pillow]
+ feature-specific-tools:
+ technical-rendering: D2
+ SVG-preview: Chrome or Chromium
+ version-pins: not declared
+ assertion-type: derived
+ confidence: high
+ evidence:
+ - path: README.md
+ line-start: 151
+ line-end: 153
+ source-kind: project-documentation
+ - path: packages/schema-support/src/contract_support.py
+ line-start: 13
+ line-end: 14
+ source-kind: dependency-import
+ - path: packages/export-validator/src/validate_export.py
+ line-start: 1
+ line-end: 14
+ source-kind: dependency-import
+ - path: harnesses/technical-visualization/renderers/d2/renderer.py
+ line-start: 206
+ line-end: 213
+ source-kind: renderer-implementation
+ - path: harnesses/image-generation/scripts/render_svg_preview.py
+ line-start: 18
+ line-end: 31
+ source-kind: preview-implementation
+
+ - id: F-NO-PACKAGE-MANIFEST
+ category: limitation
+ key: dependency-installation-metadata
+ value: no pyproject.toml, requirements.txt, setup.py, setup.cfg, Pipfile, poetry.lock, or uv.lock is present; dependency versions and one canonical installation command cannot be evidenced
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: .
+ source-kind: repository-file-scan
+
+ - id: F-TEST-INVENTORY
+ category: tests
+ key: unittest-suite
+ value:
+ framework: unittest
+ observed-test-methods: 300
+ groups: [conformance, contracts, failure_injection, harnesses, integrations, runtime]
+ declared-latest-full-run: 300 tests passed in repository refactoring review
+ current-readme-run-check: repository-layout module passed 18 tests
+ assertion-type: derived
+ confidence: high
+ evidence:
+ - path: tests
+ source-kind: test-directory-scan
+ - path: docs/refactoring-review.md
+ line-start: 76
+ line-end: 91
+ source-kind: declared-verification-report
+ - path: tests/conformance/test_repository_layout.py
+ source-kind: executed-test-module
+
+ - id: F-EXECUTED-QUICK-CHECKS
+ category: verification
+ key: readme-authoring-session-executions
+ value:
+ date: 2026-07-18
+ content-job-request-validation: {exit-code: 0}
+ content-manifest-validation: {exit-code: 0, output: VALID}
+ front-door-content-plan: {exit-code: 0, primary-capability: document-writing}
+ artifact-set-validation: {exit-code: 0, output: VALID}
+ repository-layout-tests: {tests: 18, result: PASS}
+ assertion-type: executed
+ confidence: high
+ evidence:
+ - path: packages/content-job-contract/src/validate_content_job.py
+ source-kind: executed-entrypoint
+ - path: packages/content-contract/src/validate_content.py
+ source-kind: executed-entrypoint
+ - path: packages/workflow-runtime/src/content_runtime.py
+ source-kind: executed-entrypoint
+ - path: packages/artifact-contract/src/validate_artifact_set.py
+ source-kind: executed-entrypoint
+ - path: tests/conformance/test_repository_layout.py
+ source-kind: executed-test-module
+
+ - id: F-E2E-INPUTS
+ category: prerequisites
+ key: end-to-end-external-inputs
+ value:
+ dependency-directions: [external Java/Gradle evidence repository, completed technical review file, completed narrative review file]
+ part1-redraw: [external source document, completed expert review file]
+ all-harness-quality: [external Java/Gradle evidence repository, stage-specific review files]
+ assertion-type: declared
+ confidence: high
+ evidence:
+ - path: tests/end-to-end/README.md
+ line-start: 68
+ line-end: 139
+ source-kind: end-to-end-documentation
+
+ - id: F-HYBRID-PENDING
+ category: limitation
+ key: d2-svg-layer-compositor-status
+ value:
+ automated-evidence: PASS
+ human-qualification: PENDING
+ production-status: qualification candidate, not qualified renderer
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: packages/workflow-runtime/policies/qualification.yaml
+ line-start: 29
+ line-end: 33
+ source-kind: qualification-policy
+ - path: benchmarks/hybrid-composition/results/d2-svg-layer-compositor-qualification.yaml
+ line-start: 1
+ line-end: 9
+ source-kind: automated-qualification-result
+ - path: benchmarks/hybrid-composition/results/d2-svg-layer-compositor-qualification.yaml
+ line-start: 65
+ line-end: 72
+ source-kind: human-qualification-result
+
+ - id: F-BENCHMARK-MATURITY
+ category: limitation
+ key: qualification-corpus-status
+ value:
+ document-writing: corpus-defined-results-pending
+ image-generation: corpus-defined-results-pending
+ technical-visualization: dependency-directions comparison has unexecuted conditions and pending human preference
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: benchmarks/document-writing/suite.yaml
+ line-start: 1
+ line-end: 32
+ source-kind: benchmark-suite
+ - path: benchmarks/image-quality/suite.yaml
+ line-start: 1
+ line-end: 41
+ source-kind: benchmark-suite
+ - path: benchmarks/technical-visualization/results/dependency-directions-qualification.yaml
+ line-start: 1
+ line-end: 25
+ source-kind: benchmark-result
+
+ - id: F-NO-GIT-METADATA
+ category: limitation
+ key: repository-snapshot
+ value: the supplied directory has an empty .git directory, so no commit SHA or clean/dirty Git state can be established; the README run uses a repository content hash instead
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: .
+ source-kind: filesystem-and-git-probe
+
+commands:
+ - id: CMD-001
+ command: python3 -m packages.content_job_contract.validate_content_job examples/clean-architecture/content-job-request.yaml --repo-root .
+ cwd: .
+ source: {path: packages/content-job-contract/README.md, line-start: 21, line-end: 25}
+ verification:
+ status: executed
+ method: executed from the repository root on 2026-07-18; exit code 0
+ level: isolated-execution
+ limitations: [validates the checked-in ContentJobRequest only]
+
+ - id: CMD-002
+ command: python3 -m packages.workflow_runtime.content_runtime front-door --workflow-request examples/clean-architecture/workflow-request.content-job.yaml --repo-root .
+ cwd: .
+ source: {path: README.md, line-start: 93, line-end: 96}
+ verification:
+ status: executed
+ method: executed from the repository root on 2026-07-18; exit code 0 and a document-writing plan was emitted
+ level: isolated-execution
+ limitations: [plans the checked-in request but does not execute production providers]
+
+ - id: CMD-003
+ command: python3 -m packages.content_contract.validate_content examples/clean-architecture/content-manifest.yaml --repo-root .
+ cwd: .
+ source: {path: README.md, line-start: 99, line-end: 102}
+ verification:
+ status: executed
+ method: executed from the repository root on 2026-07-18; exit code 0 and output VALID
+ level: isolated-execution
+ limitations: [validates the checked-in Content Manifest only]
+
+ - id: CMD-004
+ command: python3 -m packages.artifact_contract.validate_artifact_set examples/clean-architecture/artifact/attempt-01/artifact-set.yaml --request examples/clean-architecture/visual-request.yaml
+ cwd: .
+ source: {path: README.md, line-start: 114, line-end: 116}
+ verification:
+ status: executed
+ method: executed from the repository root on 2026-07-18; exit code 0 and output VALID
+ level: isolated-execution
+ limitations: [validates the checked-in contract fixture rather than a fresh renderer run]
+
+ - id: CMD-005
+ command: python3 -m unittest tests.conformance.test_repository_layout
+ cwd: .
+ source: {path: tests/conformance/test_repository_layout.py}
+ verification:
+ status: executed
+ method: executed from the repository root on 2026-07-18; 18 tests passed
+ level: isolated-execution
+ limitations: [covers repository layout only, not the full suite]
+
+ - id: CMD-006
+ command: python3 -m unittest discover -s tests -p 'test_*.py'
+ cwd: .
+ source: {path: README.md, line-start: 145, line-end: 149}
+ verification:
+ status: discovered
+ method: located in the current root README and unittest tree
+ level: static
+ limitations: [not executed during this README rewrite; the refactoring review separately declares an earlier 300-test pass]
diff --git a/runs/image-haness/20260718-rewrite/repository-snapshot.json b/runs/image-haness/20260718-rewrite/repository-snapshot.json
new file mode 100644
index 0000000..fa31db3
--- /dev/null
+++ b/runs/image-haness/20260718-rewrite/repository-snapshot.json
@@ -0,0 +1,7 @@
+{
+ "git-sha": null,
+ "dirty": true,
+ "diff-hash": "sha256:d65d7446cad11d46dabd2080c8393059f36fab426f4d62f18183b2c144c3de29",
+ "scanned-at": null,
+ "file-count": 560
+}
\ No newline at end of file
diff --git a/runs/image-haness/20260718-rewrite/review-findings.yaml b/runs/image-haness/20260718-rewrite/review-findings.yaml
new file mode 100644
index 0000000..3983231
--- /dev/null
+++ b/runs/image-haness/20260718-rewrite/review-findings.yaml
@@ -0,0 +1,54 @@
+schema-version: 1
+verdict: PASS
+score: 94
+scores:
+ project-specificity:
+ score: 5
+ evidence:
+ - "overview·capabilities: ContentJobRequest, sibling harness, workflow-runtime, ArtifactSet, frozen publication projection 등 이 저장소 고유의 책임과 계약을 첫 화면부터 구체적으로 설명한다. 근거: F-IDENTITY, F-SIBLING-HARNESSES, F-CONTRACT-CHAIN, F-INTEGRATIONS."
+ - "artifacts: 체크인된 Clean Architecture fixture와 P6·docvis·best-of-three 로컬 결과를 실제 경로·산출물 유형·검토 상태로 구분한다. 근거: F-VERSIONED-VISUALS, F-LOCAL-CROSS-HARNESS-OUTPUT, F-LOCAL-DOCUMENT-VISUALIZATION, F-LOCAL-IMAGE-OUTPUT."
+ reader-journey:
+ score: 5
+ evidence:
+ - overview → capability 경계 → 2분 검증 → 실행 모델 → 산출물 → 변경 위치 → 검증 수준 → 한계 → 정본 문서 순서가 평가자와 기여자의 질문을 자연스럽게 해소한다.
+ - artifacts와 limitations에서 ignored runs를 실제 결과의 탐색 위치로 안내하면서도 clean checkout·GitHub에서 지속되는 정본으로 오인하지 않도록 즉시 경계를 설명한다.
+ technical-explanation:
+ score: 5
+ evidence:
+ - "execution-model: contract chain, technical-only·image-only·hybrid routing, runtime-owned composition, expert review와 acceptance 경계를 책임 흐름으로 연결한다. 근거: F-CONTRACT-CHAIN, F-ROUTING, F-SIBLING-HARNESSES, F-CAPABILITY-TECHNICAL."
+ - "architecture: adapter·harnesses·packages·integrations의 소유권과 adapter → harnesses → packages 의존 방향을 변경 위치 표 및 정본 링크와 함께 설명한다. 근거: F-REPOSITORY-LAYERS, F-SIBLING-HARNESSES, F-INTEGRATIONS."
+ task-usability:
+ score: 4
+ evidence:
+ - "quick-start: 전제 조건, packaging manifest 부재, 실행 위치가 명확한 두 명령, 기대 결과, front-door가 production provider 실행이 아니라는 범위를 한 경로로 제공한다."
+ - "verification: CMD-001부터 CMD-005까지의 실제 exit 0 실행과 CMD-006의 명시적 미실행을 구분하고, fixture 검증·layout test가 전체 실행을 대신하지 않는다고 밝힌다. 다만 정본 설치 명령과 version pin이 없어 새 환경에서는 독자가 의존성을 별도로 준비해야 한다."
+ prose-clarity:
+ score: 4
+ evidence:
+ - 전체 문서는 짧은 문단, 경로·책임 표, 제한 목록으로 214줄의 긴 범위를 탐색 가능하게 유지하며 성공·accepted·ready·pending 상태를 과장 없이 구분한다.
+ - capabilities와 execution-model 일부에서 contract·publication·rendition·provider 같은 영문 용어가 밀집하고, 실행 확인이 quick-start와 verification 두 곳에 나뉘지만 의미 중복은 제한적이고 섹션 목적은 분명하다.
+ visual-judgment:
+ score: 5
+ evidence:
+ - execution-model의 Mermaid는 세 sibling branch, runtime-owned hybrid 합류, reviewed output과 frozen projection의 관계를 한 화면에서 보여 주어 인접 문장만으로 파악하기 어려운 흐름을 보완한다.
+ - "artifacts에서는 ignored runs의 PNG·SVG를 영구 gallery처럼 임베드하지 않고, versioned fixture만 상대 링크로 제공하며 asset 승격 조건을 설명해 시각적 매력보다 provenance와 링크 지속성을 우선한다. 근거: F-RUNS-NONCANONICAL, F-VERSIONED-VISUALS."
+hard-gates:
+ passed: true
+ failures: []
+reader-simulations:
+ 30-seconds:
+ outcome: PASS
+ evidence:
+ - overview의 제목과 세 문단만으로 자연어 콘텐츠 요청을 문서·기술 시각화·유기적 이미지·publication output으로 연결하는 시스템이라는 정체성과 책임 분리의 이유를 설명할 수 있다.
+ - overview 마지막 문장에서 평가 개발자, capability 기여자, 산출물 리뷰어가 대상임을 바로 확인할 수 있다.
+ 5-minutes:
+ outcome: PASS
+ evidence:
+ - capabilities와 execution-model에서 핵심 가치와 책임 흐름을, quick-start에서 최소 확인 경로를, architecture에서 구조를, limitations에서 packaging·benchmark·qualification·E2E 한계를 찾을 수 있다.
+ - artifacts에서 버전 관리되는 contract fixture와 ignored 로컬 생성 문서·이미지·기술 시각화를 구분하고 각각의 실제 탐색 경로를 확인할 수 있다.
+ contributor:
+ outcome: PASS
+ evidence:
+ - architecture 표에서 capability 구현은 harnesses, 계약과 runtime은 packages, publication adapter는 integrations에서 시작해야 함을 찾을 수 있다.
+ - verification에서 layout test와 전체 unittest discovery 진입점을 확인하고, documentation에서 각 harness README·runtime·E2E·benchmark 정본으로 이동할 수 있다.
+findings: []
diff --git a/runs/image-haness/20260718-rewrite/review.md b/runs/image-haness/20260718-rewrite/review.md
new file mode 100644
index 0000000..1339710
--- /dev/null
+++ b/runs/image-haness/20260718-rewrite/review.md
@@ -0,0 +1,10 @@
+# README 품질 검토
+
+- 판정: **PASS**
+- 가중 점수: **94/100**
+- Hard gate: 모두 통과
+- 독자 시뮬레이션: 30초·5분·기여자 모두 통과
+
+후보 문서는 Content Harness의 네 capability, contract chain, runtime 소유 경계와 publication 흐름을 저장소 고유 정보로 설명합니다. 체크인된 fixture와 로컬 P6·docvis·이미지 테스트 산출물을 실제 경로로 안내하면서, `runs/**`가 ignored 운영 데이터이며 정본이나 영구 gallery가 아니라는 정책도 명확히 유지합니다.
+
+명령의 증거 수준도 정직합니다. 다섯 명령의 실제 성공 결과와 전체 suite 명령의 미실행을 분리하고, fixture·layout 검증이 fresh renderer 실행이나 전체 suite를 대신하지 않는다고 밝힙니다. 설치 정본과 version pin 부재로 새 환경의 준비 마찰이 남고 일부 영문 계약 용어가 조밀하지만, 이는 공개된 저장소 한계이며 독자 과업이나 품질 통과를 막지 않습니다.
diff --git a/runs/image-haness/20260718-rewrite/run-manifest.json b/runs/image-haness/20260718-rewrite/run-manifest.json
new file mode 100644
index 0000000..173782c
--- /dev/null
+++ b/runs/image-haness/20260718-rewrite/run-manifest.json
@@ -0,0 +1,11 @@
+{
+ "schema-version": 1,
+ "run-id": "20260718-rewrite",
+ "repo-id": "image-haness",
+ "mode": "bootstrap",
+ "target-repository": "/home/donghyeon/workspace/ai-tool/image-haness",
+ "harness-version": "0.1.0",
+ "started-at": null,
+ "tool-adapter": "codex",
+ "input-hashes": {}
+}
\ No newline at end of file
diff --git a/runs/image-haness/20260718-rewrite/state.json b/runs/image-haness/20260718-rewrite/state.json
new file mode 100644
index 0000000..f6fe254
--- /dev/null
+++ b/runs/image-haness/20260718-rewrite/state.json
@@ -0,0 +1,302 @@
+{
+ "schema-version": 1,
+ "mode": "bootstrap",
+ "current": "APPLIED",
+ "history": [
+ {
+ "state": "INITIALIZED"
+ },
+ {
+ "state": "INPUT_CAPTURED",
+ "gates": [
+ {
+ "name": "request",
+ "ok": true,
+ "warnings": [],
+ "data": null
+ }
+ ]
+ },
+ {
+ "state": "REPOSITORY_SNAPSHOTTED",
+ "gates": [
+ {
+ "name": "snapshot",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "diff-hash": "sha256:d65d7446cad11d46dabd2080c8393059f36fab426f4d62f18183b2c144c3de29"
+ }
+ }
+ ]
+ },
+ {
+ "state": "FACTS_EXTRACTED",
+ "gates": [
+ {
+ "name": "facts",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "fact_ids": [
+ "F-IDENTITY",
+ "F-REPOSITORY-LAYERS",
+ "F-SIBLING-HARNESSES",
+ "F-CAPABILITY-DOCUMENT",
+ "F-CAPABILITY-TECHNICAL",
+ "F-CAPABILITY-IMAGE",
+ "F-ROUTING",
+ "F-CONTRACT-CHAIN",
+ "F-INTEGRATIONS",
+ "F-EXAMPLE-CHAIN",
+ "F-VERSIONED-VISUALS",
+ "F-RUN-WORKSPACE",
+ "F-PORTABLE-OUTPUT",
+ "F-LOCAL-CROSS-HARNESS-OUTPUT",
+ "F-LOCAL-DOCUMENT-VISUALIZATION",
+ "F-LOCAL-IMAGE-OUTPUT",
+ "F-RUNS-NONCANONICAL",
+ "F-PREREQUISITES",
+ "F-NO-PACKAGE-MANIFEST",
+ "F-TEST-INVENTORY",
+ "F-EXECUTED-QUICK-CHECKS",
+ "F-E2E-INPUTS",
+ "F-HYBRID-PENDING",
+ "F-BENCHMARK-MATURITY",
+ "F-NO-GIT-METADATA"
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "state": "PROJECT_PROFILED",
+ "gates": [
+ {
+ "name": "profile",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "profile": "generic"
+ }
+ }
+ ]
+ },
+ {
+ "state": "README_PLANNED",
+ "gates": [
+ {
+ "name": "brief",
+ "ok": true,
+ "warnings": [],
+ "data": null
+ },
+ {
+ "name": "outline",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "section_ids": [
+ "overview",
+ "capabilities",
+ "quick-start",
+ "execution-model",
+ "artifacts",
+ "architecture",
+ "verification",
+ "limitations",
+ "documentation"
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "state": "README_DRAFTED",
+ "gates": [
+ {
+ "name": "conformance",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "sections": [
+ "overview",
+ "capabilities",
+ "quick-start",
+ "execution-model",
+ "artifacts",
+ "architecture",
+ "verification",
+ "limitations",
+ "documentation"
+ ]
+ }
+ },
+ {
+ "name": "claim_map",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "claims": [
+ "C-IDENTITY",
+ "C-SIBLING-MODEL",
+ "C-DOCUMENT-CAPABILITY",
+ "C-TECHNICAL-CAPABILITY",
+ "C-IMAGE-CAPABILITY",
+ "C-RUNTIME-CAPABILITY",
+ "C-INTEGRATIONS",
+ "C-PREREQUISITES",
+ "C-INSTALLATION-LIMIT",
+ "C-CMD-CONTENT-JOB",
+ "C-RESULT-CONTENT-JOB",
+ "C-CMD-FRONT-DOOR",
+ "C-RESULT-FRONT-DOOR",
+ "C-CONTRACT-CHAIN",
+ "C-ROUTING",
+ "C-RUNTIME-OWNERSHIP",
+ "C-ACCEPTANCE-BOUNDARY",
+ "C-FLOW-VISUAL",
+ "C-VERSIONED-FIXTURE",
+ "C-LOCAL-P6-OUTPUT",
+ "C-LOCAL-DOCVIS-OUTPUT",
+ "C-LOCAL-IMAGE-OUTPUT",
+ "C-RUNS-POLICY",
+ "C-ASSET-PROMOTION",
+ "C-LAYER-OWNERSHIP",
+ "C-DEPENDENCY-DIRECTION",
+ "C-CMD-CONTENT-MANIFEST",
+ "C-RESULT-CONTENT-MANIFEST",
+ "C-CMD-ARTIFACT-SET",
+ "C-RESULT-ARTIFACT-SET",
+ "C-CMD-LAYOUT-TEST",
+ "C-RESULT-LAYOUT-TEST",
+ "C-CMD-FULL-SUITE",
+ "C-FULL-SUITE-SCOPE",
+ "C-E2E-PREREQUISITES",
+ "C-LIMIT-PACKAGING",
+ "C-LIMIT-RUNS",
+ "C-LIMIT-BENCHMARKS",
+ "C-LIMIT-HYBRID",
+ "C-LIMIT-E2E",
+ "C-DOCUMENTATION-MAP"
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "state": "VISUALS_PLANNED",
+ "gates": [
+ {
+ "name": "visual_plan",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "visuals": [
+ "content-flow"
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "state": "STRUCTURALLY_VALIDATED",
+ "gates": [
+ {
+ "name": "github_markdown",
+ "ok": true,
+ "warnings": [],
+ "data": null
+ }
+ ]
+ },
+ {
+ "state": "TECHNICALLY_VERIFIED",
+ "gates": [
+ {
+ "name": "verify",
+ "ok": true,
+ "warnings": [
+ "manual verification required: python3 -m packages.content_job_contract.validate_content_job examples/clean-architecture/content-job-request.yaml --repo-root . (unsupported-static-verifier)",
+ "manual verification required: python3 -m packages.workflow_runtime.content_runtime front-door --workflow-request examples/clean-architecture/workflow-request.content-job.yaml --repo-root . (unsupported-static-verifier)",
+ "manual verification required: python3 -m packages.content_contract.validate_content examples/clean-architecture/content-manifest.yaml --repo-root . (unsupported-static-verifier)",
+ "manual verification required: python3 -m packages.artifact_contract.validate_artifact_set examples/clean-architecture/artifact/attempt-01/artifact-set.yaml --request examples/clean-architecture/visual-request.yaml (unsupported-static-verifier)",
+ "manual verification required: python3 -m unittest tests.conformance.test_repository_layout (unsupported-static-verifier)",
+ "manual verification required: python3 -m unittest discover -s tests -p 'test_*.py' (unsupported-static-verifier)"
+ ],
+ "data": {
+ "schema-version": 1,
+ "state": "PASS_WITH_MANUAL",
+ "verification-level": "static",
+ "execution-verified": false,
+ "checks": {
+ "commands": {
+ "total": 6,
+ "verified": 0,
+ "manual-required": 6,
+ "failed": 0
+ },
+ "paths": {
+ "total": 20,
+ "verified": 20,
+ "failed": 0
+ },
+ "anchors": {
+ "total": 0,
+ "verified": 0,
+ "failed": 0
+ },
+ "readme-contracts": {
+ "total": 0,
+ "verified": 0,
+ "failed": 0
+ }
+ },
+ "failures": [],
+ "limitations": [
+ "manual verification required: python3 -m packages.content_job_contract.validate_content_job examples/clean-architecture/content-job-request.yaml --repo-root . (unsupported-static-verifier)",
+ "manual verification required: python3 -m packages.workflow_runtime.content_runtime front-door --workflow-request examples/clean-architecture/workflow-request.content-job.yaml --repo-root . (unsupported-static-verifier)",
+ "manual verification required: python3 -m packages.content_contract.validate_content examples/clean-architecture/content-manifest.yaml --repo-root . (unsupported-static-verifier)",
+ "manual verification required: python3 -m packages.artifact_contract.validate_artifact_set examples/clean-architecture/artifact/attempt-01/artifact-set.yaml --request examples/clean-architecture/visual-request.yaml (unsupported-static-verifier)",
+ "manual verification required: python3 -m unittest tests.conformance.test_repository_layout (unsupported-static-verifier)",
+ "manual verification required: python3 -m unittest discover -s tests -p 'test_*.py' (unsupported-static-verifier)"
+ ]
+ }
+ },
+ {
+ "name": "secret_scan",
+ "ok": true,
+ "warnings": [],
+ "data": null
+ }
+ ]
+ },
+ {
+ "state": "QUALITY_REVIEWED",
+ "gates": [
+ {
+ "name": "review",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "verdict": "PASS",
+ "score": 94,
+ "findings": []
+ }
+ }
+ ]
+ },
+ {
+ "state": "READY_FOR_APPLY",
+ "gates": []
+ },
+ {
+ "state": "APPLIED",
+ "gates": []
+ }
+ ],
+ "rework": {
+ "iterations": 0,
+ "findings": {}
+ }
+}
\ No newline at end of file
diff --git a/runs/image-haness/20260718-rewrite/verification.json b/runs/image-haness/20260718-rewrite/verification.json
new file mode 100644
index 0000000..8887476
--- /dev/null
+++ b/runs/image-haness/20260718-rewrite/verification.json
@@ -0,0 +1,38 @@
+{
+ "schema-version": 1,
+ "state": "PASS_WITH_MANUAL",
+ "verification-level": "static",
+ "execution-verified": false,
+ "checks": {
+ "commands": {
+ "total": 6,
+ "verified": 0,
+ "manual-required": 6,
+ "failed": 0
+ },
+ "paths": {
+ "total": 20,
+ "verified": 20,
+ "failed": 0
+ },
+ "anchors": {
+ "total": 0,
+ "verified": 0,
+ "failed": 0
+ },
+ "readme-contracts": {
+ "total": 0,
+ "verified": 0,
+ "failed": 0
+ }
+ },
+ "failures": [],
+ "limitations": [
+ "manual verification required: python3 -m packages.content_job_contract.validate_content_job examples/clean-architecture/content-job-request.yaml --repo-root . (unsupported-static-verifier)",
+ "manual verification required: python3 -m packages.workflow_runtime.content_runtime front-door --workflow-request examples/clean-architecture/workflow-request.content-job.yaml --repo-root . (unsupported-static-verifier)",
+ "manual verification required: python3 -m packages.content_contract.validate_content examples/clean-architecture/content-manifest.yaml --repo-root . (unsupported-static-verifier)",
+ "manual verification required: python3 -m packages.artifact_contract.validate_artifact_set examples/clean-architecture/artifact/attempt-01/artifact-set.yaml --request examples/clean-architecture/visual-request.yaml (unsupported-static-verifier)",
+ "manual verification required: python3 -m unittest tests.conformance.test_repository_layout (unsupported-static-verifier)",
+ "manual verification required: python3 -m unittest discover -s tests -p 'test_*.py' (unsupported-static-verifier)"
+ ]
+}
\ No newline at end of file
diff --git a/runs/image-haness/20260718-rewrite/visual-plan.yaml b/runs/image-haness/20260718-rewrite/visual-plan.yaml
new file mode 100644
index 0000000..f30bbd6
--- /dev/null
+++ b/runs/image-haness/20260718-rewrite/visual-plan.yaml
@@ -0,0 +1,36 @@
+schema-version: 1
+visuals:
+ - id: content-flow
+ section: execution-model
+ type: request-flow
+ purpose: 자연어 request와 두 contract entry가 workflow-runtime에서 sibling capability로 분기하고 reviewed publication으로 다시 합류하는 소유 경계를 한 화면에 설명한다.
+ placeholder-text: Mermaid flowchart로 request, runtime routing, 세 sibling harness, hybrid composition, reviewed outputs, publication adapter를 표시한다.
+ must-show:
+ - 자연어 요청과 ContentJobRequest 또는 Visual Request
+ - workflow-runtime의 routing, DAG, freshness 책임
+ - document-writing, technical-visualization, image-generation sibling branch
+ - runtime-owned hybrid composition
+ - reviewed publication draft와 accepted ArtifactSet
+ - frozen publication projection과 Markdown, Slides, HTML adapter
+ relationships:
+ - 자연어 요청 -> ContentJobRequest 또는 Visual Request -> workflow-runtime
+ - workflow-runtime -> document-writing
+ - workflow-runtime -> technical-visualization
+ - workflow-runtime -> image-generation
+ - technical-visualization + image-generation -> runtime-owned hybrid composition
+ - reviewed draft 또는 accepted ArtifactSet -> frozen projection -> publication adapter
+ emphasize:
+ - sibling harness는 서로 직접 호출하지 않음
+ - runtime이 분기와 합류를 모두 소유함
+ - 검토된 결과만 publication projection으로 이동함
+ avoid:
+ - image-generation이 exact technical semantics를 소유하는 것처럼 표현하기
+ - integrations가 route나 content를 다시 선택하는 것처럼 표현하기
+ - 로컬 runs 산출물을 canonical input으로 그리기
+ placement:
+ after-section-id: execution-model
+ accessibility:
+ alt-text: 자연어 요청이 ContentJobRequest 또는 Visual Request로 정규화되고 workflow-runtime에서 문서 작성, 기술 시각화, 이미지 생성으로 분기한 뒤 검토된 draft 또는 ArtifactSet과 publication adapter로 합류하는 흐름
+ production:
+ format: mermaid
+ status: embedded
diff --git a/runs/image-haness/20260719-reader-first-korean/README.candidate.md b/runs/image-haness/20260719-reader-first-korean/README.candidate.md
new file mode 100644
index 0000000..bad7c49
--- /dev/null
+++ b/runs/image-haness/20260719-reader-first-korean/README.candidate.md
@@ -0,0 +1,214 @@
+# Content Harness
+
+
+
+이 저장소는 자연어로 받은 콘텐츠 요청을 문서, 기술 그림, 이미지로 만드는 파이썬 프로젝트입니다. 세 하네스가 각 결과를 만들고 `workflow-runtime`이 요청 분기, 작업 순서, 검토 결과 취합, 게시 파일 생성을 맡습니다.
+
+대상 독자:
+
+- 저장소가 실제로 만드는 결과를 먼저 보고 싶은 개발자
+- 예제를 실행하거나 하네스·계약·통합 코드를 수정하려는 개발자
+
+## 검토를 마친 결과 예시
+
+
+
+아래 세 파일은 `p6-all-harness-quality-executable-clean-architecture-20260717` 실행에서 검토와 통합 검증을 통과한 결과입니다. README에서 계속 볼 수 있도록 `docs/assets/readme-showcase/`로 옮겼습니다.
+
+
+
+
+
+
+
+ 이미지 생성 — 후보 세 개와 독립 검토를 거쳐 고른 에디토리얼 이미지
+
+
+
+
+
+ 기술 시각화 — 호출 관계와 소스·모듈 의존을 구분한 SVG
+
+
+
+
+
+
+
+
+
+
+
+ 통합 문서 — 문서 작성, 이미지 생성, 기술 시각화 결과를 한 문서에 배치한 미리보기
+
+
+
+
+[산출물 출처 기록](docs/assets/readme-showcase/provenance.yaml)에는 원본 실행 경로, 파일별 SHA-256 해시, 크기, 검토 상태가 들어 있습니다.
+
+## 먼저 실행해 보기
+
+
+
+### 준비 사항
+
+기본 실행에는 `Python 3`, `PyYAML`, `jsonschema`가 필요합니다. `PNG` 검증과 미리보기에는 `Pillow`를 사용합니다. 기술 그림을 새로 렌더링하려면 `D2`가, `SVG`를 브라우저에서 미리 보려면 `Chrome` 또는 `Chromium`이 추가로 필요합니다. 저장소에는 이 도구들의 최소 버전이 적혀 있지 않습니다.
+
+`pyproject.toml`, `requirements.txt` 같은 패키지 설정 파일도 없습니다. 따라서 README에서 확인되지 않은 설치 명령을 제시하지 않습니다. 필요한 도구를 준비한 뒤 저장소 루트에서 아래 명령을 실행합니다.
+
+### 1. 예제 요청 검사
+
+```bash
+python3 -m packages.content_job_contract.validate_content_job examples/clean-architecture/content-job-request.yaml --repo-root .
+```
+
+
+2026-07-19 실행에서는 종료 코드 0으로 끝났습니다. 출력 없이 종료되면 예제 요청이 현재 계약을 통과한 것입니다.
+
+### 2. 작업 계획 확인
+
+```bash
+python3 -m packages.workflow_runtime.content_runtime front-door --workflow-request examples/clean-architecture/workflow-request.content-job.yaml --repo-root .
+```
+
+
+2026-07-19 실행에서는 종료 코드 0과 `primary_capability: document-writing` 계획을 확인했습니다. 이 명령은 작업 계획만 만들며 외부 생성 도구를 호출하지 않습니다.
+
+## 기능별 책임
+
+
+
+### 문서 작성 — `document-writing`
+
+독자, 글의 순서, 근거 연결, 그림이 필요한 위치를 정합니다. 요청 명세, 내용 명세, 서사 계획, 게시 초안, 그림 요청을 만들지만 원문을 덮어쓰거나 렌더러를 고르지는 않습니다.
+
+### 기술 시각화 — `technical-visualization`
+
+코드와 문서에서 확인한 관계를 의미 모형으로 만들고 D2로 렌더링합니다. 현재 `dependency-graph`와 `runtime-sequence`를 만들 수 있습니다. 기술 내용과 화면 표현을 서로 다른 검토자가 승인해야 산출물 묶음이 `accepted`가 됩니다.
+
+### 이미지 생성 — `image-generation`
+
+사진, 일러스트, 재질, 분위기처럼 유기적인 래스터 이미지를 만듭니다. 후보 세 개를 비교해 하나를 고르고, 필요한 경우 한 번만 부분 수정합니다. 정확한 아키텍처 관계, 차트, 상태 전이, 긴 본문은 이 기능으로 만들지 않습니다.
+
+### 작업 실행과 게시 — `workflow-runtime`, `integrations`
+
+`workflow-runtime`은 요청 검사, 분기, 작업 순서, 재시도, 결과 취합을 담당합니다. 세 하네스는 서로를 직접 호출하지 않습니다.
+
+`Markdown`, `Slides`, `HTML` 어댑터는 작업 실행기가 확정한 게시 자료만 받습니다. 어댑터가 내용이나 생성 도구를 다시 고르지는 않습니다.
+
+## 요청이 결과가 되는 과정
+
+
+
+파일 계약은 `ContentJobRequest` → `Content Manifest` → `Narrative Plan` → `Visual Request` → `ArtifactSet` → 게시 자료 순서로 이어집니다. 각 단계는 다음 단계가 받아도 되는 정보와 검토 상태를 제한합니다.
+
+그림 요청이 기술 관계만 포함하면 `technical-visualization`, 이미지 표현만 포함하면 `image-generation`으로 보냅니다. 둘 다 필요하면 `workflow-runtime`이 두 결과를 합치는 작업 순서를 만듭니다. 신호가 없거나 서로 충돌하면 실행을 막습니다.
+
+```mermaid
+flowchart LR
+ A["자연어 요청"] --> B["요청 명세"]
+ B --> R{"workflow-runtime 분기 · 작업 순서 · 검토"}
+ R --> D["document-writing 문서 초안"]
+ R --> T["technical-visualization 기술 그림"]
+ R --> I["image-generation 이미지"]
+ T --> H["혼합 합성"]
+ I --> H
+ D --> P["검토된 게시 자료"]
+ T --> P
+ I --> P
+ H --> P
+ P --> O["Markdown · Slides · HTML"]
+```
+
+
+
+`workflow-runtime`이 세 하네스로 요청을 나누고, 검토를 마친 결과를 게시 자료로 합칩니다.
+
+구조 검사만 통과한 결과는 바로 게시하지 않습니다. 문서는 지정된 검토를 마쳐야 하고, 기술 그림과 이미지는 `accepted`이면서 통합 준비 상태여야 합니다.
+
+## 저장소 구성과 변경 위치
+
+
+
+| 경로 | 맡는 일 | 이럴 때 먼저 확인 |
+| --- | --- | --- |
+| `.agents/`, `.codex/` | 도구가 하네스를 찾게 하는 얇은 연결부 | 도구별 진입점 변경 |
+| `harnesses/` | 문서·기술 그림·이미지 생성 정책과 구현 | 생성 방식이나 검토 규칙 변경 |
+| `packages/` | 파일 계약, 공통 검사, 작업 실행기 | 명세 구조나 실행 순서 변경 |
+| `integrations/` | 확정된 게시 자료를 `Markdown`·`Slides`·`HTML`로 변환 | 출력 형식 변경 |
+| `tests/` | 계약·실행·실패 조건·저장소 구성 검사 | 동작 변경과 회귀 검사 추가 |
+| `examples/` | 버전 관리되는 실행 예제 | 재현 가능한 예제 추가 |
+| `benchmarks/` | 평가 자료와 판정 결과 | 품질 기준이나 비교 자료 변경 |
+| `runs/` | 버전 관리하지 않는 실행 기록 | 실행 재개와 실패 원인 확인 |
+
+정본 의존 방향은 도구 연결부 → 하네스 → 공통 계약입니다. `workflow-runtime`은 등록 파일을 통해 하네스를 실행하고, 확정된 게시 자료만 `integrations`로 보냅니다.
+
+전체 계약 사슬과 혼합 합성 경계는 [ARCHITECTURE.md](ARCHITECTURE.md)에 정리돼 있습니다.
+
+## 검증
+
+
+
+아래 결과는 2026-07-19에 저장소 루트에서 확인했습니다.
+
+### 내용 명세
+
+```bash
+python3 -m packages.content_contract.validate_content examples/clean-architecture/content-manifest.yaml --repo-root .
+```
+
+
+결과는 `VALID`, 종료 코드 0입니다.
+
+### 기술 그림 산출물 묶음
+
+```bash
+python3 -m packages.artifact_contract.validate_artifact_set examples/clean-architecture/artifact/attempt-01/artifact-set.yaml --request examples/clean-architecture/visual-request.yaml
+```
+
+
+결과는 `VALID`, 종료 코드 0입니다. 이 명령은 버전 관리되는 계약 예시를 검사하며 새 그림을 렌더링하지 않습니다.
+
+### 저장소 구성
+
+```bash
+python3 -m unittest tests.conformance.test_repository_layout
+```
+
+
+구성 검사 18개가 통과했습니다.
+
+### 전체 테스트
+
+```bash
+python3 -m unittest discover -s tests -p 'test_*.py'
+```
+
+
+전체 테스트 300개가 615.249초에 통과했습니다. 외부 자료와 별도 검토 파일을 넣어야 하는 종단 간 작업은 이 결과와 구분해야 합니다.
+
+외부 입력을 준비하는 방법은 [종단 간 작업 안내](tests/end-to-end/README.md)에 있습니다.
+
+## 현재 한계
+
+
+
+- **설치 절차:** 패키지 설정 파일과 버전 고정값이 없어 하나의 재현 가능한 설치 명령을 제공하지 못합니다.
+- **실행 기록:** `runs/`는 버전 관리 대상이 아닙니다. 재사용할 예시는 `docs/`나 `examples/`로 옮기고 출처를 함께 기록해야 합니다.
+- **외부 입력:** 일부 종단 간 작업에는 외부 Java·Gradle 저장소, 원문, 완료된 전문가 검토 파일이 필요합니다.
+- **평가 자료:** 문서 작성과 이미지 생성 평가는 자료 구조만 정의돼 있고 결과는 아직 없습니다. 기술 시각화 비교에도 실행하지 않은 조건과 사람 선호 판정이 남아 있습니다.
+- **혼합 합성:** `d2-svg-layer-compositor`는 자동 검사에 통과했지만 사람 검토가 남아 있어 정식 렌더러로 분류하지 않습니다.
+
+## 더 읽을 문서
+
+
+
+- [전체 설계](ARCHITECTURE.md) — 계층, 계약, 분기, 검토 권한
+- [문서 색인](docs/README.md) — 현재 문서와 구현 이력의 구분
+- [실행 작업공간](runs/README.md) — 새 실행 할당, 재개, 결과 게시
+- [문서 작성 하네스](harnesses/document-writing/README.md)
+- [기술 시각화 하네스](harnesses/technical-visualization/README.md)
+- [이미지 생성 하네스](harnesses/image-generation/README.md)
+- [작업 실행기](packages/workflow-runtime/README.md)
+- [Clean Architecture 예제](examples/clean-architecture/)
+- [평가 자료](benchmarks/technical-visualization/README.md) · [이미지 품질](benchmarks/image-quality/README.md) · [혼합 합성](benchmarks/hybrid-composition/README.md)
diff --git a/runs/image-haness/20260719-reader-first-korean/README.generated.md b/runs/image-haness/20260719-reader-first-korean/README.generated.md
new file mode 100644
index 0000000..bad7c49
--- /dev/null
+++ b/runs/image-haness/20260719-reader-first-korean/README.generated.md
@@ -0,0 +1,214 @@
+# Content Harness
+
+
+
+이 저장소는 자연어로 받은 콘텐츠 요청을 문서, 기술 그림, 이미지로 만드는 파이썬 프로젝트입니다. 세 하네스가 각 결과를 만들고 `workflow-runtime`이 요청 분기, 작업 순서, 검토 결과 취합, 게시 파일 생성을 맡습니다.
+
+대상 독자:
+
+- 저장소가 실제로 만드는 결과를 먼저 보고 싶은 개발자
+- 예제를 실행하거나 하네스·계약·통합 코드를 수정하려는 개발자
+
+## 검토를 마친 결과 예시
+
+
+
+아래 세 파일은 `p6-all-harness-quality-executable-clean-architecture-20260717` 실행에서 검토와 통합 검증을 통과한 결과입니다. README에서 계속 볼 수 있도록 `docs/assets/readme-showcase/`로 옮겼습니다.
+
+
+
+
+
+
+
+ 이미지 생성 — 후보 세 개와 독립 검토를 거쳐 고른 에디토리얼 이미지
+
+
+
+
+
+ 기술 시각화 — 호출 관계와 소스·모듈 의존을 구분한 SVG
+
+
+
+
+
+
+
+
+
+
+
+ 통합 문서 — 문서 작성, 이미지 생성, 기술 시각화 결과를 한 문서에 배치한 미리보기
+
+
+
+
+[산출물 출처 기록](docs/assets/readme-showcase/provenance.yaml)에는 원본 실행 경로, 파일별 SHA-256 해시, 크기, 검토 상태가 들어 있습니다.
+
+## 먼저 실행해 보기
+
+
+
+### 준비 사항
+
+기본 실행에는 `Python 3`, `PyYAML`, `jsonschema`가 필요합니다. `PNG` 검증과 미리보기에는 `Pillow`를 사용합니다. 기술 그림을 새로 렌더링하려면 `D2`가, `SVG`를 브라우저에서 미리 보려면 `Chrome` 또는 `Chromium`이 추가로 필요합니다. 저장소에는 이 도구들의 최소 버전이 적혀 있지 않습니다.
+
+`pyproject.toml`, `requirements.txt` 같은 패키지 설정 파일도 없습니다. 따라서 README에서 확인되지 않은 설치 명령을 제시하지 않습니다. 필요한 도구를 준비한 뒤 저장소 루트에서 아래 명령을 실행합니다.
+
+### 1. 예제 요청 검사
+
+```bash
+python3 -m packages.content_job_contract.validate_content_job examples/clean-architecture/content-job-request.yaml --repo-root .
+```
+
+
+2026-07-19 실행에서는 종료 코드 0으로 끝났습니다. 출력 없이 종료되면 예제 요청이 현재 계약을 통과한 것입니다.
+
+### 2. 작업 계획 확인
+
+```bash
+python3 -m packages.workflow_runtime.content_runtime front-door --workflow-request examples/clean-architecture/workflow-request.content-job.yaml --repo-root .
+```
+
+
+2026-07-19 실행에서는 종료 코드 0과 `primary_capability: document-writing` 계획을 확인했습니다. 이 명령은 작업 계획만 만들며 외부 생성 도구를 호출하지 않습니다.
+
+## 기능별 책임
+
+
+
+### 문서 작성 — `document-writing`
+
+독자, 글의 순서, 근거 연결, 그림이 필요한 위치를 정합니다. 요청 명세, 내용 명세, 서사 계획, 게시 초안, 그림 요청을 만들지만 원문을 덮어쓰거나 렌더러를 고르지는 않습니다.
+
+### 기술 시각화 — `technical-visualization`
+
+코드와 문서에서 확인한 관계를 의미 모형으로 만들고 D2로 렌더링합니다. 현재 `dependency-graph`와 `runtime-sequence`를 만들 수 있습니다. 기술 내용과 화면 표현을 서로 다른 검토자가 승인해야 산출물 묶음이 `accepted`가 됩니다.
+
+### 이미지 생성 — `image-generation`
+
+사진, 일러스트, 재질, 분위기처럼 유기적인 래스터 이미지를 만듭니다. 후보 세 개를 비교해 하나를 고르고, 필요한 경우 한 번만 부분 수정합니다. 정확한 아키텍처 관계, 차트, 상태 전이, 긴 본문은 이 기능으로 만들지 않습니다.
+
+### 작업 실행과 게시 — `workflow-runtime`, `integrations`
+
+`workflow-runtime`은 요청 검사, 분기, 작업 순서, 재시도, 결과 취합을 담당합니다. 세 하네스는 서로를 직접 호출하지 않습니다.
+
+`Markdown`, `Slides`, `HTML` 어댑터는 작업 실행기가 확정한 게시 자료만 받습니다. 어댑터가 내용이나 생성 도구를 다시 고르지는 않습니다.
+
+## 요청이 결과가 되는 과정
+
+
+
+파일 계약은 `ContentJobRequest` → `Content Manifest` → `Narrative Plan` → `Visual Request` → `ArtifactSet` → 게시 자료 순서로 이어집니다. 각 단계는 다음 단계가 받아도 되는 정보와 검토 상태를 제한합니다.
+
+그림 요청이 기술 관계만 포함하면 `technical-visualization`, 이미지 표현만 포함하면 `image-generation`으로 보냅니다. 둘 다 필요하면 `workflow-runtime`이 두 결과를 합치는 작업 순서를 만듭니다. 신호가 없거나 서로 충돌하면 실행을 막습니다.
+
+```mermaid
+flowchart LR
+ A["자연어 요청"] --> B["요청 명세"]
+ B --> R{"workflow-runtime 분기 · 작업 순서 · 검토"}
+ R --> D["document-writing 문서 초안"]
+ R --> T["technical-visualization 기술 그림"]
+ R --> I["image-generation 이미지"]
+ T --> H["혼합 합성"]
+ I --> H
+ D --> P["검토된 게시 자료"]
+ T --> P
+ I --> P
+ H --> P
+ P --> O["Markdown · Slides · HTML"]
+```
+
+
+
+`workflow-runtime`이 세 하네스로 요청을 나누고, 검토를 마친 결과를 게시 자료로 합칩니다.
+
+구조 검사만 통과한 결과는 바로 게시하지 않습니다. 문서는 지정된 검토를 마쳐야 하고, 기술 그림과 이미지는 `accepted`이면서 통합 준비 상태여야 합니다.
+
+## 저장소 구성과 변경 위치
+
+
+
+| 경로 | 맡는 일 | 이럴 때 먼저 확인 |
+| --- | --- | --- |
+| `.agents/`, `.codex/` | 도구가 하네스를 찾게 하는 얇은 연결부 | 도구별 진입점 변경 |
+| `harnesses/` | 문서·기술 그림·이미지 생성 정책과 구현 | 생성 방식이나 검토 규칙 변경 |
+| `packages/` | 파일 계약, 공통 검사, 작업 실행기 | 명세 구조나 실행 순서 변경 |
+| `integrations/` | 확정된 게시 자료를 `Markdown`·`Slides`·`HTML`로 변환 | 출력 형식 변경 |
+| `tests/` | 계약·실행·실패 조건·저장소 구성 검사 | 동작 변경과 회귀 검사 추가 |
+| `examples/` | 버전 관리되는 실행 예제 | 재현 가능한 예제 추가 |
+| `benchmarks/` | 평가 자료와 판정 결과 | 품질 기준이나 비교 자료 변경 |
+| `runs/` | 버전 관리하지 않는 실행 기록 | 실행 재개와 실패 원인 확인 |
+
+정본 의존 방향은 도구 연결부 → 하네스 → 공통 계약입니다. `workflow-runtime`은 등록 파일을 통해 하네스를 실행하고, 확정된 게시 자료만 `integrations`로 보냅니다.
+
+전체 계약 사슬과 혼합 합성 경계는 [ARCHITECTURE.md](ARCHITECTURE.md)에 정리돼 있습니다.
+
+## 검증
+
+
+
+아래 결과는 2026-07-19에 저장소 루트에서 확인했습니다.
+
+### 내용 명세
+
+```bash
+python3 -m packages.content_contract.validate_content examples/clean-architecture/content-manifest.yaml --repo-root .
+```
+
+
+결과는 `VALID`, 종료 코드 0입니다.
+
+### 기술 그림 산출물 묶음
+
+```bash
+python3 -m packages.artifact_contract.validate_artifact_set examples/clean-architecture/artifact/attempt-01/artifact-set.yaml --request examples/clean-architecture/visual-request.yaml
+```
+
+
+결과는 `VALID`, 종료 코드 0입니다. 이 명령은 버전 관리되는 계약 예시를 검사하며 새 그림을 렌더링하지 않습니다.
+
+### 저장소 구성
+
+```bash
+python3 -m unittest tests.conformance.test_repository_layout
+```
+
+
+구성 검사 18개가 통과했습니다.
+
+### 전체 테스트
+
+```bash
+python3 -m unittest discover -s tests -p 'test_*.py'
+```
+
+
+전체 테스트 300개가 615.249초에 통과했습니다. 외부 자료와 별도 검토 파일을 넣어야 하는 종단 간 작업은 이 결과와 구분해야 합니다.
+
+외부 입력을 준비하는 방법은 [종단 간 작업 안내](tests/end-to-end/README.md)에 있습니다.
+
+## 현재 한계
+
+
+
+- **설치 절차:** 패키지 설정 파일과 버전 고정값이 없어 하나의 재현 가능한 설치 명령을 제공하지 못합니다.
+- **실행 기록:** `runs/`는 버전 관리 대상이 아닙니다. 재사용할 예시는 `docs/`나 `examples/`로 옮기고 출처를 함께 기록해야 합니다.
+- **외부 입력:** 일부 종단 간 작업에는 외부 Java·Gradle 저장소, 원문, 완료된 전문가 검토 파일이 필요합니다.
+- **평가 자료:** 문서 작성과 이미지 생성 평가는 자료 구조만 정의돼 있고 결과는 아직 없습니다. 기술 시각화 비교에도 실행하지 않은 조건과 사람 선호 판정이 남아 있습니다.
+- **혼합 합성:** `d2-svg-layer-compositor`는 자동 검사에 통과했지만 사람 검토가 남아 있어 정식 렌더러로 분류하지 않습니다.
+
+## 더 읽을 문서
+
+
+
+- [전체 설계](ARCHITECTURE.md) — 계층, 계약, 분기, 검토 권한
+- [문서 색인](docs/README.md) — 현재 문서와 구현 이력의 구분
+- [실행 작업공간](runs/README.md) — 새 실행 할당, 재개, 결과 게시
+- [문서 작성 하네스](harnesses/document-writing/README.md)
+- [기술 시각화 하네스](harnesses/technical-visualization/README.md)
+- [이미지 생성 하네스](harnesses/image-generation/README.md)
+- [작업 실행기](packages/workflow-runtime/README.md)
+- [Clean Architecture 예제](examples/clean-architecture/)
+- [평가 자료](benchmarks/technical-visualization/README.md) · [이미지 품질](benchmarks/image-quality/README.md) · [혼합 합성](benchmarks/hybrid-composition/README.md)
diff --git a/runs/image-haness/20260719-reader-first-korean/README.patch b/runs/image-haness/20260719-reader-first-korean/README.patch
new file mode 100644
index 0000000..a48fb17
--- /dev/null
+++ b/runs/image-haness/20260719-reader-first-korean/README.patch
@@ -0,0 +1,378 @@
+--- README.md (current)
++++ README.md (candidate)
+@@ -2,213 +2,213 @@
+
+
+
+-Content Harness는 자연어 기반 콘텐츠 요청을 문서 계획, 정확한 기술 시각화, 유기적 이미지 생성, 검토된 publication output으로 연결하는 provider-neutral Python 시스템입니다.
+-
+-문서 작성과 기술 도형, 유기적 이미지에는 서로 다른 생성·검토 기준이 필요합니다. 이 저장소는 세 production harness를 sibling으로 유지하고, `workflow-runtime`만 라우팅·DAG 실행·결과 전달·publication을 조정하도록 책임을 나눕니다.
+-
+-이 README는 저장소를 처음 평가하는 개발자에게는 실행 가능한 contract chain을, 기여자에게는 capability별 변경 위치를, 리뷰어에게는 실제 생성 산출물과 현재 qualification 한계를 보여줍니다.
+-
+-## 책임이 섞이지 않는 네 capability
++이 저장소는 자연어로 받은 콘텐츠 요청을 문서, 기술 그림, 이미지로 만드는 파이썬 프로젝트입니다. 세 하네스가 각 결과를 만들고 `workflow-runtime`이 요청 분기, 작업 순서, 검토 결과 취합, 게시 파일 생성을 맡습니다.
++
++대상 독자:
++
++- 저장소가 실제로 만드는 결과를 먼저 보고 싶은 개발자
++- 예제를 실행하거나 하네스·계약·통합 코드를 수정하려는 개발자
++
++## 검토를 마친 결과 예시
++
++
++
++아래 세 파일은 `p6-all-harness-quality-executable-clean-architecture-20260717` 실행에서 검토와 통합 검증을 통과한 결과입니다. README에서 계속 볼 수 있도록 `docs/assets/readme-showcase/`로 옮겼습니다.
++
++
++
++
++
++
++
++ 이미지 생성 — 후보 세 개와 독립 검토를 거쳐 고른 에디토리얼 이미지
++
++
++
++
++
++ 기술 시각화 — 호출 관계와 소스·모듈 의존을 구분한 SVG
++
++
++
++
++
++
++
++
++
++
++
++ 통합 문서 — 문서 작성, 이미지 생성, 기술 시각화 결과를 한 문서에 배치한 미리보기
++
++
++
++
++[산출물 출처 기록](docs/assets/readme-showcase/provenance.yaml)에는 원본 실행 경로, 파일별 SHA-256 해시, 크기, 검토 상태가 들어 있습니다.
++
++## 먼저 실행해 보기
++
++
++
++### 준비 사항
++
++기본 실행에는 `Python 3`, `PyYAML`, `jsonschema`가 필요합니다. `PNG` 검증과 미리보기에는 `Pillow`를 사용합니다. 기술 그림을 새로 렌더링하려면 `D2`가, `SVG`를 브라우저에서 미리 보려면 `Chrome` 또는 `Chromium`이 추가로 필요합니다. 저장소에는 이 도구들의 최소 버전이 적혀 있지 않습니다.
++
++`pyproject.toml`, `requirements.txt` 같은 패키지 설정 파일도 없습니다. 따라서 README에서 확인되지 않은 설치 명령을 제시하지 않습니다. 필요한 도구를 준비한 뒤 저장소 루트에서 아래 명령을 실행합니다.
++
++### 1. 예제 요청 검사
++
++```bash
++python3 -m packages.content_job_contract.validate_content_job examples/clean-architecture/content-job-request.yaml --repo-root .
++```
++
++
++2026-07-19 실행에서는 종료 코드 0으로 끝났습니다. 출력 없이 종료되면 예제 요청이 현재 계약을 통과한 것입니다.
++
++### 2. 작업 계획 확인
++
++```bash
++python3 -m packages.workflow_runtime.content_runtime front-door --workflow-request examples/clean-architecture/workflow-request.content-job.yaml --repo-root .
++```
++
++
++2026-07-19 실행에서는 종료 코드 0과 `primary_capability: document-writing` 계획을 확인했습니다. 이 명령은 작업 계획만 만들며 외부 생성 도구를 호출하지 않습니다.
++
++## 기능별 책임
+
+
+
+-### Document Writing
+-
+-`document-writing`은 독자·서사·근거 연결·시각화 기회를 다루고, ContentJobRequest·Content Manifest·Narrative Plan·publication draft·Visual Request를 만듭니다. 원문을 제자리에서 덮어쓰거나 renderer와 image provider를 선택하지 않습니다.
+-
+-### Technical Visualization
+-
+-`technical-visualization`은 근거에 묶인 semantic model, visual grammar, D2 렌더링, 문서·발표용 rendition을 소유합니다. 현재 실행 가능한 visual type은 `dependency-graph`와 `runtime-sequence`이며, accepted ArtifactSet에는 서로 다른 reviewer가 작성한 technical-semantic·technical-visual review가 필요합니다.
+-
+-### Image Generation
+-
+-`image-generation`은 사진·일러스트·재질·분위기 같은 organic raster를 소유합니다. production 경로는 해시된 후보 3개, pairwise comparison, 명시적 선택, 최대 한 번의 bounded repair를 사용하며, exact architecture relation·chart·state machine·긴 정확 텍스트는 이 capability의 범위 밖입니다.
+-
+-### Workflow Runtime과 Integrations
+-
+-`workflow-runtime`은 contract validation, routing, cycle-free DAG, freshness, retry, immutable result 수집, integration dispatch, event와 portable output publication을 소유합니다. sibling harness는 서로를 직접 호출하지 않습니다.
+-
+-Markdown·Slides·HTML adapter는 runtime이 선택해 동결한 publication projection 하나만 소비하며, 내용·관점·route·renderer·provider를 다시 결정하지 않습니다.
+-
+-## 2분 검증
+-
+-
+-
+-### 전제 조건
+-
+-핵심 contract와 runtime은 Python 3에서 동작하며 PyYAML과 jsonschema를 사용합니다. Raster 검증·preview에는 Pillow가, technical rendering에는 D2가, SVG의 browser preview에는 Chrome 또는 Chromium이 필요합니다. 저장소는 이 도구들의 버전을 고정하지 않습니다.
+-
+-현재 저장소에는 `pyproject.toml`, `requirements.txt`, `setup.py`, `setup.cfg`, `Pipfile`, `poetry.lock`, `uv.lock`이 없어 하나의 정본 설치 명령을 제시할 수 없습니다. 필요한 도구를 환경에 준비한 뒤 아래 검증을 실행하십시오.
+-
+-### 1. 자연어 요청의 contract 확인
+-
+-```bash
+-python3 -m packages.content_job_contract.validate_content_job examples/clean-architecture/content-job-request.yaml --repo-root .
+-```
+-
+-
+-이 명령은 이번 README 작성 세션에서 exit code 0으로 완료됐습니다. 출력 없이 종료되면 체크인된 ContentJobRequest가 현재 contract를 통과한 것입니다.
+-
+-### 2. Front door 계획 확인
+-
+-```bash
+-python3 -m packages.workflow_runtime.content_runtime front-door --workflow-request examples/clean-architecture/workflow-request.content-job.yaml --repo-root .
+-```
+-
+-
+-이 명령도 exit code 0으로 완료됐고 `primary_capability: document-writing`인 plan을 출력했습니다. 이는 계획 단계의 확인이며 author·review provider를 호출하는 production 실행은 아닙니다.
+-
+-## 요청에서 publication까지
++### 문서 작성 — `document-writing`
++
++독자, 글의 순서, 근거 연결, 그림이 필요한 위치를 정합니다. 요청 명세, 내용 명세, 서사 계획, 게시 초안, 그림 요청을 만들지만 원문을 덮어쓰거나 렌더러를 고르지는 않습니다.
++
++### 기술 시각화 — `technical-visualization`
++
++코드와 문서에서 확인한 관계를 의미 모형으로 만들고 D2로 렌더링합니다. 현재 `dependency-graph`와 `runtime-sequence`를 만들 수 있습니다. 기술 내용과 화면 표현을 서로 다른 검토자가 승인해야 산출물 묶음이 `accepted`가 됩니다.
++
++### 이미지 생성 — `image-generation`
++
++사진, 일러스트, 재질, 분위기처럼 유기적인 래스터 이미지를 만듭니다. 후보 세 개를 비교해 하나를 고르고, 필요한 경우 한 번만 부분 수정합니다. 정확한 아키텍처 관계, 차트, 상태 전이, 긴 본문은 이 기능으로 만들지 않습니다.
++
++### 작업 실행과 게시 — `workflow-runtime`, `integrations`
++
++`workflow-runtime`은 요청 검사, 분기, 작업 순서, 재시도, 결과 취합을 담당합니다. 세 하네스는 서로를 직접 호출하지 않습니다.
++
++`Markdown`, `Slides`, `HTML` 어댑터는 작업 실행기가 확정한 게시 자료만 받습니다. 어댑터가 내용이나 생성 도구를 다시 고르지는 않습니다.
++
++## 요청이 결과가 되는 과정
+
+
+
+-Contract chain은 `ContentJobRequest` → `Content Manifest` → `Narrative Plan` → `Visual Request` → `ArtifactSet` → frozen publication projection 순서로 책임을 좁혀 갑니다. JSON Schema는 구조를, Python validator는 현재 파일 hash·safe path·cross-contract ID·evidence·routing·freshness처럼 schema만으로 표현하기 어려운 조건을 확인합니다.
+-
+-Visual Request의 신호가 technical-only이면 `technical-visualization`, image-only이면 `image-generation`, 둘 다이면 runtime-owned hybrid DAG로 라우팅됩니다. 신호가 없으면 `BLOCKED_UNRESOLVED`, 명시적 충돌이면 `ROUTING_CONFLICT`입니다.
+-
+-각 harness는 plan 또는 immutable JobResult를 runtime에 반환합니다. Runtime만 sibling 결과를 조립하고 accepted rendition의 publication projection을 동결해 integration adapter로 넘깁니다.
+-
+-Deterministic validation은 expert review를 대신하지 않습니다. 필수 review가 없는 유효한 technical 결과는 `produced`에 머물며 `accepted`나 integration-ready로 승격되지 않습니다.
+-
+-다음 흐름은 request와 contract가 runtime에서 sibling capability로 분기한 뒤 reviewed draft 또는 accepted ArtifactSet으로 합류하는 지점을 요약합니다.
++파일 계약은 `ContentJobRequest` → `Content Manifest` → `Narrative Plan` → `Visual Request` → `ArtifactSet` → 게시 자료 순서로 이어집니다. 각 단계는 다음 단계가 받아도 되는 정보와 검토 상태를 제한합니다.
++
++그림 요청이 기술 관계만 포함하면 `technical-visualization`, 이미지 표현만 포함하면 `image-generation`으로 보냅니다. 둘 다 필요하면 `workflow-runtime`이 두 결과를 합치는 작업 순서를 만듭니다. 신호가 없거나 서로 충돌하면 실행을 막습니다.
+
+ ```mermaid
+ flowchart LR
+- A["자연어 요청"] --> B["ContentJobRequest / Visual Request"]
+- B --> R{"workflow-runtime routing · DAG · freshness"}
+- R --> D["document-writing"]
+- R --> T["technical-visualization"]
+- R --> I["image-generation"]
+- T --> H["runtime-owned hybrid composition"]
++ A["자연어 요청"] --> B["요청 명세"]
++ B --> R{"workflow-runtime 분기 · 작업 순서 · 검토"}
++ R --> D["document-writing 문서 초안"]
++ R --> T["technical-visualization 기술 그림"]
++ R --> I["image-generation 이미지"]
++ T --> H["혼합 합성"]
+ I --> H
+- D --> O["reviewed publication draft"]
+- T --> S["accepted ArtifactSet"]
+- I --> S
+- H --> S
+- O --> P["frozen publication projection"]
+- S --> P
+- P --> G["Markdown · Slides · HTML"]
++ D --> P["검토된 게시 자료"]
++ T --> P
++ I --> P
++ H --> P
++ P --> O["Markdown · Slides · HTML"]
+ ```
+
+
+
+-## 생성 산출물 둘러보기
+-
+-
+-
+-### 버전 관리되는 contract example
+-
+-[Clean Architecture 예제](examples/clean-architecture/)는 ContentJobRequest부터 Visual Request와 ArtifactSet까지 이어지는 체크인된 contract chain입니다. `artifact/attempt-01/`에는 document·presentation·reveal-step SVG와 `accepted`/`ready` 상태의 manifest가 있지만, 이는 renderer-backed golden이 아니라 최소 contract fixture입니다.
+-
+-- [ArtifactSet manifest](examples/clean-architecture/artifact/attempt-01/artifact-set.yaml)
+-- [문서용 SVG fixture](examples/clean-architecture/artifact/attempt-01/dependency-directions.svg)
+-- [발표용 SVG fixture](examples/clean-architecture/artifact/attempt-01/dependency-directions.presentation.svg)
+-
+-### 현재 작업 사본의 로컬 테스트 산출물
+-
+-현재 작업 사본에는 문서 작성·기술 시각화·이미지 생성을 함께 통과시킨 로컬 P6 결과가 있습니다. `runs/p6-all-harness-quality-executable-clean-architecture-20260717/output/` 아래에는 `final-document.md`, `index.html`, 전체 문서 `preview.png`, 문서·발표용 dependency-direction SVG, organic PNG 두 target, image candidate contact sheet와 validation manifest가 있습니다.
+-
+-문서와 기술 시각화를 함께 시험한 `runs/docvis-20260716-executable-clean-architecture-part1/`에는 통합 HTML, desktop·mobile 문서 preview, 두 figure의 target별 SVG와 PNG fallback, delivery·asset manifest가 있습니다.
+-
+-Best-of-three 이미지 예제인 `runs/img-20260716-japanese-animation-test/`는 3개 후보 중 attempt 2를 `BEST_OF_N_PASS`로 선택하고 `outputs/final-selected.png`를 남겼습니다.
+-
+-| 산출물 유형 | 로컬 예시 | 확인할 것 |
++`workflow-runtime`이 세 하네스로 요청을 나누고, 검토를 마친 결과를 게시 자료로 합칩니다.
++
++구조 검사만 통과한 결과는 바로 게시하지 않습니다. 문서는 지정된 검토를 마쳐야 하고, 기술 그림과 이미지는 `accepted`이면서 통합 준비 상태여야 합니다.
++
++## 저장소 구성과 변경 위치
++
++
++
++| 경로 | 맡는 일 | 이럴 때 먼저 확인 |
+ | --- | --- | --- |
+-| 생성 문서 | `output/final-document.md`, `output/index.html`, `output/preview.png` | Markdown·HTML·전체 페이지 preview와 delivery manifest |
+-| 기술 시각화 | `assets/dependency-directions.document.svg`, `assets/dependency-directions.presentation.svg` | 같은 semantic source의 target별 크기·표현 |
+-| 생성 이미지 | `assets/editorial-workbench.document.png`, `assets/editorial-workbench.presentation.png` | target별 organic rendition과 선택된 candidate hash |
+-| 비교·검토 자료 | `assets/image-candidates.png`, `validation-summary.yaml` | 후보 contact sheet와 capability별 validation 결과 |
+-
+-`runs/**`는 `.gitignore` 대상인 로컬 immutable 실행 작업공간이며 cache나 source of truth가 아닙니다. 새 실행은 `runs//run--NNN/`을 할당하고, reviewed deliverable이 있으면 `/output/index.html`과 hash-bound `manifest.yaml`을 만들 수 있습니다.
+-
+-따라서 위 로컬 PNG·SVG를 README에 직접 임베드하지 않았습니다. GitHub에서 지속되는 gallery가 필요하면 검토된 파일을 `examples/` 또는 별도 versioned 문서 asset 경로로 승격하고, provenance와 manifest를 함께 갱신해야 합니다.
+-
+-자세한 실행 데이터 정책은 [Runtime workspace](runs/README.md)를 참고하십시오.
+-
+-## 저장소 구조와 변경 위치
+-
+-
+-
+-| 경로 | 정본 책임 | 변경할 때 함께 볼 곳 |
+-| --- | --- | --- |
+-| `.agents/`, `.codex/` | AI 도구의 thin discovery adapter | 해당 capability의 `harnesses/` 정본 |
+-| `harnesses/` | document·technical visual·image capability 정책과 구현 | `packages/` contract, capability test |
+-| `packages/` | contract, schema support, workflow runtime | schema fixture, conformance·runtime test |
+-| `integrations/` | frozen projection을 받는 Markdown·Slides·HTML adapter | publication adapter test |
+-| `tests/` | conformance, contract, runtime, failure injection, E2E | `tests/golden/` regression oracle |
+-| `examples/` | versioned executable contract chain | validator와 example manifest |
+-| `benchmarks/` | suite, failure corpus, qualification result | policy의 qualification 상태 |
+-| `runs/` | ignored local execution data | `runs/README.md`; 정본으로 사용 금지 |
+-
+-이 소유권 지도에서 `.agents/.codex`는 adapter, `harnesses`는 capability 구현, `packages`는 contract와 runtime, `integrations`는 publication target을 담당합니다.
+-
+-정본 의존 방향은 adapter → harnesses → packages이며, `workflow-runtime`은 handler registry를 통해 harness를 실행하고 frozen projection만 integrations로 보냅니다. Contract와 integration adapter가 harness implementation을 역으로 소유하지 않습니다.
+-
+-구체적인 contract chain과 hybrid composition 경계는 [ARCHITECTURE.md](ARCHITECTURE.md)에 있습니다.
+-
+-## 검증 명령과 증거 수준
++| `.agents/`, `.codex/` | 도구가 하네스를 찾게 하는 얇은 연결부 | 도구별 진입점 변경 |
++| `harnesses/` | 문서·기술 그림·이미지 생성 정책과 구현 | 생성 방식이나 검토 규칙 변경 |
++| `packages/` | 파일 계약, 공통 검사, 작업 실행기 | 명세 구조나 실행 순서 변경 |
++| `integrations/` | 확정된 게시 자료를 `Markdown`·`Slides`·`HTML`로 변환 | 출력 형식 변경 |
++| `tests/` | 계약·실행·실패 조건·저장소 구성 검사 | 동작 변경과 회귀 검사 추가 |
++| `examples/` | 버전 관리되는 실행 예제 | 재현 가능한 예제 추가 |
++| `benchmarks/` | 평가 자료와 판정 결과 | 품질 기준이나 비교 자료 변경 |
++| `runs/` | 버전 관리하지 않는 실행 기록 | 실행 재개와 실패 원인 확인 |
++
++정본 의존 방향은 도구 연결부 → 하네스 → 공통 계약입니다. `workflow-runtime`은 등록 파일을 통해 하네스를 실행하고, 확정된 게시 자료만 `integrations`로 보냅니다.
++
++전체 계약 사슬과 혼합 합성 경계는 [ARCHITECTURE.md](ARCHITECTURE.md)에 정리돼 있습니다.
++
++## 검증
+
+
+
+-이번 README 작업에서는 다음 세 검증도 저장소 루트에서 실제 실행했습니다.
++아래 결과는 2026-07-19에 저장소 루트에서 확인했습니다.
++
++### 내용 명세
+
+ ```bash
+ python3 -m packages.content_contract.validate_content examples/clean-architecture/content-manifest.yaml --repo-root .
+ ```
+
+
+-결과: `VALID`, exit code 0.
++결과는 `VALID`, 종료 코드 0입니다.
++
++### 기술 그림 산출물 묶음
+
+ ```bash
+ python3 -m packages.artifact_contract.validate_artifact_set examples/clean-architecture/artifact/attempt-01/artifact-set.yaml --request examples/clean-architecture/visual-request.yaml
+ ```
+
+
+-결과: `VALID`, exit code 0. 이 검증은 체크인된 contract fixture를 대상으로 하며 fresh renderer execution을 대신하지 않습니다.
++결과는 `VALID`, 종료 코드 0입니다. 이 명령은 버전 관리되는 계약 예시를 검사하며 새 그림을 렌더링하지 않습니다.
++
++### 저장소 구성
+
+ ```bash
+ python3 -m unittest tests.conformance.test_repository_layout
+ ```
+
+
+-결과: 18개 test가 통과했습니다. 이 범위는 canonical directory와 adapter boundary를 확인하며 전체 suite를 대신하지 않습니다.
+-
+-전체 discovery 명령은 다음과 같이 정의돼 있습니다.
++구성 검사 18개가 통과했습니다.
++
++### 전체 테스트
+
+ ```bash
+ python3 -m unittest discover -s tests -p 'test_*.py'
+ ```
+
+
+-전체 suite는 이번 README 작업에서 재실행하지 않았습니다. [2026-07-18 refactoring review](docs/refactoring-review.md#verification-performed)는 별도의 300-test pass를 기록하지만, 이를 이번 실행 결과로 재표현하지 않습니다.
+-
+-Renderer-backed E2E는 외부 Java/Gradle evidence repository, 외부 source document 또는 scope별 expert review 파일을 요구합니다. exact run root를 단계 사이에 전달하는 명령은 [End-to-end workflows](tests/end-to-end/README.md)에 분리돼 있습니다.
+-
+-## 현재 상태와 한계
++전체 테스트 300개가 615.249초에 통과했습니다. 외부 자료와 별도 검토 파일을 넣어야 하는 종단 간 작업은 이 결과와 구분해야 합니다.
++
++외부 입력을 준비하는 방법은 [종단 간 작업 안내](tests/end-to-end/README.md)에 있습니다.
++
++## 현재 한계
+
+
+
+-- **설치 재현성:** dependency packaging manifest와 version pin이 없으므로 README는 임의의 패키지 설치 명령이나 최소 버전을 만들지 않습니다.
+-- **산출물 지속성:** 실제 PNG·SVG·HTML·Markdown 샘플은 로컬 `runs/`에 있지만 clean checkout이나 GitHub 링크의 영속성을 보장하지 않습니다.
+-- **Benchmark 성숙도:** document-writing과 image-generation suite는 corpus만 정의되고 결과가 pending입니다. Technical visualization의 dependency-direction 비교도 일부 condition과 human preference가 남아 있습니다.
+-- **Hybrid qualification:** `d2-svg-layer-compositor`의 자동 16-case 증거는 PASS지만 human Gate 3는 `PENDING`입니다. 이 renderer는 qualification candidate이며 qualified renderer로 소개하면 안 됩니다.
+-- **E2E 입력:** 전체 품질·dependency-direction·redraw 경로는 이 저장소만으로 완결되지 않고 외부 evidence/source와 완료된 expert review를 요구합니다.
+-
+-## 문서와 정본 지도
++- **설치 절차:** 패키지 설정 파일과 버전 고정값이 없어 하나의 재현 가능한 설치 명령을 제공하지 못합니다.
++- **실행 기록:** `runs/`는 버전 관리 대상이 아닙니다. 재사용할 예시는 `docs/`나 `examples/`로 옮기고 출처를 함께 기록해야 합니다.
++- **외부 입력:** 일부 종단 간 작업에는 외부 Java·Gradle 저장소, 원문, 완료된 전문가 검토 파일이 필요합니다.
++- **평가 자료:** 문서 작성과 이미지 생성 평가는 자료 구조만 정의돼 있고 결과는 아직 없습니다. 기술 시각화 비교에도 실행하지 않은 조건과 사람 선호 판정이 남아 있습니다.
++- **혼합 합성:** `d2-svg-layer-compositor`는 자동 검사에 통과했지만 사람 검토가 남아 있어 정식 렌더러로 분류하지 않습니다.
++
++## 더 읽을 문서
+
+
+
+-정본 설계는 `ARCHITECTURE.md`, 문서 색인은 `docs/README.md`, 실행 작업공간 정책은 `runs/README.md`에 있습니다.
+-
+-- [Architecture](ARCHITECTURE.md) — layering, contract chain, routing, review authority, run identity
+-- [Documentation map](docs/README.md) — 현재 문서와 historical implementation 기록의 구분
+-- [Runtime workspace](runs/README.md) — fresh allocation, exact resume, output publication
+-- [Document Writing Harness](harnesses/document-writing/README.md)
+-- [Technical Visualization Harness](harnesses/technical-visualization/README.md)
+-- [Image Generation Harness](harnesses/image-generation/README.md)
+-- [Workflow Runtime](packages/workflow-runtime/README.md)
+-- [Clean Architecture example](examples/clean-architecture/)
+-- [End-to-end workflows](tests/end-to-end/README.md)
+-- [Benchmarks](benchmarks/technical-visualization/README.md) · [image quality](benchmarks/image-quality/README.md) · [hybrid composition](benchmarks/hybrid-composition/README.md)
+-
+-과거 phase 문서는 구현 이력일 뿐 현재 capability 정의가 아닙니다. 현재 동작을 바꿀 때는 위 정본과 관련 contract·test·benchmark를 함께 갱신하십시오.
++- [전체 설계](ARCHITECTURE.md) — 계층, 계약, 분기, 검토 권한
++- [문서 색인](docs/README.md) — 현재 문서와 구현 이력의 구분
++- [실행 작업공간](runs/README.md) — 새 실행 할당, 재개, 결과 게시
++- [문서 작성 하네스](harnesses/document-writing/README.md)
++- [기술 시각화 하네스](harnesses/technical-visualization/README.md)
++- [이미지 생성 하네스](harnesses/image-generation/README.md)
++- [작업 실행기](packages/workflow-runtime/README.md)
++- [Clean Architecture 예제](examples/clean-architecture/)
++- [평가 자료](benchmarks/technical-visualization/README.md) · [이미지 품질](benchmarks/image-quality/README.md) · [혼합 합성](benchmarks/hybrid-composition/README.md)
diff --git a/runs/image-haness/20260719-reader-first-korean/apply-manifest.yaml b/runs/image-haness/20260719-reader-first-korean/apply-manifest.yaml
new file mode 100644
index 0000000..afff2c3
--- /dev/null
+++ b/runs/image-haness/20260719-reader-first-korean/apply-manifest.yaml
@@ -0,0 +1,7 @@
+schema-version: 1
+mode: bootstrap
+target-rel: README.md
+generated-hash: sha256:f1e6ff9c315bbd56e83bf6192e73da50096a54a38c2a987232f82a3ee36a4f86
+target-before-hash: sha256:bb63802996c738e926449e65ee9319825b4bf4f2ab3379ee31afa85e1d5c3cc4
+repository-snapshot-hash: sha256:0f6969583accd44093b1df782f287d582dfc24bbebbc56d2adefb1c2381f2854
+review-score: 94
diff --git a/runs/image-haness/20260719-reader-first-korean/claim-map.yaml b/runs/image-haness/20260719-reader-first-korean/claim-map.yaml
new file mode 100644
index 0000000..3eafead
--- /dev/null
+++ b/runs/image-haness/20260719-reader-first-korean/claim-map.yaml
@@ -0,0 +1,239 @@
+schema-version: 1
+claims:
+ - id: C-IDENTITY
+ type: factual
+ statement: 이 저장소는 자연어로 받은 콘텐츠 요청을 문서, 기술 그림, 이미지로 만드는 파이썬 프로젝트입니다.
+ section: overview
+ sources: [{fact-id: F-IDENTITY}, {fact-id: F-SIBLING-HARNESSES}]
+ status: supported
+
+ - id: C-SHOWCASE-STATUS
+ type: factual
+ statement: 아래 세 파일은 `p6-all-harness-quality-executable-clean-architecture-20260717` 실행에서 검토와 통합 검증을 통과한 결과입니다.
+ section: showcase
+ sources: [{fact-id: F-README-SHOWCASE}]
+ status: supported
+
+ - id: C-SHOWCASE-PROVENANCE
+ type: factual
+ statement: "[산출물 출처 기록](docs/assets/readme-showcase/provenance.yaml)에는 원본 실행 경로, 파일별 SHA-256 해시, 크기, 검토 상태가 들어 있습니다."
+ section: showcase
+ sources: [{fact-id: F-README-SHOWCASE}]
+ status: supported
+
+ - id: C-PREREQUISITES
+ type: factual
+ statement: 기본 실행에는 `Python 3`, `PyYAML`, `jsonschema`가 필요합니다.
+ section: quick-start
+ sources: [{fact-id: F-PREREQUISITES}]
+ status: supported
+
+ - id: C-INSTALLATION-LIMIT
+ type: factual
+ statement: "`pyproject.toml`, `requirements.txt` 같은 패키지 설정 파일도 없습니다."
+ section: quick-start
+ sources: [{fact-id: F-NO-PACKAGE-MANIFEST}]
+ status: supported
+
+ - id: C-CMD-CONTENT-JOB
+ type: factual
+ statement: python3 -m packages.content_job_contract.validate_content_job examples/clean-architecture/content-job-request.yaml --repo-root .
+ section: quick-start
+ sources: [{fact-id: F-EXAMPLE-CHAIN}, {fact-id: F-EXECUTED-QUICK-CHECKS}]
+ status: supported
+
+ - id: C-RESULT-CONTENT-JOB
+ type: factual
+ statement: 2026-07-19 실행에서는 종료 코드 0으로 끝났습니다.
+ section: quick-start
+ sources: [{fact-id: F-EXECUTED-QUICK-CHECKS}]
+ status: supported
+
+ - id: C-CMD-FRONT-DOOR
+ type: factual
+ statement: python3 -m packages.workflow_runtime.content_runtime front-door --workflow-request examples/clean-architecture/workflow-request.content-job.yaml --repo-root .
+ section: quick-start
+ sources: [{fact-id: F-EXAMPLE-CHAIN}, {fact-id: F-EXECUTED-QUICK-CHECKS}]
+ status: supported
+
+ - id: C-RESULT-FRONT-DOOR
+ type: factual
+ statement: "2026-07-19 실행에서는 종료 코드 0과 `primary_capability: document-writing` 계획을 확인했습니다."
+ section: quick-start
+ sources: [{fact-id: F-EXECUTED-QUICK-CHECKS}]
+ status: supported
+
+ - id: C-DOCUMENT-CAPABILITY
+ type: factual
+ statement: 독자, 글의 순서, 근거 연결, 그림이 필요한 위치를 정합니다.
+ section: capabilities
+ sources: [{fact-id: F-CAPABILITY-DOCUMENT}]
+ status: supported
+
+ - id: C-TECHNICAL-CAPABILITY
+ type: factual
+ statement: 코드와 문서에서 확인한 관계를 의미 모형으로 만들고 D2로 렌더링합니다.
+ section: capabilities
+ sources: [{fact-id: F-CAPABILITY-TECHNICAL}]
+ status: supported
+
+ - id: C-IMAGE-CAPABILITY
+ type: factual
+ statement: 사진, 일러스트, 재질, 분위기처럼 유기적인 래스터 이미지를 만듭니다.
+ section: capabilities
+ sources: [{fact-id: F-CAPABILITY-IMAGE}]
+ status: supported
+
+ - id: C-RUNTIME-CAPABILITY
+ type: factual
+ statement: "`workflow-runtime`은 요청 검사, 분기, 작업 순서, 재시도, 결과 취합을 담당합니다."
+ section: capabilities
+ sources: [{fact-id: F-SIBLING-HARNESSES}, {fact-id: F-RUN-WORKSPACE}]
+ status: supported
+
+ - id: C-INTEGRATIONS
+ type: factual
+ statement: "`Markdown`, `Slides`, `HTML` 어댑터는 작업 실행기가 확정한 게시 자료만 받습니다."
+ section: capabilities
+ sources: [{fact-id: F-INTEGRATIONS}]
+ status: supported
+
+ - id: C-CONTRACT-CHAIN
+ type: factual
+ statement: 파일 계약은 `ContentJobRequest` → `Content Manifest` → `Narrative Plan` → `Visual Request` → `ArtifactSet` → 게시 자료 순서로 이어집니다.
+ section: execution-model
+ sources: [{fact-id: F-CONTRACT-CHAIN}]
+ status: supported
+
+ - id: C-ROUTING
+ type: factual
+ statement: 그림 요청이 기술 관계만 포함하면 `technical-visualization`, 이미지 표현만 포함하면 `image-generation`으로 보냅니다.
+ section: execution-model
+ sources: [{fact-id: F-ROUTING}]
+ status: supported
+
+ - id: C-ACCEPTANCE-BOUNDARY
+ type: factual
+ statement: 구조 검사만 통과한 결과는 바로 게시하지 않습니다.
+ section: execution-model
+ sources: [{fact-id: F-CAPABILITY-DOCUMENT}, {fact-id: F-CAPABILITY-TECHNICAL}, {fact-id: F-CAPABILITY-IMAGE}, {fact-id: F-PORTABLE-OUTPUT}]
+ status: supported
+
+ - id: C-FLOW-RELATIONSHIPS
+ type: factual
+ statement: "`workflow-runtime`이 세 하네스로 요청을 나누고, 검토를 마친 결과를 게시 자료로 합칩니다."
+ section: execution-model
+ sources: [{fact-id: F-SIBLING-HARNESSES}, {fact-id: F-CONTRACT-CHAIN}, {fact-id: F-INTEGRATIONS}]
+ status: supported
+
+ - id: C-DEPENDENCY-DIRECTION
+ type: factual
+ statement: 정본 의존 방향은 도구 연결부 → 하네스 → 공통 계약입니다.
+ section: architecture
+ sources: [{fact-id: F-REPOSITORY-LAYERS}, {fact-id: F-SIBLING-HARNESSES}, {fact-id: F-INTEGRATIONS}]
+ status: supported
+
+ - id: C-VERIFICATION-DATE
+ type: factual
+ statement: 아래 결과는 2026-07-19에 저장소 루트에서 확인했습니다.
+ section: verification
+ sources: [{fact-id: F-EXECUTED-QUICK-CHECKS}]
+ status: supported
+
+ - id: C-CMD-CONTENT-MANIFEST
+ type: factual
+ statement: python3 -m packages.content_contract.validate_content examples/clean-architecture/content-manifest.yaml --repo-root .
+ section: verification
+ sources: [{fact-id: F-EXAMPLE-CHAIN}, {fact-id: F-EXECUTED-QUICK-CHECKS}]
+ status: supported
+
+ - id: C-RESULT-CONTENT-MANIFEST
+ type: factual
+ statement: 결과는 `VALID`, 종료 코드 0입니다.
+ section: verification
+ sources: [{fact-id: F-EXECUTED-QUICK-CHECKS}]
+ status: supported
+
+ - id: C-CMD-ARTIFACT-SET
+ type: factual
+ statement: python3 -m packages.artifact_contract.validate_artifact_set examples/clean-architecture/artifact/attempt-01/artifact-set.yaml --request examples/clean-architecture/visual-request.yaml
+ section: verification
+ sources: [{fact-id: F-VERSIONED-VISUALS}, {fact-id: F-EXECUTED-QUICK-CHECKS}]
+ status: supported
+
+ - id: C-RESULT-ARTIFACT-SET
+ type: factual
+ statement: 이 명령은 버전 관리되는 계약 예시를 검사하며 새 그림을 렌더링하지 않습니다.
+ section: verification
+ sources: [{fact-id: F-VERSIONED-VISUALS}, {fact-id: F-EXECUTED-QUICK-CHECKS}]
+ status: supported
+
+ - id: C-CMD-LAYOUT-TEST
+ type: factual
+ statement: python3 -m unittest tests.conformance.test_repository_layout
+ section: verification
+ sources: [{fact-id: F-TEST-INVENTORY}, {fact-id: F-EXECUTED-QUICK-CHECKS}]
+ status: supported
+
+ - id: C-RESULT-LAYOUT-TEST
+ type: factual
+ statement: 구성 검사 18개가 통과했습니다.
+ section: verification
+ sources: [{fact-id: F-TEST-INVENTORY}, {fact-id: F-EXECUTED-QUICK-CHECKS}]
+ status: supported
+
+ - id: C-CMD-FULL-SUITE
+ type: factual
+ statement: "python3 -m unittest discover -s tests -p 'test_*.py'"
+ section: verification
+ sources: [{fact-id: F-TEST-INVENTORY}, {fact-id: F-EXECUTED-QUICK-CHECKS}]
+ status: supported
+
+ - id: C-RESULT-FULL-SUITE
+ type: factual
+ statement: 전체 테스트 300개가 615.249초에 통과했습니다.
+ section: verification
+ sources: [{fact-id: F-TEST-INVENTORY}, {fact-id: F-EXECUTED-QUICK-CHECKS}]
+ status: supported
+
+ - id: C-E2E-PREREQUISITES
+ type: factual
+ statement: "외부 입력을 준비하는 방법은 [종단 간 작업 안내](tests/end-to-end/README.md)에 있습니다."
+ section: verification
+ sources: [{fact-id: F-E2E-INPUTS}]
+ status: supported
+
+ - id: C-LIMIT-PACKAGING
+ type: factual
+ statement: 패키지 설정 파일과 버전 고정값이 없어 하나의 재현 가능한 설치 명령을 제공하지 못합니다.
+ section: limitations
+ sources: [{fact-id: F-NO-PACKAGE-MANIFEST}, {fact-id: F-PREREQUISITES}]
+ status: supported
+
+ - id: C-LIMIT-RUNS
+ type: factual
+ statement: "`runs/`는 버전 관리 대상이 아닙니다."
+ section: limitations
+ sources: [{fact-id: F-RUNS-NONCANONICAL}, {fact-id: F-README-SHOWCASE}]
+ status: supported
+
+ - id: C-LIMIT-E2E
+ type: factual
+ statement: 일부 종단 간 작업에는 외부 Java·Gradle 저장소, 원문, 완료된 전문가 검토 파일이 필요합니다.
+ section: limitations
+ sources: [{fact-id: F-E2E-INPUTS}]
+ status: supported
+
+ - id: C-LIMIT-BENCHMARKS
+ type: factual
+ statement: 문서 작성과 이미지 생성 평가는 자료 구조만 정의돼 있고 결과는 아직 없습니다.
+ section: limitations
+ sources: [{fact-id: F-BENCHMARK-MATURITY}]
+ status: supported
+
+ - id: C-LIMIT-HYBRID
+ type: factual
+ statement: "`d2-svg-layer-compositor`는 자동 검사에 통과했지만 사람 검토가 남아 있어 정식 렌더러로 분류하지 않습니다."
+ section: limitations
+ sources: [{fact-id: F-HYBRID-PENDING}]
+ status: supported
diff --git a/runs/image-haness/20260719-reader-first-korean/execution-evidence.yaml b/runs/image-haness/20260719-reader-first-korean/execution-evidence.yaml
new file mode 100644
index 0000000..7be601b
--- /dev/null
+++ b/runs/image-haness/20260719-reader-first-korean/execution-evidence.yaml
@@ -0,0 +1,34 @@
+schema-version: 1
+repository: /home/donghyeon/workspace/ai-tool/image-haness
+executed-at: 2026-07-19
+working-directory: repository root
+commands:
+ - id: CMD-001
+ exit-code: 0
+ observed: 출력 없이 완료
+ independently-rechecked: true
+ - id: CMD-002
+ exit-code: 0
+ observed: "primary_capability: document-writing"
+ independently-rechecked: true
+ - id: CMD-003
+ exit-code: 0
+ observed: VALID
+ independently-rechecked: true
+ - id: CMD-004
+ exit-code: 0
+ observed: VALID
+ independently-rechecked: true
+ - id: CMD-005
+ exit-code: 0
+ observed: 18 tests passed
+ independently-rechecked: true
+ - id: CMD-006
+ exit-code: 0
+ observed: 300 tests passed
+ duration-seconds: 615.249
+ independently-rechecked: false
+limitations:
+ - 독립 실행 검증자는 CMD-001부터 CMD-005까지 다시 실행했다.
+ - CMD-006은 현재 README 작성 세션에서 실행했으며 독립 검증자는 300개 테스트가 존재하는지만 다시 확인했다.
+ - verification.json의 정적 검사 결과와 실제 실행 결과는 서로 다른 검증 수준이다.
diff --git a/runs/image-haness/20260719-reader-first-korean/prose-report.json b/runs/image-haness/20260719-reader-first-korean/prose-report.json
new file mode 100644
index 0000000..6f0a91e
--- /dev/null
+++ b/runs/image-haness/20260719-reader-first-korean/prose-report.json
@@ -0,0 +1,16 @@
+{
+ "schema-version": 1,
+ "policy-id": "korean-reader-prose-v1",
+ "language": "ko-KR",
+ "applicable": true,
+ "scope": "candidate",
+ "state": "PASS",
+ "summary": {
+ "errors": 0,
+ "warnings": 0,
+ "sentences": 78,
+ "prose-characters": 2023,
+ "hangul-characters": 1775
+ },
+ "findings": []
+}
\ No newline at end of file
diff --git a/runs/image-haness/20260719-reader-first-korean/quality-manifest.yaml b/runs/image-haness/20260719-reader-first-korean/quality-manifest.yaml
new file mode 100644
index 0000000..4ced23e
--- /dev/null
+++ b/runs/image-haness/20260719-reader-first-korean/quality-manifest.yaml
@@ -0,0 +1,14 @@
+schema-version: 2
+mode: bootstrap
+profile: generic
+repository-snapshot-hash: sha256:0f6969583accd44093b1df782f287d582dfc24bbebbc56d2adefb1c2381f2854
+artifacts:
+ readme-request.yaml: sha256:8ab945ced2bb7ee124f55c12baa41759a971e5b72267d4f4284b22020281e9a9
+ repository-facts.yaml: sha256:997882f1cdf9e9a69797939fc2db58a3757d027184c70ab67c7133612461979f
+ readme-brief.yaml: sha256:2f60e1fb0f63467b213c5ce483ff88413b9982fcb0841394c3ef3edbb15c14f9
+ readme-outline.yaml: sha256:4d49c2204058ed1b3d8ff0b4f684a704f1c24e386f43cec9c214f47b338a5b66
+ README.candidate.md: sha256:f1e6ff9c315bbd56e83bf6192e73da50096a54a38c2a987232f82a3ee36a4f86
+ claim-map.yaml: sha256:1ba678e33ec7ea25b5d675c5cfbad9b8c3736ac13fdeba62424bddff345fadd5
+ visual-plan.yaml: sha256:1440c3055cede6634bf9adbfe4343631e97e1f21a8ee2ea8f04f5753c2555b79
+ prose-report.json: sha256:bc4f0930ea0996bcf969ff12433d2c7c0f5a9c06796243d06e828e64a2b2772c
+ review-findings.yaml: sha256:fdd3180866eb42edf14162e2160b54dfd382c44ea280880744356424a5428fec
diff --git a/runs/image-haness/20260719-reader-first-korean/readme-brief.yaml b/runs/image-haness/20260719-reader-first-korean/readme-brief.yaml
new file mode 100644
index 0000000..b59beca
--- /dev/null
+++ b/runs/image-haness/20260719-reader-first-korean/readme-brief.yaml
@@ -0,0 +1,51 @@
+schema-version: 1
+project-profile:
+ primary: generic
+ secondary:
+ - 여러 종류의 콘텐츠를 만드는 작업 흐름
+ - 파일 계약으로 연결된 Python 시스템
+audiences:
+ primary:
+ - 콘텐츠 하네스가 만드는 결과와 실행 방법을 확인하려는 개발자
+ - 문서 작성, 기술 시각화, 이미지 생성 기능을 수정하려는 개발자
+ secondary:
+ - 산출물의 근거와 검토 절차를 확인하려는 기술 책임자
+reader-outcomes:
+ - 검토를 통과한 문서, 이미지, 기술 시각화 결과를 바로 확인한다.
+ - 예제 요청을 검사하고 전체 테스트를 실행할 수 있다.
+ - 네 기능의 책임과 서로 직접 호출하지 않는 경계를 설명할 수 있다.
+ - 변경하려는 기능의 정본 경로를 찾을 수 있다.
+ - 실행 기록, 버전 관리되는 예시, 아직 끝나지 않은 검증을 구분한다.
+project-story:
+ value-proposition: 자연어 요청을 문서, 기술 그림, 이미지로 만들고 검토가 끝난 결과만 게시 파일로 묶는다.
+ problem: 결과 종류마다 생성 방법과 검토 기준이 다르므로, 한 작업 흐름으로 연결하되 각 기능의 책임은 섞이지 않아야 한다.
+ target-reader: 저장소를 평가하거나 기능을 수정하려는 개발자
+ notable-traits:
+ - text: 문서 작성, 기술 시각화, 이미지 생성은 서로 직접 호출하지 않으며 작업 실행기가 분기와 결과 조립을 맡는다.
+ fact-ids: [F-SIBLING-HARNESSES, F-ROUTING]
+ - text: 검토를 통과한 대표 산출물 세 개를 영구 문서 경로에서 바로 볼 수 있다.
+ fact-ids: [F-README-SHOWCASE]
+ - text: 요청부터 게시 파일까지 단계마다 별도 계약을 사용한다.
+ fact-ids: [F-CONTRACT-CHAIN, F-INTEGRATIONS]
+ - text: 새 실행은 기존 결과를 덮어쓰지 않고 별도 작업공간을 만든다.
+ fact-ids: [F-RUN-WORKSPACE]
+ maturity: 핵심 계약과 네 기능, 통합 어댑터, 300개 테스트가 구현돼 있다. 일부 평가 자료와 혼합 합성기의 사람 검토는 아직 끝나지 않았다.
+ limitations:
+ - 의존성 버전과 설치 절차를 고정하는 패키지 설정 파일이 없다.
+ - 외부 자료와 별도 전문가 검토가 필요한 종단 간 실행이 있다.
+ - runs 아래 파일은 실행 기록이며 재사용할 예시는 docs 또는 examples로 옮겨야 한다.
+ - d2-svg-layer-compositor는 자동 검사를 통과했지만 사람 검토가 남았다.
+narrative-variant: product
+reader-journey:
+ - reader-question: 이 저장소로 만든 결과를 먼저 볼 수 있는가?
+ section-id: showcase
+ - reader-question: 가장 짧게 동작을 확인하려면 무엇을 실행하는가?
+ section-id: quick-start
+ - reader-question: 각 기능은 무엇을 맡고 어디까지 책임지는가?
+ section-id: capabilities
+ - reader-question: 요청은 어떤 단계를 거쳐 게시 파일이 되는가?
+ section-id: execution-model
+ - reader-question: 기능을 고치려면 어느 디렉터리부터 봐야 하는가?
+ section-id: architecture
+ - reader-question: 현재 통과한 검사와 남아 있는 한계는 무엇인가?
+ section-id: verification
diff --git a/runs/image-haness/20260719-reader-first-korean/readme-outline.yaml b/runs/image-haness/20260719-reader-first-korean/readme-outline.yaml
new file mode 100644
index 0000000..c69d280
--- /dev/null
+++ b/runs/image-haness/20260719-reader-first-korean/readme-outline.yaml
@@ -0,0 +1,141 @@
+schema-version: 1
+sections:
+ - id: overview
+ title-guidance: Content Harness
+ level: 1
+ purpose: 무엇을 만드는 저장소인지 두 문장 안에 밝힌다.
+ required: true
+ content-strategy: inline
+ content-requirements:
+ - 만드는 결과와 작업 실행기의 역할
+ - 이 문서가 도움 되는 독자
+ visual-slot:
+ decision: exclude
+ reader-question: 별도 표지 그림이 첫 설명보다 필요한가?
+ rationale: 바로 아래 대표 산출물이 실제 결과를 보여 주므로 장식 그림은 넣지 않는다.
+
+ - id: showcase
+ title-guidance: 검토를 마친 결과 예시
+ level: 2
+ purpose: 검토 완료된 이미지, 기술 그림, 통합 문서를 README 안에서 보여 준다.
+ required: true
+ content-strategy: inline
+ content-requirements:
+ - 이미지 생성 결과와 무엇을 판단할 수 있는지 설명
+ - 기술 시각화 결과와 무엇을 판단할 수 있는지 설명
+ - 세 기능을 합친 문서 미리보기
+ - 출처 실행, 검토 상태, 해시를 기록한 provenance 링크
+ visual-slot:
+ decision: include
+ reader-question: 실제로 어떤 결과를 만드는지 바로 확인할 수 있는가?
+ rationale: 결과물 자체를 보는 것이 기능 이름을 나열하는 것보다 빠르고 정확하다.
+ purpose: 검토 완료 산출물 세 개를 역할과 함께 보여 준다.
+
+ - id: quick-start
+ title-guidance: 먼저 실행해 보기
+ level: 2
+ purpose: 준비 사항과 가장 짧은 예제 검증 경로를 제공한다.
+ required: true
+ content-strategy: inline
+ content-requirements:
+ - Python과 선택 도구
+ - 정본 설치 명령이 없는 이유
+ - 요청 검사와 작업 계획 명령
+ - 실제 확인한 성공 결과와 범위
+ visual-slot:
+ decision: exclude
+ reader-question: 두 명령을 실행하는 데 그림이 필요한가?
+ rationale: 복사할 수 있는 명령과 성공 신호만 두는 편이 빠르다.
+
+ - id: capabilities
+ title-guidance: 기능별 책임
+ level: 2
+ purpose: 네 기능이 맡는 일과 하지 않는 일을 구분한다.
+ required: true
+ content-strategy: inline
+ content-requirements:
+ - 문서 작성
+ - 기술 시각화
+ - 이미지 생성
+ - 작업 실행기와 통합 어댑터
+ visual-slot:
+ decision: exclude
+ reader-question: 책임을 비교할 때 별도 그림이 필요한가?
+ rationale: 짧은 소제목과 경계 설명이 경로를 찾는 데 더 정확하다.
+
+ - id: execution-model
+ title-guidance: 요청이 결과가 되는 과정
+ level: 2
+ purpose: 계약 순서, 분기, 검토, 게시 파일 생성을 한 흐름으로 설명한다.
+ required: true
+ content-strategy: inline
+ content-requirements:
+ - 계약 사슬
+ - 기술 그림과 이미지 분기 규칙
+ - 검토를 통과한 결과만 합치는 경계
+ visual-slot:
+ decision: include
+ reader-question: 세 기능이 어디서 갈라지고 합쳐지는가?
+ rationale: 분기와 합류가 함께 있어 작은 흐름도가 문장보다 빠르다.
+ purpose: 작업 실행기가 세 기능을 나누고 결과를 합치는 과정을 보여 준다.
+
+ - id: architecture
+ title-guidance: 저장소 구성과 변경 위치
+ level: 2
+ purpose: 수정 목적에 따라 시작할 디렉터리를 안내한다.
+ required: true
+ content-strategy: inline
+ content-requirements:
+ - 주요 디렉터리의 정본 책임
+ - 어댑터, 하네스, 계약의 의존 방향
+ visual-slot:
+ decision: exclude
+ reader-question: 파일 경로를 찾는 데 그림이 표보다 나은가?
+ rationale: 경로와 책임을 짝지은 표가 바로 이동하기 쉽다.
+
+ - id: verification
+ title-guidance: 검증
+ level: 2
+ purpose: 이번 작업에서 실행한 검사와 성공 신호를 적는다.
+ required: true
+ content-strategy: inline
+ content-requirements:
+ - 콘텐츠 명세 검사
+ - 산출물 묶음 검사
+ - 저장소 구성 검사
+ - 전체 300개 테스트 결과
+ visual-slot:
+ decision: exclude
+ reader-question: 검사 결과를 이해하는 데 그림이 필요한가?
+ rationale: 명령과 성공 결과를 바로 붙이는 편이 재현하기 쉽다.
+
+ - id: limitations
+ title-guidance: 현재 한계
+ level: 2
+ purpose: 설치, 실행 기록, 외부 입력, 아직 끝나지 않은 평가를 밝힌다.
+ required: true
+ content-strategy: inline
+ content-requirements:
+ - 패키지 설정 파일 부재
+ - runs의 비영속성
+ - 외부 입력이 필요한 종단 간 실행
+ - 평가 자료와 사람 검토 상태
+ visual-slot:
+ decision: exclude
+ reader-question: 남은 제약을 이해하는 데 그림이 필요한가?
+ rationale: 영향과 후속 행동을 붙인 짧은 목록이면 충분하다.
+
+ - id: documentation
+ title-guidance: 더 읽을 문서
+ level: 2
+ purpose: 설계와 기능별 상세 문서로 이동하는 링크를 제공한다.
+ required: true
+ content-strategy: inline
+ content-requirements:
+ - 전체 설계
+ - 문서 색인과 실행 작업공간 정책
+ - 기능별 안내서와 종단 간 예제
+ visual-slot:
+ decision: exclude
+ reader-question: 세부 문서를 찾는 데 그림이 필요한가?
+ rationale: 목적을 붙인 상대 링크 목록이 가장 빠르다.
diff --git a/runs/image-haness/20260719-reader-first-korean/readme-request.yaml b/runs/image-haness/20260719-reader-first-korean/readme-request.yaml
new file mode 100644
index 0000000..f9937ba
--- /dev/null
+++ b/runs/image-haness/20260719-reader-first-korean/readme-request.yaml
@@ -0,0 +1,56 @@
+schema-version: 1
+target:
+ repository: /home/donghyeon/workspace/ai-tool/image-haness
+ readme-path: README.md
+mode: bootstrap
+profile-override: generic
+project-intent:
+ purpose: 저장소가 만드는 문서·기술 그림·이미지를 먼저 보여 주고, 각 기능의 책임과 실행 방법을 실제 구현과 검증 결과에 근거해 설명한다.
+ positioning: 콘텐츠 하네스를 처음 살펴보는 개발자와 기능을 수정하려는 기여자가 필요한 정보를 빠르게 찾는 저장소 안내서다.
+ maturity: 검토를 통과한 대표 산출물, 현재 구현, 실행한 테스트, 아직 끝나지 않은 검증을 서로 구분해 적는다.
+audience:
+ primary:
+ - 콘텐츠 하네스가 무엇을 만들고 어떻게 확인하는지 알고 싶은 개발자
+ - 문서 작성, 기술 시각화, 이미지 생성 흐름을 수정하려는 개발자
+ secondary:
+ - 생성 문서와 시각 산출물의 계약·검증 방식을 검토하는 기술 리더
+reader-actions:
+ - 검토를 통과한 문서, 이미지, 기술 시각화 결과를 바로 확인한다.
+ - 가장 짧은 예제 명령과 전체 테스트 명령을 실행한다.
+ - 각 기능이 맡는 일과 수정할 디렉터리를 찾는다.
+ - 실행 기록과 버전 관리되는 예시를 구분한다.
+ - 필요한 도구와 아직 끝나지 않은 검증을 확인한다.
+content-policy:
+ language: ko-KR
+ tone: 결론을 먼저 말하는 짧고 자연스러운 한국어. 제품명과 코드 식별자는 인라인 코드로 보존하고 일반 개념은 익숙한 한국어로 설명한다.
+ target-length: medium
+ preserve-existing-copy: false
+ detail-docs-policy: summary-and-link
+visual-policy:
+ mode: when-useful
+ max-visuals: 4
+ preferred-formats:
+ - repository-owned raster or SVG artifact
+ - mermaid
+ placeholder-format: HTML 주석 기반 제작 사양; 검증된 기존 산출물은 저장소 상대 경로로 직접 표시
+must-include:
+ - 프로젝트 개요와 대상 독자
+ - 검토 완료된 이미지 생성, 기술 시각화, 통합 문서 산출물 3종과 출처 기록
+ - document-writing, technical-visualization, image-generation, workflow-runtime의 책임과 연결 관계
+ - 대표 검증 또는 실행 흐름과 명령별 검증 수준
+ - 테스트로 생성된 이미지, 문서, 기술 시각화 산출물의 실제 경로와 성격
+ - 저장소 구조와 기여 위치
+ - 필수 및 선택 도구
+ - runs 디렉터리의 실행 기록 성격과 정본으로 사용하지 않는다는 경계
+ - 현재 구현 상태와 확인된 한계
+ - ARCHITECTURE.md와 docs 색인 링크
+must-exclude:
+ - 저장소 근거가 없는 기능·버전·성능·품질 우위 주장
+ - 실패·중간 후보 산출물을 성공 예시로 오인시키는 표현
+ - 비밀 값 또는 개인 환경의 절대 경로
+ - 상세 설계 이력과 모든 run 파일의 장문 나열
+ - 일반 개념을 불필요하게 영어로 나열하는 제목과 설명
+ - 작성 과정이나 문서 자체를 설명하는 메타 문장
+ - 독자의 행동과 관계없는 수식어, 반복 요약, 장식용 문구
+ - runs 경로의 파일을 README에 직접 삽입하는 링크
+protected-sections: []
diff --git a/runs/image-haness/20260719-reader-first-korean/repository-facts.yaml b/runs/image-haness/20260719-reader-first-korean/repository-facts.yaml
new file mode 100644
index 0000000..0f7922e
--- /dev/null
+++ b/runs/image-haness/20260719-reader-first-korean/repository-facts.yaml
@@ -0,0 +1,615 @@
+schema-version: 1
+repository-snapshot-hash: sha256:0f6969583accd44093b1df782f287d582dfc24bbebbc56d2adefb1c2381f2854
+project-name: Content Harness
+languages: [Python, YAML, JSON, Markdown]
+facts:
+ - id: F-IDENTITY
+ category: identity
+ key: project-purpose
+ value:
+ name: Content Harness
+ purpose: provider-neutral technical-document planning, exact technical visualization, organic image generation, and accepted-asset publication
+ assertion-type: derived
+ confidence: high
+ evidence:
+ - path: README.md
+ line-start: 1
+ line-end: 14
+ source-kind: project-documentation
+ - path: packages/workflow-runtime/handlers.yaml
+ line-start: 1
+ line-end: 8
+ source-kind: handler-registry
+
+ - id: F-REPOSITORY-LAYERS
+ category: architecture
+ key: canonical-layer-ownership
+ value:
+ .agents-and-.codex: thin provider discovery adapters
+ harnesses: capability policy and implementation canon
+ packages: contracts and runtime canon
+ integrations: publication target adapters
+ tests: repository-wide validation and golden artifacts
+ examples: versioned executable examples
+ benchmarks: evaluation suites and failure corpora
+ runs: ignored local workflow data
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: ARCHITECTURE.md
+ line-start: 3
+ line-end: 28
+ source-kind: architecture-documentation
+ - path: ARCHITECTURE.md
+ line-start: 55
+ line-end: 67
+ source-kind: architecture-documentation
+ - path: .codex/agents/natural-prose-reviewer.toml
+ line-start: 1
+ line-end: 9
+ source-kind: thin-provider-adapter
+
+ - id: F-SIBLING-HARNESSES
+ category: architecture
+ key: sibling-harness-runtime-boundary
+ value:
+ handlers: [document-writing, technical-visualization, image-generation]
+ rule: sibling harnesses return plans or results and do not call one another
+ runtime-responsibility: validation, routing, DAG execution, retries, result transfer, integration, and events
+ execution-boundary: workflow-runtime -> handlers.yaml -> HarnessHandler -> immutable JobResult
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: ARCHITECTURE.md
+ line-start: 30
+ line-end: 53
+ source-kind: architecture-documentation
+ - path: packages/workflow-runtime/handlers.yaml
+ line-start: 1
+ line-end: 8
+ source-kind: handler-registry
+ - path: tests/conformance/test_repository_layout.py
+ line-start: 43
+ line-end: 51
+ source-kind: conformance-test
+
+ - id: F-CAPABILITY-DOCUMENT
+ category: capability
+ key: document-writing
+ value:
+ owns: [narrative, audience, evidence linkage, visual-opportunity detection, figure context]
+ operations: [document-writing.intake, document-writing.analyze, document-writing.plan, document-writing.revise, document-writing.draft]
+ outputs: [content-job-request, publication-draft, content-manifest, narrative-plan, narrative-analysis, reviews, visual-requests]
+ boundary: never edits the source document in place and does not select renderers or generate imagery
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: harnesses/document-writing/README.md
+ line-start: 3
+ line-end: 29
+ source-kind: capability-documentation
+ - path: harnesses/document-writing/capability.yaml
+ line-start: 1
+ line-end: 22
+ source-kind: capability-declaration
+ - path: harnesses/document-writing/handler.py
+ line-start: 253
+ line-end: 345
+ symbol: DocumentWritingHandler
+ source-kind: implementation
+
+ - id: F-CAPABILITY-TECHNICAL
+ category: capability
+ key: technical-visualization
+ value:
+ owns: [evidence-grounded semantic models, visual grammar, deterministic rendering, target-specific renditions]
+ executable-visual-types: [dependency-graph, runtime-sequence]
+ renderer: d2
+ output-profiles: [document, presentation]
+ acceptance-boundary: separate exact-input technical-semantic and technical-visual expert reviews are required
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: harnesses/technical-visualization/README.md
+ line-start: 3
+ line-end: 23
+ source-kind: capability-documentation
+ - path: harnesses/technical-visualization/capability.yaml
+ line-start: 1
+ line-end: 23
+ source-kind: capability-declaration
+ - path: harnesses/technical-visualization/handler.py
+ line-start: 904
+ line-end: 962
+ symbol: TechnicalVisualizationHandler
+ source-kind: implementation
+
+ - id: F-CAPABILITY-IMAGE
+ category: capability
+ key: image-generation
+ value:
+ owns: [organic raster imagery, photography, illustration, bounded candidate search, local repair]
+ operations: [image-generation.generate, image-generation.generate-component]
+ production-model: three hashed candidates, pairwise comparison, explicit selection, and at most one bounded repair
+ excluded: [exact architecture relations, charts, state transitions, long exact text, evidence-derived technical geometry]
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: harnesses/image-generation/README.md
+ line-start: 3
+ line-end: 26
+ source-kind: capability-documentation
+ - path: harnesses/image-generation/capability.yaml
+ line-start: 1
+ line-end: 24
+ source-kind: capability-declaration
+ - path: harnesses/image-generation/handler.py
+ line-start: 246
+ line-end: 301
+ symbol: ImageGenerationHandler
+ source-kind: implementation
+
+ - id: F-ROUTING
+ category: architecture
+ key: visual-routing-policy
+ value:
+ technical-only: technical-visualization
+ image-only: image-generation
+ both: hybrid DAG
+ neither: BLOCKED_UNRESOLVED
+ explicit-conflict: ROUTING_CONFLICT
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: ARCHITECTURE.md
+ line-start: 100
+ line-end: 118
+ source-kind: architecture-documentation
+ - path: packages/workflow-runtime/policies/routing.yaml
+ line-start: 27
+ line-end: 31
+ source-kind: runtime-policy
+
+ - id: F-CONTRACT-CHAIN
+ category: architecture
+ key: content-to-publication-contract-chain
+ value:
+ - ContentJobRequest
+ - Content Manifest
+ - Narrative Plan
+ - Visual Request
+ - ArtifactSet
+ - frozen publication projection
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: ARCHITECTURE.md
+ line-start: 69
+ line-end: 98
+ source-kind: architecture-documentation
+
+ - id: F-INTEGRATIONS
+ category: capability
+ key: publication-adapters
+ value:
+ targets: [Markdown, Slides, HTML]
+ input: one runtime-selected frozen publication projection
+ boundary: adapters do not choose content, route, renderer, provider, or visual grammar
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: integrations/README.md
+ line-start: 1
+ line-end: 11
+ source-kind: integration-documentation
+
+ - id: F-EXAMPLE-CHAIN
+ category: examples
+ key: checked-in-clean-architecture-chain
+ value:
+ root: examples/clean-architecture
+ contracts: [content-job-request.yaml, content-manifest.yaml, narrative-plan.yaml, reference-registry.yaml, visual-request.yaml, workflow-request.content-job.yaml, workflow-request.visual.yaml, artifact/attempt-01/artifact-set.yaml]
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: tests/conformance/test_repository_layout.py
+ line-start: 480
+ line-end: 496
+ source-kind: conformance-test
+ - path: examples/clean-architecture/content-job-request.yaml
+ source-kind: versioned-example
+
+ - id: F-VERSIONED-VISUALS
+ category: artifacts
+ key: checked-in-technical-visual-contract-fixture
+ value:
+ artifact-status: accepted
+ integration-status: ready
+ scope: contract-only fixture rather than renderer-backed golden comparison
+ renditions:
+ - {path: examples/clean-architecture/artifact/attempt-01/dependency-directions.svg, target: document, dimensions: 820x460}
+ - {path: examples/clean-architecture/artifact/attempt-01/dependency-directions.presentation.svg, target: presentation, dimensions: 1600x900}
+ - {path: examples/clean-architecture/artifact/attempt-01/dependency-directions.presentation-step-1.svg, target: presentation-reveal-step, dimensions: 1600x900}
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: examples/clean-architecture/artifact/attempt-01/artifact-set.yaml
+ line-start: 2
+ line-end: 78
+ source-kind: artifact-manifest
+ - path: tests/golden/dependency-directions/README.md
+ line-start: 1
+ line-end: 7
+ source-kind: golden-fixture-documentation
+
+ - id: F-RUN-WORKSPACE
+ category: runtime
+ key: fresh-run-allocation
+ value:
+ path: runs//run--NNN/
+ semantics: each valid fresh intake or execution creates a new immutable workspace; matching request or workflow ids do not authorize reuse
+ optional-output: /output/
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: runs/README.md
+ line-start: 1
+ line-end: 32
+ source-kind: runtime-workspace-policy
+ - path: packages/workflow-runtime/README.md
+ line-start: 86
+ line-end: 98
+ source-kind: runtime-documentation
+
+ - id: F-PORTABLE-OUTPUT
+ category: artifacts
+ key: reviewed-output-bundle
+ value:
+ location: /output/
+ entrypoint: index.html
+ manifest: manifest.yaml
+ condition: reviewed publication draft or accepted integration-ready ArtifactSet
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: packages/workflow-runtime/README.md
+ line-start: 216
+ line-end: 221
+ source-kind: runtime-documentation
+ - path: tests/runtime/test_output_bundle.py
+ line-start: 176
+ line-end: 204
+ symbol: test_bundle_is_portable_and_manifest_hashes_match
+ source-kind: runtime-test
+
+ - id: F-LOCAL-CROSS-HARNESS-OUTPUT
+ category: artifacts
+ key: local-cross-harness-test-output
+ value:
+ root: runs/p6-all-harness-quality-executable-clean-architecture-20260717/output
+ generated-document: [README.md, final-document.md, index.html, preview.png]
+ technical-visualization: [assets/dependency-directions.document.svg, assets/dependency-directions.presentation.svg]
+ image-generation: [assets/editorial-workbench.document.png, assets/editorial-workbench.presentation.png, assets/image-candidates.png]
+ validation: validation-summary.yaml
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: runs/p6-all-harness-quality-executable-clean-architecture-20260717/output/manifest.yaml
+ line-start: 1
+ line-end: 35
+ source-kind: local-generated-output-manifest
+ - path: runs/p6-all-harness-quality-executable-clean-architecture-20260717/output/README.md
+ line-start: 1
+ line-end: 12
+ source-kind: local-generated-document
+ - path: runs/p6-all-harness-quality-executable-clean-architecture-20260717/output/preview.png
+ source-kind: local-generated-preview
+
+ - id: F-LOCAL-DOCUMENT-VISUALIZATION
+ category: artifacts
+ key: local-document-visualization-test-output
+ value:
+ root: runs/docvis-20260716-executable-clean-architecture-part1
+ document-output: document/part1-integrated.html
+ figures: [fig-invisible-shortcut, fig-enforcement-gradient]
+ formats: [desktop-SVG, mobile-SVG, PNG-fallback]
+ previews: [integrated-previews/part1-desktop.png, integrated-previews/part1-mobile-v2.png]
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: runs/docvis-20260716-executable-clean-architecture-part1/delivery/delivery-manifest.yaml
+ line-start: 1
+ line-end: 24
+ source-kind: local-delivery-manifest
+ - path: runs/docvis-20260716-executable-clean-architecture-part1/figures/fig-enforcement-gradient/asset-manifest.yaml
+ line-start: 1
+ line-end: 30
+ source-kind: local-figure-manifest
+
+ - id: F-LOCAL-IMAGE-OUTPUT
+ category: artifacts
+ key: local-best-of-three-image-test-output
+ value:
+ root: runs/img-20260716-japanese-animation-test
+ generation-candidates: 3
+ selected-attempt: 2
+ selected-output: outputs/final-selected.png
+ selection-label: BEST_OF_N_PASS
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: runs/img-20260716-japanese-animation-test/selection.json
+ line-start: 1
+ line-end: 64
+ source-kind: local-selection-record
+ - path: runs/img-20260716-japanese-animation-test/outputs/final-selected.png
+ source-kind: local-generated-image
+
+ - id: F-README-SHOWCASE
+ category: artifacts
+ key: reviewed-readme-showcase
+ value:
+ source-run: p6-all-harness-quality-executable-clean-architecture-20260717
+ source-status: PASS
+ promotion-policy: 검토 완료 출력만 runs에서 docs/assets/readme-showcase로 복사
+ assets:
+ - {path: docs/assets/readme-showcase/editorial-workbench.png, role: 이미지 생성 결과, dimensions: 1200x675, sha256: aaf6a848e5a1094c6620fa2545df6e9e156b2af136d7bf7486840be93fcb10f1}
+ - {path: docs/assets/readme-showcase/dependency-directions.svg, role: 기술 시각화 결과, dimensions: 1600x900, sha256: 5dacb86fb637bf0ac3ae6bf6cd9f97ea1fbc7112c02edc859ef1574cc55226cf}
+ - {path: docs/assets/readme-showcase/publication-preview.png, role: 통합 문서 결과, dimensions: 1440x2400, sha256: a12aaf738c3e4c4773666d96ba46f8e341065407e975c34a69a50d390102d979}
+ provenance: docs/assets/readme-showcase/provenance.yaml
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: docs/assets/readme-showcase/provenance.yaml
+ line-start: 1
+ line-end: 28
+ source-kind: promoted-artifact-provenance
+ - path: runs/p6-all-harness-quality-executable-clean-architecture-20260717/output/validation-summary.yaml
+ line-start: 1
+ line-end: 145
+ source-kind: local-validation-summary
+
+ - id: F-RUNS-NONCANONICAL
+ category: limitation
+ key: local-run-durability
+ value: runs/** is ignored local operational data, not a cache or source of truth; reusable examples belong under examples, regression oracles under tests/golden, and evaluation corpora under benchmarks
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: .gitignore
+ line-start: 5
+ line-end: 7
+ source-kind: ignore-policy
+ - path: runs/README.md
+ line-start: 1
+ line-end: 7
+ source-kind: runtime-workspace-policy
+ - path: docs/README.md
+ line-start: 23
+ line-end: 35
+ source-kind: documentation-policy
+
+ - id: F-PREREQUISITES
+ category: prerequisites
+ key: runtime-tools
+ value:
+ language: Python 3
+ python-packages: [PyYAML, jsonschema, Pillow]
+ feature-specific-tools:
+ technical-rendering: D2
+ SVG-preview: Chrome or Chromium
+ version-pins: not declared
+ assertion-type: derived
+ confidence: high
+ evidence:
+ - path: README.md
+ line-start: 151
+ line-end: 153
+ source-kind: project-documentation
+ - path: packages/schema-support/src/contract_support.py
+ line-start: 13
+ line-end: 14
+ source-kind: dependency-import
+ - path: packages/export-validator/src/validate_export.py
+ line-start: 1
+ line-end: 14
+ source-kind: dependency-import
+ - path: harnesses/technical-visualization/renderers/d2/renderer.py
+ line-start: 206
+ line-end: 213
+ source-kind: renderer-implementation
+ - path: harnesses/image-generation/scripts/render_svg_preview.py
+ line-start: 18
+ line-end: 31
+ source-kind: preview-implementation
+
+ - id: F-NO-PACKAGE-MANIFEST
+ category: limitation
+ key: dependency-installation-metadata
+ value: no pyproject.toml, requirements.txt, setup.py, setup.cfg, Pipfile, poetry.lock, or uv.lock is present; dependency versions and one canonical installation command cannot be evidenced
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: .
+ source-kind: repository-file-scan
+
+ - id: F-TEST-INVENTORY
+ category: tests
+ key: unittest-suite
+ value:
+ framework: unittest
+ observed-test-methods: 300
+ groups: [conformance, contracts, failure_injection, harnesses, integrations, runtime]
+ declared-latest-full-run: 300 tests passed in repository refactoring review
+ current-readme-run-check: repository-layout module passed 18 tests
+ current-readme-full-run: 300 tests passed
+ assertion-type: derived
+ confidence: high
+ evidence:
+ - path: tests
+ source-kind: test-directory-scan
+ - path: docs/refactoring-review.md
+ line-start: 76
+ line-end: 91
+ source-kind: declared-verification-report
+ - path: tests/conformance/test_repository_layout.py
+ source-kind: executed-test-module
+
+ - id: F-EXECUTED-QUICK-CHECKS
+ category: verification
+ key: readme-authoring-session-executions
+ value:
+ date: 2026-07-19
+ content-job-request-validation: {exit-code: 0}
+ content-manifest-validation: {exit-code: 0, output: VALID}
+ front-door-content-plan: {exit-code: 0, primary-capability: document-writing}
+ artifact-set-validation: {exit-code: 0, output: VALID}
+ repository-layout-tests: {tests: 18, result: PASS}
+ full-unittest-suite: {tests: 300, result: PASS, duration-seconds: 615.249}
+ assertion-type: executed
+ confidence: high
+ evidence:
+ - path: packages/content-job-contract/src/validate_content_job.py
+ source-kind: executed-entrypoint
+ - path: packages/content-contract/src/validate_content.py
+ source-kind: executed-entrypoint
+ - path: packages/workflow-runtime/src/content_runtime.py
+ source-kind: executed-entrypoint
+ - path: packages/artifact-contract/src/validate_artifact_set.py
+ source-kind: executed-entrypoint
+ - path: tests/conformance/test_repository_layout.py
+ source-kind: executed-test-module
+ - path: tests
+ source-kind: executed-test-suite
+
+ - id: F-E2E-INPUTS
+ category: prerequisites
+ key: end-to-end-external-inputs
+ value:
+ dependency-directions: [external Java/Gradle evidence repository, completed technical review file, completed narrative review file]
+ part1-redraw: [external source document, completed expert review file]
+ all-harness-quality: [external Java/Gradle evidence repository, stage-specific review files]
+ assertion-type: declared
+ confidence: high
+ evidence:
+ - path: tests/end-to-end/README.md
+ line-start: 68
+ line-end: 139
+ source-kind: end-to-end-documentation
+
+ - id: F-HYBRID-PENDING
+ category: limitation
+ key: d2-svg-layer-compositor-status
+ value:
+ automated-evidence: PASS
+ human-qualification: PENDING
+ production-status: qualification candidate, not qualified renderer
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: packages/workflow-runtime/policies/qualification.yaml
+ line-start: 29
+ line-end: 33
+ source-kind: qualification-policy
+ - path: benchmarks/hybrid-composition/results/d2-svg-layer-compositor-qualification.yaml
+ line-start: 1
+ line-end: 9
+ source-kind: automated-qualification-result
+ - path: benchmarks/hybrid-composition/results/d2-svg-layer-compositor-qualification.yaml
+ line-start: 65
+ line-end: 72
+ source-kind: human-qualification-result
+
+ - id: F-BENCHMARK-MATURITY
+ category: limitation
+ key: qualification-corpus-status
+ value:
+ document-writing: corpus-defined-results-pending
+ image-generation: corpus-defined-results-pending
+ technical-visualization: dependency-directions comparison has unexecuted conditions and pending human preference
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: benchmarks/document-writing/suite.yaml
+ line-start: 1
+ line-end: 32
+ source-kind: benchmark-suite
+ - path: benchmarks/image-quality/suite.yaml
+ line-start: 1
+ line-end: 41
+ source-kind: benchmark-suite
+ - path: benchmarks/technical-visualization/results/dependency-directions-qualification.yaml
+ line-start: 1
+ line-end: 25
+ source-kind: benchmark-result
+
+ - id: F-NO-GIT-METADATA
+ category: limitation
+ key: repository-snapshot
+ value: the supplied directory has an empty .git directory, so no commit SHA or clean/dirty Git state can be established; the README run uses a repository content hash instead
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: .
+ source-kind: filesystem-and-git-probe
+
+commands:
+ - id: CMD-001
+ command: python3 -m packages.content_job_contract.validate_content_job examples/clean-architecture/content-job-request.yaml --repo-root .
+ cwd: .
+ source: {path: packages/content-job-contract/README.md, line-start: 21, line-end: 25}
+ verification:
+ status: executed
+ method: executed from the repository root on 2026-07-19; exit code 0; recorded in this README run's execution-evidence.yaml
+ level: isolated-execution
+ limitations: [validates the checked-in ContentJobRequest only]
+
+ - id: CMD-002
+ command: python3 -m packages.workflow_runtime.content_runtime front-door --workflow-request examples/clean-architecture/workflow-request.content-job.yaml --repo-root .
+ cwd: .
+ source: {path: README.md, line-start: 93, line-end: 96}
+ verification:
+ status: executed
+ method: executed from the repository root on 2026-07-19; exit code 0 and a document-writing plan was emitted; recorded in execution-evidence.yaml
+ level: isolated-execution
+ limitations: [plans the checked-in request but does not execute production providers]
+
+ - id: CMD-003
+ command: python3 -m packages.content_contract.validate_content examples/clean-architecture/content-manifest.yaml --repo-root .
+ cwd: .
+ source: {path: README.md, line-start: 99, line-end: 102}
+ verification:
+ status: executed
+ method: executed from the repository root on 2026-07-19; exit code 0 and output VALID; recorded in execution-evidence.yaml
+ level: isolated-execution
+ limitations: [validates the checked-in Content Manifest only]
+
+ - id: CMD-004
+ command: python3 -m packages.artifact_contract.validate_artifact_set examples/clean-architecture/artifact/attempt-01/artifact-set.yaml --request examples/clean-architecture/visual-request.yaml
+ cwd: .
+ source: {path: README.md, line-start: 114, line-end: 116}
+ verification:
+ status: executed
+ method: executed from the repository root on 2026-07-19; exit code 0 and output VALID; recorded in execution-evidence.yaml
+ level: isolated-execution
+ limitations: [validates the checked-in contract fixture rather than a fresh renderer run]
+
+ - id: CMD-005
+ command: python3 -m unittest tests.conformance.test_repository_layout
+ cwd: .
+ source: {path: tests/conformance/test_repository_layout.py}
+ verification:
+ status: executed
+ method: executed from the repository root on 2026-07-19; 18 tests passed; recorded in execution-evidence.yaml
+ level: isolated-execution
+ limitations: [covers repository layout only, not the full suite]
+
+ - id: CMD-006
+ command: python3 -m unittest discover -s tests -p 'test_*.py'
+ cwd: .
+ source: {path: README.md, line-start: 145, line-end: 149}
+ verification:
+ status: executed
+ method: executed from the repository root on 2026-07-19; 300 tests passed in 615.249 seconds; recorded in execution-evidence.yaml
+ level: full-suite-execution
+ limitations: [external provider inputs required by renderer-backed end-to-end workflows were not supplied separately]
diff --git a/runs/image-haness/20260719-reader-first-korean/repository-snapshot.json b/runs/image-haness/20260719-reader-first-korean/repository-snapshot.json
new file mode 100644
index 0000000..ded7931
--- /dev/null
+++ b/runs/image-haness/20260719-reader-first-korean/repository-snapshot.json
@@ -0,0 +1,7 @@
+{
+ "git-sha": null,
+ "dirty": true,
+ "diff-hash": "sha256:0f6969583accd44093b1df782f287d582dfc24bbebbc56d2adefb1c2381f2854",
+ "scanned-at": null,
+ "file-count": 356
+}
\ No newline at end of file
diff --git a/runs/image-haness/20260719-reader-first-korean/review-findings.yaml b/runs/image-haness/20260719-reader-first-korean/review-findings.yaml
new file mode 100644
index 0000000..5948586
--- /dev/null
+++ b/runs/image-haness/20260719-reader-first-korean/review-findings.yaml
@@ -0,0 +1,56 @@
+schema-version: 1
+verdict: PASS
+score: 94
+scores:
+ project-specificity:
+ score: 5
+ evidence:
+ - 개요는 세 하네스와 workflow-runtime의 책임을 바로 밝히며, 기능별 책임·계약 사슬·검토 경계를 저장소 고유 식별자와 함께 설명한다.
+ - 검토를 마친 결과 예시 섹션은 F-README-SHOWCASE에 근거한 세 산출물과 출처 기록을 제시한다.
+ reader-journey:
+ score: 5
+ evidence:
+ - 결과 예시 → 먼저 실행해 보기 → 기능별 책임과 실행 과정 → 변경 위치 → 검증 → 현재 한계 순서로 독자의 핵심 과업을 따른다.
+ - 첫 문단과 대상 독자 목록만 읽어도 무엇을 만드는 저장소이며 누구를 위한 것인지 파악할 수 있다.
+ technical-explanation:
+ score: 5
+ evidence:
+ - 기능별 책임 섹션은 document-writing, technical-visualization, image-generation, workflow-runtime, integrations가 맡는 일과 경계를 구분한다.
+ - 요청이 결과가 되는 과정은 계약 사슬, 분기 조건, 합류 관계, 게시 승인 경계를 Mermaid 흐름도와 본문으로 설명한다.
+ - 저장소 구성과 변경 위치 표는 디렉터리 나열에 그치지 않고 책임, 변경 목적, 정본 의존 방향을 연결한다.
+ task-usability:
+ score: 4
+ evidence:
+ - 먼저 실행해 보기 섹션은 준비 사항, 복사 가능한 두 명령, 실행 위치, 종료 코드와 예상 결과, 검증 범위를 함께 제시한다.
+ - 검증 섹션은 계약 검사, 산출물 묶음 검사, 구성 검사, 전체 테스트를 분리해 명령별 검증 수준을 알 수 있게 한다.
+ - 패키지 설정과 버전 고정값이 없어 정본 설치 명령을 제공할 수 없는 저장소 제약 때문에 완전한 신규 환경 재현에는 추가 준비가 필요하다.
+ prose-clarity:
+ score: 4
+ evidence:
+ - 문장은 대체로 독자의 행동과 확인 결과를 먼저 제시하며, 홍보성 수식어·반복 종결·번역투·영문 일반 개념 나열이 독해를 방해하지 않는다.
+ - prose-report.json은 오류 0건, 경고 0건으로 PASS이며, 필요한 파일·모듈·계약·상태 식별자는 대부분 코드 형태로 구분된다.
+ - 일부 README 자체를 언급하는 문장이 남아 있으나 설치 근거와 산출물 보존 위치를 설명하는 짧은 맥락이며 독자 과업을 방해하지 않는다.
+ visual-judgment:
+ score: 5
+ evidence:
+ - 검토된 이미지, 기술 시각화, 통합 문서 미리보기는 실제 산출물을 먼저 판단하려는 독자 질문에 직접 답하며 출처·해시·검토 상태 기록으로 연결된다.
+ - 요청 분기와 결과 합류는 Mermaid 흐름도로 표현하고, 명령·경로·한계처럼 그림이 불필요한 부분은 텍스트와 표로 유지했다.
+hard-gates:
+ passed: true
+ failures: []
+reader-simulations:
+ 30-seconds:
+ outcome: PASS
+ evidence:
+ - 제목 아래 첫 문단과 대상 독자 목록에서 자연어 요청을 세 종류의 결과로 만드는 저장소라는 점, 작업 실행기의 역할, 대상 개발자를 확인할 수 있다.
+ 5-minutes:
+ outcome: PASS
+ evidence:
+ - 대표 결과 세 종류, 최소 실행 명령, 기능 책임과 계약 흐름, 저장소 구조, 검증 범위, 현재 한계를 순서대로 찾을 수 있다.
+ - 명령마다 성공 신호와 검증 범위가 붙어 있어 계획 생성과 실제 외부 도구 실행을 혼동하지 않는다.
+ contributor:
+ outcome: PASS
+ evidence:
+ - 저장소 구성과 변경 위치 표에서 변경 목적별 시작 디렉터리를 찾고, 검증 섹션에서 부분 검사와 전체 테스트 명령을 확인할 수 있다.
+ - 더 읽을 문서 섹션에서 ARCHITECTURE.md, 기능별 README, 실행 작업공간 정책, 예제와 평가 자료로 이동할 수 있다.
+findings: []
diff --git a/runs/image-haness/20260719-reader-first-korean/review.md b/runs/image-haness/20260719-reader-first-korean/review.md
new file mode 100644
index 0000000..6262d99
--- /dev/null
+++ b/runs/image-haness/20260719-reader-first-korean/review.md
@@ -0,0 +1,8 @@
+# README 품질 검토
+
+- 판정: PASS
+- 점수: 94/100
+- 중대 지적: 없음
+- 한국어 문체 검사: 오류 0건, 경고 0건
+
+대표 산출물을 먼저 보여 준 뒤 실행, 책임, 작업 흐름, 변경 위치, 검증, 한계로 이어지는 순서가 세 독자 모의 검토를 모두 통과했다. 패키지 설정 파일이 없어 신규 환경 설치를 하나의 명령으로 재현할 수 없는 점은 README에 한계로 명시돼 있다.
diff --git a/runs/image-haness/20260719-reader-first-korean/run-manifest.json b/runs/image-haness/20260719-reader-first-korean/run-manifest.json
new file mode 100644
index 0000000..b053c08
--- /dev/null
+++ b/runs/image-haness/20260719-reader-first-korean/run-manifest.json
@@ -0,0 +1,11 @@
+{
+ "schema-version": 1,
+ "run-id": "20260719-reader-first-korean",
+ "repo-id": "image-haness",
+ "mode": "bootstrap",
+ "target-repository": "/home/donghyeon/workspace/ai-tool/image-haness",
+ "harness-version": "0.1.0",
+ "started-at": null,
+ "tool-adapter": "codex",
+ "input-hashes": {}
+}
\ No newline at end of file
diff --git a/runs/image-haness/20260719-reader-first-korean/state.json b/runs/image-haness/20260719-reader-first-korean/state.json
new file mode 100644
index 0000000..0573834
--- /dev/null
+++ b/runs/image-haness/20260719-reader-first-korean/state.json
@@ -0,0 +1,320 @@
+{
+ "schema-version": 1,
+ "mode": "bootstrap",
+ "current": "APPLIED",
+ "history": [
+ {
+ "state": "INITIALIZED"
+ },
+ {
+ "state": "INPUT_CAPTURED",
+ "gates": [
+ {
+ "name": "request",
+ "ok": true,
+ "warnings": [],
+ "data": null
+ }
+ ]
+ },
+ {
+ "state": "REPOSITORY_SNAPSHOTTED",
+ "gates": [
+ {
+ "name": "snapshot",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "diff-hash": "sha256:0f6969583accd44093b1df782f287d582dfc24bbebbc56d2adefb1c2381f2854"
+ }
+ }
+ ]
+ },
+ {
+ "state": "FACTS_EXTRACTED",
+ "gates": [
+ {
+ "name": "facts",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "fact_ids": [
+ "F-IDENTITY",
+ "F-REPOSITORY-LAYERS",
+ "F-SIBLING-HARNESSES",
+ "F-CAPABILITY-DOCUMENT",
+ "F-CAPABILITY-TECHNICAL",
+ "F-CAPABILITY-IMAGE",
+ "F-ROUTING",
+ "F-CONTRACT-CHAIN",
+ "F-INTEGRATIONS",
+ "F-EXAMPLE-CHAIN",
+ "F-VERSIONED-VISUALS",
+ "F-RUN-WORKSPACE",
+ "F-PORTABLE-OUTPUT",
+ "F-LOCAL-CROSS-HARNESS-OUTPUT",
+ "F-LOCAL-DOCUMENT-VISUALIZATION",
+ "F-LOCAL-IMAGE-OUTPUT",
+ "F-README-SHOWCASE",
+ "F-RUNS-NONCANONICAL",
+ "F-PREREQUISITES",
+ "F-NO-PACKAGE-MANIFEST",
+ "F-TEST-INVENTORY",
+ "F-EXECUTED-QUICK-CHECKS",
+ "F-E2E-INPUTS",
+ "F-HYBRID-PENDING",
+ "F-BENCHMARK-MATURITY",
+ "F-NO-GIT-METADATA"
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "state": "PROJECT_PROFILED",
+ "gates": [
+ {
+ "name": "profile",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "profile": "generic"
+ }
+ }
+ ]
+ },
+ {
+ "state": "README_PLANNED",
+ "gates": [
+ {
+ "name": "brief",
+ "ok": true,
+ "warnings": [],
+ "data": null
+ },
+ {
+ "name": "outline",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "section_ids": [
+ "overview",
+ "showcase",
+ "quick-start",
+ "capabilities",
+ "execution-model",
+ "architecture",
+ "verification",
+ "limitations",
+ "documentation"
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "state": "README_DRAFTED",
+ "gates": [
+ {
+ "name": "conformance",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "sections": [
+ "overview",
+ "showcase",
+ "quick-start",
+ "capabilities",
+ "execution-model",
+ "architecture",
+ "verification",
+ "limitations",
+ "documentation"
+ ]
+ }
+ },
+ {
+ "name": "claim_map",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "claims": [
+ "C-IDENTITY",
+ "C-SHOWCASE-STATUS",
+ "C-SHOWCASE-PROVENANCE",
+ "C-PREREQUISITES",
+ "C-INSTALLATION-LIMIT",
+ "C-CMD-CONTENT-JOB",
+ "C-RESULT-CONTENT-JOB",
+ "C-CMD-FRONT-DOOR",
+ "C-RESULT-FRONT-DOOR",
+ "C-DOCUMENT-CAPABILITY",
+ "C-TECHNICAL-CAPABILITY",
+ "C-IMAGE-CAPABILITY",
+ "C-RUNTIME-CAPABILITY",
+ "C-INTEGRATIONS",
+ "C-CONTRACT-CHAIN",
+ "C-ROUTING",
+ "C-ACCEPTANCE-BOUNDARY",
+ "C-FLOW-RELATIONSHIPS",
+ "C-DEPENDENCY-DIRECTION",
+ "C-VERIFICATION-DATE",
+ "C-CMD-CONTENT-MANIFEST",
+ "C-RESULT-CONTENT-MANIFEST",
+ "C-CMD-ARTIFACT-SET",
+ "C-RESULT-ARTIFACT-SET",
+ "C-CMD-LAYOUT-TEST",
+ "C-RESULT-LAYOUT-TEST",
+ "C-CMD-FULL-SUITE",
+ "C-RESULT-FULL-SUITE",
+ "C-E2E-PREREQUISITES",
+ "C-LIMIT-PACKAGING",
+ "C-LIMIT-RUNS",
+ "C-LIMIT-E2E",
+ "C-LIMIT-BENCHMARKS",
+ "C-LIMIT-HYBRID"
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "state": "VISUALS_PLANNED",
+ "gates": [
+ {
+ "name": "visual_plan",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "visuals": [
+ "content-flow",
+ "showcase-dependency",
+ "showcase-editorial",
+ "showcase-publication"
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "state": "STRUCTURALLY_VALIDATED",
+ "gates": [
+ {
+ "name": "github_markdown",
+ "ok": true,
+ "warnings": [],
+ "data": null
+ },
+ {
+ "name": "reader_prose",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "schema-version": 1,
+ "policy-id": "korean-reader-prose-v1",
+ "language": "ko-KR",
+ "applicable": true,
+ "scope": "candidate",
+ "state": "PASS",
+ "summary": {
+ "errors": 0,
+ "warnings": 0,
+ "sentences": 78,
+ "prose-characters": 2023,
+ "hangul-characters": 1775
+ },
+ "findings": []
+ }
+ }
+ ]
+ },
+ {
+ "state": "TECHNICALLY_VERIFIED",
+ "gates": [
+ {
+ "name": "verify",
+ "ok": true,
+ "warnings": [
+ "manual verification required: python3 -m packages.content_job_contract.validate_content_job examples/clean-architecture/content-job-request.yaml --repo-root . (unsupported-static-verifier)",
+ "manual verification required: python3 -m packages.workflow_runtime.content_runtime front-door --workflow-request examples/clean-architecture/workflow-request.content-job.yaml --repo-root . (unsupported-static-verifier)",
+ "manual verification required: python3 -m packages.content_contract.validate_content examples/clean-architecture/content-manifest.yaml --repo-root . (unsupported-static-verifier)",
+ "manual verification required: python3 -m packages.artifact_contract.validate_artifact_set examples/clean-architecture/artifact/attempt-01/artifact-set.yaml --request examples/clean-architecture/visual-request.yaml (unsupported-static-verifier)",
+ "manual verification required: python3 -m unittest tests.conformance.test_repository_layout (unsupported-static-verifier)",
+ "manual verification required: python3 -m unittest discover -s tests -p 'test_*.py' (unsupported-static-verifier)"
+ ],
+ "data": {
+ "schema-version": 1,
+ "state": "PASS_WITH_MANUAL",
+ "verification-level": "static",
+ "execution-verified": false,
+ "checks": {
+ "commands": {
+ "total": 6,
+ "verified": 0,
+ "manual-required": 6,
+ "failed": 0
+ },
+ "paths": {
+ "total": 17,
+ "verified": 17,
+ "failed": 0
+ },
+ "anchors": {
+ "total": 0,
+ "verified": 0,
+ "failed": 0
+ },
+ "readme-contracts": {
+ "total": 0,
+ "verified": 0,
+ "failed": 0
+ }
+ },
+ "failures": [],
+ "limitations": [
+ "manual verification required: python3 -m packages.content_job_contract.validate_content_job examples/clean-architecture/content-job-request.yaml --repo-root . (unsupported-static-verifier)",
+ "manual verification required: python3 -m packages.workflow_runtime.content_runtime front-door --workflow-request examples/clean-architecture/workflow-request.content-job.yaml --repo-root . (unsupported-static-verifier)",
+ "manual verification required: python3 -m packages.content_contract.validate_content examples/clean-architecture/content-manifest.yaml --repo-root . (unsupported-static-verifier)",
+ "manual verification required: python3 -m packages.artifact_contract.validate_artifact_set examples/clean-architecture/artifact/attempt-01/artifact-set.yaml --request examples/clean-architecture/visual-request.yaml (unsupported-static-verifier)",
+ "manual verification required: python3 -m unittest tests.conformance.test_repository_layout (unsupported-static-verifier)",
+ "manual verification required: python3 -m unittest discover -s tests -p 'test_*.py' (unsupported-static-verifier)"
+ ]
+ }
+ },
+ {
+ "name": "secret_scan",
+ "ok": true,
+ "warnings": [],
+ "data": null
+ }
+ ]
+ },
+ {
+ "state": "QUALITY_REVIEWED",
+ "gates": [
+ {
+ "name": "review",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "verdict": "PASS",
+ "score": 94,
+ "findings": []
+ }
+ }
+ ]
+ },
+ {
+ "state": "READY_FOR_APPLY",
+ "gates": []
+ },
+ {
+ "state": "APPLIED",
+ "gates": []
+ }
+ ],
+ "rework": {
+ "iterations": 0,
+ "findings": {}
+ }
+}
\ No newline at end of file
diff --git a/runs/image-haness/20260719-reader-first-korean/verification.json b/runs/image-haness/20260719-reader-first-korean/verification.json
new file mode 100644
index 0000000..4d40f60
--- /dev/null
+++ b/runs/image-haness/20260719-reader-first-korean/verification.json
@@ -0,0 +1,38 @@
+{
+ "schema-version": 1,
+ "state": "PASS_WITH_MANUAL",
+ "verification-level": "static",
+ "execution-verified": false,
+ "checks": {
+ "commands": {
+ "total": 6,
+ "verified": 0,
+ "manual-required": 6,
+ "failed": 0
+ },
+ "paths": {
+ "total": 17,
+ "verified": 17,
+ "failed": 0
+ },
+ "anchors": {
+ "total": 0,
+ "verified": 0,
+ "failed": 0
+ },
+ "readme-contracts": {
+ "total": 0,
+ "verified": 0,
+ "failed": 0
+ }
+ },
+ "failures": [],
+ "limitations": [
+ "manual verification required: python3 -m packages.content_job_contract.validate_content_job examples/clean-architecture/content-job-request.yaml --repo-root . (unsupported-static-verifier)",
+ "manual verification required: python3 -m packages.workflow_runtime.content_runtime front-door --workflow-request examples/clean-architecture/workflow-request.content-job.yaml --repo-root . (unsupported-static-verifier)",
+ "manual verification required: python3 -m packages.content_contract.validate_content examples/clean-architecture/content-manifest.yaml --repo-root . (unsupported-static-verifier)",
+ "manual verification required: python3 -m packages.artifact_contract.validate_artifact_set examples/clean-architecture/artifact/attempt-01/artifact-set.yaml --request examples/clean-architecture/visual-request.yaml (unsupported-static-verifier)",
+ "manual verification required: python3 -m unittest tests.conformance.test_repository_layout (unsupported-static-verifier)",
+ "manual verification required: python3 -m unittest discover -s tests -p 'test_*.py' (unsupported-static-verifier)"
+ ]
+}
\ No newline at end of file
diff --git a/runs/image-haness/20260719-reader-first-korean/visual-plan.yaml b/runs/image-haness/20260719-reader-first-korean/visual-plan.yaml
new file mode 100644
index 0000000..333cce7
--- /dev/null
+++ b/runs/image-haness/20260719-reader-first-korean/visual-plan.yaml
@@ -0,0 +1,97 @@
+schema-version: 1
+visuals:
+ - id: showcase-editorial
+ section: showcase
+ type: artifact-showcase
+ purpose: 이미지 생성 기능이 만드는 에디토리얼 결과의 구도와 질감을 보여 준다.
+ placeholder-text: 검토를 통과한 이미지 생성 결과
+ must-show:
+ - 햇빛이 드는 작업대와 건축 모형을 조정하는 개발자
+ relationships: []
+ emphasize:
+ - 후보 비교와 독립 검토를 거쳐 선택한 결과
+ avoid:
+ - 실행 기록 경로의 파일 직접 연결
+ - 장식용 영웅 이미지로 오해할 설명
+ require-provenance: true
+ asset:
+ path: docs/assets/readme-showcase/editorial-workbench.png
+ provenance: docs/assets/readme-showcase/provenance.yaml
+ source-run: p6-all-harness-quality-executable-clean-architecture-20260717
+ sha256: sha256:aaf6a848e5a1094c6620fa2545df6e9e156b2af136d7bf7486840be93fcb10f1
+ caption: 후보 세 개와 독립 검토를 거쳐 고른 에디토리얼 이미지
+ placement:
+ after-section-id: showcase
+ accessibility:
+ alt-text: 햇빛이 드는 작업대에서 개발자가 건축 모형을 손으로 조정하는 장면
+
+ - id: showcase-dependency
+ section: showcase
+ type: artifact-showcase
+ purpose: 기술 시각화 기능이 호출과 소스·모듈 의존을 구분하는 방식을 보여 준다.
+ placeholder-text: 검토를 통과한 기술 시각화 결과
+ must-show:
+ - 유스케이스 호출, 소스 코드 의존, 모듈 의존을 분리한 방향
+ relationships: []
+ emphasize:
+ - 근거에 묶인 의미 모형에서 만든 SVG
+ avoid:
+ - 관계를 확인할 수 없을 정도로 작은 표시
+ - 실행 기록 경로의 파일 직접 연결
+ require-provenance: true
+ asset:
+ path: docs/assets/readme-showcase/dependency-directions.svg
+ provenance: docs/assets/readme-showcase/provenance.yaml
+ source-run: p6-all-harness-quality-executable-clean-architecture-20260717
+ sha256: sha256:5dacb86fb637bf0ac3ae6bf6cd9f97ea1fbc7112c02edc859ef1574cc55226cf
+ caption: 호출 관계와 소스·모듈 의존을 구분한 SVG
+ placement:
+ after-section-id: showcase
+ accessibility:
+ alt-text: 유스케이스 호출, 소스 코드 의존, 모듈 의존을 구분한 클린 아키텍처 방향 그림
+
+ - id: showcase-publication
+ section: showcase
+ type: artifact-showcase
+ purpose: 문서 작성과 두 시각 산출물이 최종 문서에서 어떻게 합쳐지는지 보여 준다.
+ placeholder-text: 검토를 통과한 통합 문서 미리보기
+ must-show:
+ - 한국어 본문, 에디토리얼 이미지, 의존 방향 그림이 배치된 전체 문서
+ relationships: []
+ emphasize:
+ - 세 하네스 결과가 한 게시 문서에 함께 들어간 모습
+ avoid:
+ - 본문 내용을 읽을 수 있다고 과장하는 설명
+ - 실행 기록 경로의 파일 직접 연결
+ require-provenance: true
+ asset:
+ path: docs/assets/readme-showcase/publication-preview.png
+ provenance: docs/assets/readme-showcase/provenance.yaml
+ source-run: p6-all-harness-quality-executable-clean-architecture-20260717
+ sha256: sha256:a12aaf738c3e4c4773666d96ba46f8e341065407e975c34a69a50d390102d979
+ caption: 문서 작성, 이미지 생성, 기술 시각화 결과를 한 문서에 배치한 미리보기
+ placement:
+ after-section-id: showcase
+ accessibility:
+ alt-text: 에디토리얼 이미지와 의존 방향 그림을 포함한 한국어 기술 문서 전체 미리보기
+
+ - id: content-flow
+ section: execution-model
+ type: request-flow
+ purpose: 작업 실행기가 요청을 세 하네스로 나누고 검토된 게시 자료로 합치는 과정을 보여 준다.
+ placeholder-text: 요청 분기와 게시 자료 합류 흐름
+ must-show:
+ - workflow-runtime에서 세 하네스로 나뉘는 요청
+ - 검토된 게시 자료에서 출력 형식으로 이어지는 결과
+ relationships:
+ - workflow-runtime이 하네스를 호출하고 하네스 결과를 게시 자료로 합친다.
+ emphasize:
+ - 하네스끼리 직접 호출하지 않는 경계
+ - 검토 뒤에만 게시 자료로 합류하는 순서
+ avoid:
+ - 실제로 존재하지 않는 하네스 간 직접 호출
+ - 렌더러나 외부 제공자 세부 정보
+ placement:
+ after-section-id: execution-model
+ accessibility:
+ alt-text: 자연어 요청이 작업 실행기에서 문서 작성, 기술 시각화, 이미지 생성으로 나뉜 뒤 검토된 게시 자료로 합쳐지는 흐름
diff --git a/runs/readme-harness/20260720-public-readme-r2/README.candidate.md b/runs/readme-harness/20260720-public-readme-r2/README.candidate.md
new file mode 100644
index 0000000..ff79e91
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme-r2/README.candidate.md
@@ -0,0 +1,211 @@
+# README Harness
+
+
+
+저장소에서 확인한 사실과 사용자가 정한 요구를 바탕으로 README 초안을 만드는 도구입니다.
+
+
+명령·링크·경로를 검사한 뒤, 사람이 검토하고 적용할 수 있는 패치를 생성합니다.
+
+
+현재 지원하는 작성·검증 흐름은 Codex용입니다.
+
+Claude와 Antigravity에서 같은 동작을 하는지는 아직 미검증 상태입니다.
+
+
+
+
+## 무엇을 만드는가
+
+README를 새로 만들거나 기존 문서를 안전하게 갱신하려는 개발자를 위한 도구입니다.
+
+- 새 README 작성
+- 기존 README 점검
+- 사람 작성 내용을 보존한 갱신
+- 특정 섹션만 다시 작성
+- 검토한 패치만 직접 적용
+
+
+
+
+
+## 실제 결과
+
+아래 내용은 검토를 통과한 이전 실행의 패치 일부입니다.
+
+
+```diff
+-A GitHub-README-specialized harness built around a shared core with entrypoints
+-for **Codex**, **Antigravity**, and **Claude**. It does not "prettify" READMEs —
+-it analyzes the facts that exist in a repository, judges project type and
+-audience, then iteratively produces and maintains a README with a readable
++이 하네스는 저장소의 실제 코드와 사용 목적을 바탕으로 문서 후보를 만들고,
++명령·경로·근거를 검사한 뒤 검토 가능한 패치로 제공합니다.
+```
+
+
+
+[전체 패치와 출처](examples/readme-showcase/README.patch)에서 더 긴 변경 내용을 확인할 수 있습니다.
+
+
+
+
+
+## 빠른 시작
+
+현재 실행 경로는 Codex 작업 공간의 `requirement-driven-readme` 스킬입니다.
+
+
+
+Codex에 다음과 같이 요청합니다.
+
+> 이 저장소의 README를 `bootstrap` 모드로 작성해 주세요.
+> 주 독자는 백엔드 개발자이며, 설치와 첫 실행 방법을 우선해 주세요.
+
+
+작업 뒤 확인할 파일은 `README.generated.md`와 `README.patch`입니다.
+
+
+
+생성된 README의 명령과 링크를 읽고, 패치가 의도한 범위만 바꾸는지 검토합니다.
+
+대상 `README.md`는 적용 명령을 실행하기 전까지 바뀌지 않습니다.
+
+
+
+검토가 끝난 패치만 직접 적용합니다.
+
+```bash
+python3 .agents/skills/requirement-driven-readme/scripts/apply_patch.py --run-dir runs// --repo /path/to/repository
+```
+
+적용 직전에 생성 파일과 대상 README, 저장소 기준 정보가 바뀌지 않았는지 다시 확인합니다.
+
+
+
+
+
+
+## 어떤 작업을 지원하는가
+
+새 README 작성과 전면 재작성의 기본 선택은 `bootstrap`입니다.
+
+
+현재 README의 문제만 찾는 작업은 `audit`입니다.
+
+
+사람이 작성한 영역을 보존하는 갱신은 `refresh`입니다.
+
+
+한 섹션과 영향을 받는 검사 결과의 갱신은 `section-update`입니다.
+
+
+
+
+
+
+## 안전하게 다루는 방법
+
+코드에서 확인한 사실과 사용자가 정한 문서 요구는 따로 둡니다.
+
+
+명령, 경로, 버전처럼 오류 영향이 큰 정보는 근거 파일과 연결합니다.
+
+
+갱신 작업은 보호 영역과 마커 밖의 사람이 작성한 문장을 보존합니다.
+
+
+사람이 고친 영역과 새 초안이 충돌하면 자동 병합과 적용이 중단됩니다.
+
+
+비밀 값이나 저장소 밖 경로가 발견되면 패치를 준비하지 않습니다.
+
+
+검토 뒤 저장소나 생성 파일이 바뀌어도 적용을 중단합니다.
+
+
+
+
+
+
+## 동작 방식
+
+사용자 요청 → 저장소 사실 확인 → README 작성 → 명령·링크·문장 검사 → 독립 검토 → 패치 확인 → 직접 적용
+
+
+검사에서 문제가 나오면 해당 내용을 맡은 단계부터 다시 작성합니다.
+
+
+
+
+
+
+## 입력과 생성 파일
+
+`readme-request.yaml`에는 독자, 목적, 언어, 보존 범위와 그림 정책을 적습니다.
+
+
+사용자는 다음 두 결과를 주로 확인합니다.
+
+- `README.generated.md`: 생성된 README
+- `README.patch`: 현재 README와의 차이
+
+각 작업의 파일은 `runs//` 아래에 따로 저장됩니다.
+
+
+
+
+
+
+## 개발
+
+개발에는 Python 3.12 이상이 필요하며, 개발 의존성에는 `pytest`가 포함됩니다.
+
+
+저장소 루트에서 개발 모드로 설치합니다.
+
+```bash
+python3 -m pip install -e ".[dev]"
+```
+
+전체 테스트는 다음 명령으로 실행합니다.
+
+```bash
+python3 -m pytest -q
+```
+
+
+
+
+
+## 상세 문서
+
+- [구성요소와 책임](docs/architecture.md)
+- [시각 자료와 실제 결과 증명](docs/visuals.md)
+- [모드별 처리 단계와 차단 조건](docs/state-machine.md)
+- [모델 사용량 기록](docs/usage-metrics.md)
+- [블라인드 README 품질 비교](docs/quality-benchmark.md)
+- [전체 설계 명세](docs/superpowers/specs/2026-07-16-readme-harness-design.md)
+
+주요 구현은 `src/readme_harness`, 규칙과 워크플로는 `.agents`, 테스트는 `tests`에 있습니다.
+
+
+
+
+
+
+## 현재 한계
+
+- README 문장은 모델이 작성하고 검사 스크립트는 준비된 파일을 확인합니다.
+
+
+- 실행 기록이 없는 명령은 정적으로만 확인합니다.
+
+
+- `Claude`와 `Antigravity`에서 `Codex`와 같은 동작을 하는지는 아직 검증하지 않았습니다.
+
+
+- 블라인드 품질 비교는 아직 실행하지 않았으며 더 좋은 결과를 낸다고 주장하지 않습니다.
+
+
+
diff --git a/runs/readme-harness/20260720-public-readme-r2/README.generated.md b/runs/readme-harness/20260720-public-readme-r2/README.generated.md
new file mode 100644
index 0000000..ff79e91
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme-r2/README.generated.md
@@ -0,0 +1,211 @@
+# README Harness
+
+
+
+저장소에서 확인한 사실과 사용자가 정한 요구를 바탕으로 README 초안을 만드는 도구입니다.
+
+
+명령·링크·경로를 검사한 뒤, 사람이 검토하고 적용할 수 있는 패치를 생성합니다.
+
+
+현재 지원하는 작성·검증 흐름은 Codex용입니다.
+
+Claude와 Antigravity에서 같은 동작을 하는지는 아직 미검증 상태입니다.
+
+
+
+
+## 무엇을 만드는가
+
+README를 새로 만들거나 기존 문서를 안전하게 갱신하려는 개발자를 위한 도구입니다.
+
+- 새 README 작성
+- 기존 README 점검
+- 사람 작성 내용을 보존한 갱신
+- 특정 섹션만 다시 작성
+- 검토한 패치만 직접 적용
+
+
+
+
+
+## 실제 결과
+
+아래 내용은 검토를 통과한 이전 실행의 패치 일부입니다.
+
+
+```diff
+-A GitHub-README-specialized harness built around a shared core with entrypoints
+-for **Codex**, **Antigravity**, and **Claude**. It does not "prettify" READMEs —
+-it analyzes the facts that exist in a repository, judges project type and
+-audience, then iteratively produces and maintains a README with a readable
++이 하네스는 저장소의 실제 코드와 사용 목적을 바탕으로 문서 후보를 만들고,
++명령·경로·근거를 검사한 뒤 검토 가능한 패치로 제공합니다.
+```
+
+
+
+[전체 패치와 출처](examples/readme-showcase/README.patch)에서 더 긴 변경 내용을 확인할 수 있습니다.
+
+
+
+
+
+## 빠른 시작
+
+현재 실행 경로는 Codex 작업 공간의 `requirement-driven-readme` 스킬입니다.
+
+
+
+Codex에 다음과 같이 요청합니다.
+
+> 이 저장소의 README를 `bootstrap` 모드로 작성해 주세요.
+> 주 독자는 백엔드 개발자이며, 설치와 첫 실행 방법을 우선해 주세요.
+
+
+작업 뒤 확인할 파일은 `README.generated.md`와 `README.patch`입니다.
+
+
+
+생성된 README의 명령과 링크를 읽고, 패치가 의도한 범위만 바꾸는지 검토합니다.
+
+대상 `README.md`는 적용 명령을 실행하기 전까지 바뀌지 않습니다.
+
+
+
+검토가 끝난 패치만 직접 적용합니다.
+
+```bash
+python3 .agents/skills/requirement-driven-readme/scripts/apply_patch.py --run-dir runs// --repo /path/to/repository
+```
+
+적용 직전에 생성 파일과 대상 README, 저장소 기준 정보가 바뀌지 않았는지 다시 확인합니다.
+
+
+
+
+
+
+## 어떤 작업을 지원하는가
+
+새 README 작성과 전면 재작성의 기본 선택은 `bootstrap`입니다.
+
+
+현재 README의 문제만 찾는 작업은 `audit`입니다.
+
+
+사람이 작성한 영역을 보존하는 갱신은 `refresh`입니다.
+
+
+한 섹션과 영향을 받는 검사 결과의 갱신은 `section-update`입니다.
+
+
+
+
+
+
+## 안전하게 다루는 방법
+
+코드에서 확인한 사실과 사용자가 정한 문서 요구는 따로 둡니다.
+
+
+명령, 경로, 버전처럼 오류 영향이 큰 정보는 근거 파일과 연결합니다.
+
+
+갱신 작업은 보호 영역과 마커 밖의 사람이 작성한 문장을 보존합니다.
+
+
+사람이 고친 영역과 새 초안이 충돌하면 자동 병합과 적용이 중단됩니다.
+
+
+비밀 값이나 저장소 밖 경로가 발견되면 패치를 준비하지 않습니다.
+
+
+검토 뒤 저장소나 생성 파일이 바뀌어도 적용을 중단합니다.
+
+
+
+
+
+
+## 동작 방식
+
+사용자 요청 → 저장소 사실 확인 → README 작성 → 명령·링크·문장 검사 → 독립 검토 → 패치 확인 → 직접 적용
+
+
+검사에서 문제가 나오면 해당 내용을 맡은 단계부터 다시 작성합니다.
+
+
+
+
+
+
+## 입력과 생성 파일
+
+`readme-request.yaml`에는 독자, 목적, 언어, 보존 범위와 그림 정책을 적습니다.
+
+
+사용자는 다음 두 결과를 주로 확인합니다.
+
+- `README.generated.md`: 생성된 README
+- `README.patch`: 현재 README와의 차이
+
+각 작업의 파일은 `runs//` 아래에 따로 저장됩니다.
+
+
+
+
+
+
+## 개발
+
+개발에는 Python 3.12 이상이 필요하며, 개발 의존성에는 `pytest`가 포함됩니다.
+
+
+저장소 루트에서 개발 모드로 설치합니다.
+
+```bash
+python3 -m pip install -e ".[dev]"
+```
+
+전체 테스트는 다음 명령으로 실행합니다.
+
+```bash
+python3 -m pytest -q
+```
+
+
+
+
+
+## 상세 문서
+
+- [구성요소와 책임](docs/architecture.md)
+- [시각 자료와 실제 결과 증명](docs/visuals.md)
+- [모드별 처리 단계와 차단 조건](docs/state-machine.md)
+- [모델 사용량 기록](docs/usage-metrics.md)
+- [블라인드 README 품질 비교](docs/quality-benchmark.md)
+- [전체 설계 명세](docs/superpowers/specs/2026-07-16-readme-harness-design.md)
+
+주요 구현은 `src/readme_harness`, 규칙과 워크플로는 `.agents`, 테스트는 `tests`에 있습니다.
+
+
+
+
+
+
+## 현재 한계
+
+- README 문장은 모델이 작성하고 검사 스크립트는 준비된 파일을 확인합니다.
+
+
+- 실행 기록이 없는 명령은 정적으로만 확인합니다.
+
+
+- `Claude`와 `Antigravity`에서 `Codex`와 같은 동작을 하는지는 아직 검증하지 않았습니다.
+
+
+- 블라인드 품질 비교는 아직 실행하지 않았으며 더 좋은 결과를 낸다고 주장하지 않습니다.
+
+
+
diff --git a/runs/readme-harness/20260720-public-readme-r2/README.patch b/runs/readme-harness/20260720-public-readme-r2/README.patch
new file mode 100644
index 0000000..77b65bc
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme-r2/README.patch
@@ -0,0 +1,413 @@
+--- README.md (current)
++++ README.md (candidate)
+@@ -1,224 +1,211 @@
+ # README Harness
+
+-이 하네스는 저장소의 실제 코드와 사용 목적을 바탕으로 문서 후보를 만들고,
+-명령·경로·근거를 검사한 뒤 검토 가능한 패치로 제공합니다.
+-
+-- 새 README 작성
+-- 기존 문서 점검
+-- 사람 작성 영역을 보존한 갱신
+-- 특정 섹션과 관련 검증 산출물의 재생성
+-- 검토 후 별도로 실행하는 적용
+-
++
++
++저장소에서 확인한 사실과 사용자가 정한 요구를 바탕으로 README 초안을 만드는 도구입니다.
++
++
++명령·링크·경로를 검사한 뒤, 사람이 검토하고 적용할 수 있는 패치를 생성합니다.
++
++
++현재 지원하는 작성·검증 흐름은 Codex용입니다.
++
++Claude와 Antigravity에서 같은 동작을 하는지는 아직 미검증 상태입니다.
++
++
++
+
+ ## 무엇을 만드는가
+
+ README를 새로 만들거나 기존 문서를 안전하게 갱신하려는 개발자를 위한 도구입니다.
+
+-`bootstrap`, `audit`, `refresh`, `section-update` 네 모드를 구현했습니다.
+-
+-저장소 근거와 사용자 요구를 분리해 읽고, 고위험 사실을 근거에 연결합니다. 그림을
+-넣기로 했다면 실제 소스나 자산까지 확인하고, 품질 심사는 원문의 줄과 해시에 묶인
+-근거를 사용합니다. 패치 준비가 끝나도 대상 `README.md`는 자동으로 바뀌지 않습니다.
+-
+-
+-결정론적 Codex 경로는 구현됐습니다. 후보 문장 작성은 모델 파이프라인이 담당하며,
+-다른 도구와의 런타임 동등성은 Phase 4 검증 전까지 보장하지 않습니다.
+-
+-
+-
+-## 설치
+-
+-`Python` 3.12 이상이 필요합니다.
+-런타임 의존성은 `jsonschema`와 `PyYAML`입니다.
+-개발 의존성은 `pytest`입니다.
+-
+-저장소 루트에서 개발 의존성을 포함한 편집 가능 설치를 실행합니다.
++- 새 README 작성
++- 기존 README 점검
++- 사람 작성 내용을 보존한 갱신
++- 특정 섹션만 다시 작성
++- 검토한 패치만 직접 적용
++
++
++
++
++
++## 실제 결과
++
++아래 내용은 검토를 통과한 이전 실행의 패치 일부입니다.
++
++
++```diff
++-A GitHub-README-specialized harness built around a shared core with entrypoints
++-for **Codex**, **Antigravity**, and **Claude**. It does not "prettify" READMEs —
++-it analyzes the facts that exist in a repository, judges project type and
++-audience, then iteratively produces and maintains a README with a readable
+++이 하네스는 저장소의 실제 코드와 사용 목적을 바탕으로 문서 후보를 만들고,
+++명령·경로·근거를 검사한 뒤 검토 가능한 패치로 제공합니다.
++```
++
++
++
++[전체 패치와 출처](examples/readme-showcase/README.patch)에서 더 긴 변경 내용을 확인할 수 있습니다.
++
++
++
++
++
++## 빠른 시작
++
++현재 실행 경로는 Codex 작업 공간의 `requirement-driven-readme` 스킬입니다.
++
++
++
++Codex에 다음과 같이 요청합니다.
++
++> 이 저장소의 README를 `bootstrap` 모드로 작성해 주세요.
++> 주 독자는 백엔드 개발자이며, 설치와 첫 실행 방법을 우선해 주세요.
++
++
++작업 뒤 확인할 파일은 `README.generated.md`와 `README.patch`입니다.
++
++
++
++생성된 README의 명령과 링크를 읽고, 패치가 의도한 범위만 바꾸는지 검토합니다.
++
++대상 `README.md`는 적용 명령을 실행하기 전까지 바뀌지 않습니다.
++
++
++
++검토가 끝난 패치만 직접 적용합니다.
++
++```bash
++python3 .agents/skills/requirement-driven-readme/scripts/apply_patch.py --run-dir runs// --repo /path/to/repository
++```
++
++적용 직전에 생성 파일과 대상 README, 저장소 기준 정보가 바뀌지 않았는지 다시 확인합니다.
++
++
++
++
++
++
++## 어떤 작업을 지원하는가
++
++새 README 작성과 전면 재작성의 기본 선택은 `bootstrap`입니다.
++
++
++현재 README의 문제만 찾는 작업은 `audit`입니다.
++
++
++사람이 작성한 영역을 보존하는 갱신은 `refresh`입니다.
++
++
++한 섹션과 영향을 받는 검사 결과의 갱신은 `section-update`입니다.
++
++
++
++
++
++
++## 안전하게 다루는 방법
++
++코드에서 확인한 사실과 사용자가 정한 문서 요구는 따로 둡니다.
++
++
++명령, 경로, 버전처럼 오류 영향이 큰 정보는 근거 파일과 연결합니다.
++
++
++갱신 작업은 보호 영역과 마커 밖의 사람이 작성한 문장을 보존합니다.
++
++
++사람이 고친 영역과 새 초안이 충돌하면 자동 병합과 적용이 중단됩니다.
++
++
++비밀 값이나 저장소 밖 경로가 발견되면 패치를 준비하지 않습니다.
++
++
++검토 뒤 저장소나 생성 파일이 바뀌어도 적용을 중단합니다.
++
++
++
++
++
++
++## 동작 방식
++
++사용자 요청 → 저장소 사실 확인 → README 작성 → 명령·링크·문장 검사 → 독립 검토 → 패치 확인 → 직접 적용
++
++
++검사에서 문제가 나오면 해당 내용을 맡은 단계부터 다시 작성합니다.
++
++
++
++
++
++
++## 입력과 생성 파일
++
++`readme-request.yaml`에는 독자, 목적, 언어, 보존 범위와 그림 정책을 적습니다.
++
++
++사용자는 다음 두 결과를 주로 확인합니다.
++
++- `README.generated.md`: 생성된 README
++- `README.patch`: 현재 README와의 차이
++
++각 작업의 파일은 `runs//` 아래에 따로 저장됩니다.
++
++
++
++
++
++
++## 개발
++
++개발에는 Python 3.12 이상이 필요하며, 개발 의존성에는 `pytest`가 포함됩니다.
++
++
++저장소 루트에서 개발 모드로 설치합니다.
+
+ ```bash
+ python3 -m pip install -e ".[dev]"
+ ```
+
+-이 설치 명령은 프로젝트 선언에서 확인했지만, 현재 작업에서는 새 가상환경 설치까지
+-실행해 증명하지 않았습니다.
+-
+-
+-## 빠른 시작
+-
+-먼저 전체 테스트를 실행합니다.
++전체 테스트는 다음 명령으로 실행합니다.
+
+ ```bash
+ python3 -m pytest -q
+ ```
+
+-종료 코드 0과 실패 항목 없는 통과 요약이 성공 기준입니다. 이 후보는 아직 현재
+-README를 바꾸지 않았으므로 최종 전체 결과는 명시적 적용 뒤 다시 확인합니다.
+-
+-자체 README 테스트는 이 명령을 최소 실행 경로로 요구합니다. 다른 운영체제와 새
+-가상환경의 동일한 결과까지 보장하는 계약은 아닙니다.
+-
+-이 프로젝트는 명령 하나로 문서를 완성하는 독립 실행 도구가 아닙니다. Codex 작업 공간에서
+-`requirement-driven-readme` 스킬로 대상 저장소의 `bootstrap` 실행을 요청하면 작성
+-역할이 사용자 요구, 저장소 근거, 개요, 후보, 주장 지도, 그림 계획과 품질 심사
+-산출물을 준비합니다.
+-
+-대상 저장소용 실행 디렉터리를 만듭니다.
+-
+-```bash
+-python3 .agents/skills/requirement-driven-readme/scripts/init_run.py --repo-id demo --run-id first --mode bootstrap --target-repository /path/to/repository --tool-adapter codex
+-```
+-
+-이 명령은 `runs/demo/first`에 상태와 실행 매니페스트를 초기화합니다.
+-
+-
+-실행 디렉터리에 `readme-request.yaml`, `repository-facts.yaml`, `readme-brief.yaml`,
+-`readme-outline.yaml`, `README.candidate.md`, `claim-map.yaml`, `visual-plan.yaml`,
+-`review-findings.yaml`이 준비되면 모든 결정론적 게이트를 재생합니다.
+-
+-```bash
+-python3 .agents/skills/requirement-driven-readme/scripts/run_bootstrap.py --run-dir runs/demo/first --repo /path/to/repository
+-```
+-
+-드라이버는 후보를 새로 쓰지 않고 준비된 산출물을 `QUALITY_REVIEWED`까지
+-검증합니다.
+-
+-
+-## 사용 모드
+-
+-| 작업 | 모드 | 결과 |
+-|---|---|---|
+-| README가 없거나 전면 재작성 | `bootstrap` | 검증된 후보와 적용 준비용 패치 |
+-| 기존 문서의 결함만 점검 | `audit` | 감사 결과와 검증 보고서, 후보·패치 없음 |
+-| 사람 작성 영역을 보존한 갱신 | `refresh` | 3방향 병합과 병합본 전체 재검증 |
+-| 한 섹션과 파급 산출물 갱신 | `section-update` | 관련 산출물 무효화 후 갱신 검증 재실행 |
+-
+-네 모드는 요청 스키마에 선언되어 있고 각 흐름의 상태·게이트 계약이 구현되어
+-있습니다.
+-
+-
+-## 요청 API, 설정과 산출물
+-
+-`readme-request.yaml`은 독자, 언어, 길이, 보존 범위, 공개 용어, 그림 정책을
+-정합니다. 기술 사실은 `repository-facts.yaml`에 저장하고, 각 실행은
+-`runs//` 아래에서 격리합니다.
+-
+-어댑터가 제공하는 단계별 모델 사용량은 실행 매니페스트에 누적합니다. 제공되지
+-않은 값은 0으로 추정하지 않습니다.
+-
+-대표 산출물은 다음 순서로 이어집니다.
+-
+-```text
+-readme-brief.yaml + readme-outline.yaml
+-README.candidate.md + claim-map.yaml + visual-plan.yaml
+-prose-report.json + verification.json + review-findings.yaml
+-quality-manifest.yaml
+-README.generated.md + README.patch + apply-manifest.yaml
+-```
+-
+-품질 검토를 통과한 뒤 다음 명령으로 패치를 준비합니다.
+-
+-```bash
+-python3 .agents/skills/requirement-driven-readme/scripts/generate_patch.py --run-dir runs/demo/first --repo /path/to/repository
+-```
+-
+-이 단계는 `README.generated.md`, `README.patch`, `apply-manifest.yaml`을 만들고
+-상태를 `READY_FOR_APPLY`로 전진시킵니다.
+-
+-검토가 끝난 패치만 별도 명령으로 적용합니다.
+-
+-```bash
+-python3 .agents/skills/requirement-driven-readme/scripts/apply_patch.py --run-dir runs/demo/first --repo /path/to/repository
+-```
+-
+-적용 직전에 후보·저장소·대상 README 해시와 경로 경계를 다시 검사합니다.
+-
+-
+-
+-## 동작 방식
+-
+-사용자 요구는 독자 흐름과 공개 용어, 그림 결정을 만듭니다. 대상 저장소에서는
+-근거와 프로젝트 유형을 수집합니다. 두 입력이 합쳐진 후보와 시각 자료는 결정론적
+-게이트와 독립 품질 심사를 통과해야 패치가 됩니다.
+-
+-```mermaid
+-flowchart LR
+- T[Codex / Claude / Antigravity] --> O[실행 조정]
+- U[사용자 요구] --> P[독자 흐름·용어·그림 결정]
+- R[대상 저장소] --> E[근거 수집·프로젝트 분류]
+- O --> E
+- O --> P
+- E --> P
+- P --> W[README 작성]
+- P --> V[그림 소스·자산 생성]
+- W --> G[근거·명령·경로·문체 검사]
+- V --> G
+- G --> Q[독립 품질 심사]
+- Q -->|수정 필요| P
+- Q -->|통과| A[패치 준비·명시적 적용]
+- H[(해시 기반 실행 산출물)] --- E
+- H --- P
+- H --- G
+- H --- A
+-```
+-
+-
+-
+-구성요소 책임과 컨텍스트 경계는 [아키텍처 문서](docs/architecture.md)에,
+-모드별 전이는 [상태기계 문서](docs/state-machine.md)에 정리했습니다.
+-
+-
+-## 안전장치
+-
+-- 명령·버전·전제조건·모듈·경로·보장·한계 주장은 저장소 근거에 연결합니다.
+-- 인라인 코드의 영문 표현이 실제 식별자인지 확인하고 내부 전용 용어의 공개 노출을
+- 차단합니다.
+-- 그림을 포함하기로 한 개요 결정, 계획 항목, README 마커, 생성 소스나 자산이
+- 일치해야 시각 자료 게이트를 통과합니다.
+-- 품질 점수와 독자 과업 근거의 줄 범위와 해시를 실제 후보에 대조하고,
+- `review.md`는 검증된 YAML에서 렌더링합니다.
+-- 감사 모드는 결과 스키마를 확인하고 산출물을 원자적으로 기록한 다음 완료 상태로
+- 전진합니다.
+-- 갱신 모드는 보호 영역과 마커 밖 문장을 보존하며, 사람이 고친 관리 영역과 새
+- 후보가 충돌하면 자동 적용을 막습니다.
+-- 비밀 값, 저장소 밖 경로, 오래된 스냅숏, 검토 뒤 바뀐 산출물은 패치 준비나
+- 적용을 차단합니다.
+-
+-시각 자료의 소스·자산·대체 텍스트·신선도 규칙은
+-[시각 자료 정책](docs/visuals.md)에서 확인할 수 있습니다.
+-
+-
+-## 테스트
+-
+-전체 회귀 테스트는 다음 명령으로 실행합니다.
+-
+-```bash
+-python3 -m pytest -q
+-```
+-
+-GitHub Actions는 의존성을 설치한 뒤 전체 테스트를 실행합니다. 실행 환경은
+-Python 3.12입니다. 자체 README 테스트는 라이브러리 프로파일, 30초 독자 흐름, 최소 실행
+-경로, Mermaid 그림 결정을 확인합니다.
+-
++
++
++
+
+ ## 상세 문서
+
+-- [구성요소와 컨텍스트 경계](docs/architecture.md)
+-- [그림 결정과 소스·자산 계약](docs/visuals.md)
+-- [모드별 상태와 차단 조건](docs/state-machine.md)
+-- [모델 사용량 계측](docs/usage-metrics.md)
+-- [블라인드 README 품질 벤치마크](docs/quality-benchmark.md)
++- [구성요소와 책임](docs/architecture.md)
++- [시각 자료와 실제 결과 증명](docs/visuals.md)
++- [모드별 처리 단계와 차단 조건](docs/state-machine.md)
++- [모델 사용량 기록](docs/usage-metrics.md)
++- [블라인드 README 품질 비교](docs/quality-benchmark.md)
+ - [전체 설계 명세](docs/superpowers/specs/2026-07-16-readme-harness-design.md)
+
+-주요 구현은 `src/readme_harness`, 스키마·규칙·워크플로는 `.agents`, 테스트는
+-`tests`에 있습니다.
+-
++주요 구현은 `src/readme_harness`, 규칙과 워크플로는 `.agents`, 테스트는 `tests`에 있습니다.
++
++
++
++
++
+
+ ## 현재 한계
+
+-- 후보 작성은 LLM 파이프라인의 판단에 의존합니다. 결정론적 드라이버는 준비된
+- 산출물을 검증하고 상태를 전진시킵니다.
+-- 네 모드의 결정론적 경로는 구현됐지만 도구 간 런타임 동등성은 Phase 4 검증
+- 목표입니다.
+-- 명령 검증 보고서의 기본 수준은 정적 검사입니다. 실행을 별도로 기록하지 않은
+- 명령은 실제 실행 성공을 뜻하지 않습니다.
+-- 여덟 저장소 유형의 블라인드 비교 계약은 마련했지만 결과 상태는 아직 `not-run`입니다.
+- `PASS` 결과 전에는 품질 우월성을 주장하지 않습니다.
++- README 문장은 모델이 작성하고 검사 스크립트는 준비된 파일을 확인합니다.
++
++
++- 실행 기록이 없는 명령은 정적으로만 확인합니다.
++
++
++- `Claude`와 `Antigravity`에서 `Codex`와 같은 동작을 하는지는 아직 검증하지 않았습니다.
++
++
++- 블라인드 품질 비교는 아직 실행하지 않았으며 더 좋은 결과를 낸다고 주장하지 않습니다.
++
++
++
diff --git a/runs/readme-harness/20260720-public-readme-r2/apply-manifest.yaml b/runs/readme-harness/20260720-public-readme-r2/apply-manifest.yaml
new file mode 100644
index 0000000..b3f4613
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme-r2/apply-manifest.yaml
@@ -0,0 +1,7 @@
+schema-version: 1
+mode: bootstrap
+target-rel: README.md
+generated-hash: sha256:b54317f98e0bea64cc31f489caca9a541b24bbdfec3aab6af3be41d0dd4dab22
+target-before-hash: sha256:dd241b6b8b7a0972086226c73b217128d98224cf30ab87505a6d5e8e0d2dcedf
+repository-snapshot-hash: sha256:2ff902bd9a7de01648f972d099614584bc26fa84c1492cec61dc6da82e4f6275
+review-score: 90
diff --git a/runs/readme-harness/20260720-public-readme-r2/artifacts/attempt-1/README.candidate.md b/runs/readme-harness/20260720-public-readme-r2/artifacts/attempt-1/README.candidate.md
new file mode 100644
index 0000000..dad1cd4
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme-r2/artifacts/attempt-1/README.candidate.md
@@ -0,0 +1,211 @@
+# README Harness
+
+
+
+저장소에서 확인한 사실과 사용자가 정한 요구를 바탕으로 README 초안을 만드는 도구입니다.
+
+
+명령·링크·경로를 검사한 뒤, 사람이 검토하고 적용할 수 있는 패치를 생성합니다.
+
+
+현재 지원하는 작성·검증 흐름은 Codex용입니다.
+
+Claude와 Antigravity에서 같은 동작을 하는지는 아직 미검증 상태입니다.
+
+
+
+
+## 무엇을 만드는가
+
+README를 새로 만들거나 기존 문서를 안전하게 갱신하려는 개발자를 위한 도구입니다.
+
+- 새 README 작성
+- 기존 README 점검
+- 사람 작성 내용을 보존한 갱신
+- 특정 섹션만 다시 작성
+- 검토한 패치만 직접 적용
+
+
+
+
+
+## 실제 결과
+
+아래 내용은 검토와 적용을 마친 이전 실행의 패치 일부입니다.
+
+
+```diff
+-A GitHub-README-specialized harness built around a shared core with entrypoints
+-for **Codex**, **Antigravity**, and **Claude**. It does not "prettify" READMEs —
+-it analyzes the facts that exist in a repository, judges project type and
+-audience, then iteratively produces and maintains a README with a readable
++이 하네스는 저장소의 실제 코드와 사용 목적을 바탕으로 문서 후보를 만들고,
++명령·경로·근거를 검사한 뒤 검토 가능한 패치로 제공합니다.
+```
+
+
+
+[전체 패치와 출처](examples/readme-showcase/README.patch)에서 더 긴 변경 내용을 확인할 수 있습니다.
+
+
+
+
+
+## 빠른 시작
+
+현재 실행 경로는 Codex 작업 공간의 `requirement-driven-readme` 스킬입니다.
+
+
+
+Codex에 다음과 같이 요청합니다.
+
+> 이 저장소의 README를 `bootstrap` 모드로 작성해 주세요.
+> 주 독자는 백엔드 개발자이며, 설치와 첫 실행 방법을 우선해 주세요.
+
+
+작업 뒤 확인할 파일은 `README.generated.md`와 `README.patch`입니다.
+
+
+
+생성된 README의 명령과 링크를 읽고, 패치가 의도한 범위만 바꾸는지 검토합니다.
+
+대상 `README.md`는 적용 명령을 실행하기 전까지 바뀌지 않습니다.
+
+
+
+검토가 끝난 패치만 직접 적용합니다.
+
+```bash
+python3 .agents/skills/requirement-driven-readme/scripts/apply_patch.py --run-dir runs// --repo /path/to/repository
+```
+
+적용 직전에 생성 파일과 대상 README, 저장소 기준 정보가 바뀌지 않았는지 다시 확인합니다.
+
+
+
+
+
+
+## 어떤 작업을 지원하는가
+
+새 README 작성과 전면 재작성의 기본 선택은 `bootstrap`입니다.
+
+
+현재 README의 문제만 찾는 작업은 `audit`입니다.
+
+
+사람이 작성한 영역을 보존하는 갱신은 `refresh`입니다.
+
+
+한 섹션과 영향을 받는 검사 결과의 갱신은 `section-update`입니다.
+
+
+
+
+
+
+## 안전하게 다루는 방법
+
+코드에서 확인한 사실과 사용자가 정한 문서 요구는 따로 둡니다.
+
+
+명령, 경로, 버전처럼 오류 영향이 큰 정보는 근거 파일과 연결합니다.
+
+
+갱신 작업은 보호 영역과 마커 밖의 사람이 작성한 문장을 보존합니다.
+
+
+사람이 고친 영역과 새 초안이 충돌하면 자동 병합과 적용이 중단됩니다.
+
+
+비밀 값이나 저장소 밖 경로가 발견되면 패치를 준비하지 않습니다.
+
+
+검토 뒤 저장소나 생성 파일이 바뀌어도 적용을 중단합니다.
+
+
+
+
+
+
+## 동작 방식
+
+사용자 요청 → 저장소 사실 확인 → README 작성 → 명령·링크·문장 검사 → 독립 검토 → 패치 확인 → 직접 적용
+
+
+검사에서 문제가 나오면 해당 내용을 맡은 단계부터 다시 작성합니다.
+
+
+
+
+
+
+## 입력과 생성 파일
+
+`readme-request.yaml`에는 독자, 목적, 언어, 보존 범위와 그림 정책을 적습니다.
+
+
+사용자는 다음 두 결과를 주로 확인합니다.
+
+- `README.generated.md`: 생성된 README
+- `README.patch`: 현재 README와의 차이
+
+각 작업의 파일은 `runs//` 아래에 따로 저장됩니다.
+
+
+
+
+
+
+## 개발
+
+개발에는 Python 3.12 이상이 필요하며, 개발 의존성에는 `pytest`가 포함됩니다.
+
+
+저장소 루트에서 개발 모드로 설치합니다.
+
+```bash
+python3 -m pip install -e ".[dev]"
+```
+
+전체 테스트는 다음 명령으로 실행합니다.
+
+```bash
+python3 -m pytest -q
+```
+
+
+
+
+
+## 상세 문서
+
+- [구성요소와 책임](docs/architecture.md)
+- [시각 자료와 실제 결과 증명](docs/visuals.md)
+- [모드별 처리 단계와 차단 조건](docs/state-machine.md)
+- [모델 사용량 기록](docs/usage-metrics.md)
+- [블라인드 README 품질 비교](docs/quality-benchmark.md)
+- [전체 설계 명세](docs/superpowers/specs/2026-07-16-readme-harness-design.md)
+
+주요 구현은 `src/readme_harness`, 규칙과 워크플로는 `.agents`, 테스트는 `tests`에 있습니다.
+
+
+
+
+
+
+## 현재 한계
+
+- README 문장은 모델이 작성하고 검사 스크립트는 준비된 파일을 확인합니다.
+
+
+- 실행 기록이 없는 명령은 정적으로만 확인합니다.
+
+
+- `Claude`와 `Antigravity`에서 `Codex`와 같은 동작을 하는지는 아직 검증하지 않았습니다.
+
+
+- 블라인드 품질 비교는 아직 실행하지 않았으며 더 좋은 결과를 낸다고 주장하지 않습니다.
+
+
+
diff --git a/runs/readme-harness/20260720-public-readme-r2/artifacts/attempt-1/claim-map.yaml b/runs/readme-harness/20260720-public-readme-r2/artifacts/attempt-1/claim-map.yaml
new file mode 100644
index 0000000..9308ae1
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme-r2/artifacts/attempt-1/claim-map.yaml
@@ -0,0 +1,147 @@
+schema-version: 1
+claims:
+ - id: C-PROJECT-001
+ type: factual
+ section: document
+ sources: [{fact-id: F-PROJECT-001}]
+ status: supported
+ - id: C-OUTPUT-001
+ type: factual
+ section: document
+ sources: [{fact-id: F-VERIFY-001}, {fact-id: F-OUTPUT-001}]
+ status: supported
+ - id: C-CODEX-001
+ type: factual
+ section: document
+ sources: [{fact-id: F-CODEX-001}]
+ status: supported
+ - id: C-XTOOL-001
+ type: factual
+ section: document
+ sources: [{fact-id: F-CODEX-001}]
+ status: supported
+ - id: C-PROOF-001
+ type: factual
+ section: proof
+ sources: [{fact-id: F-PROOF-001}]
+ status: supported
+ - id: C-INVOCATION-001
+ type: factual
+ section: quick-start
+ sources: [{fact-id: F-CODEX-001}]
+ status: supported
+ - id: C-RESULTS-001
+ type: factual
+ section: quick-start
+ sources: [{fact-id: F-OUTPUT-001}]
+ status: supported
+ - id: C-NO-AUTO-APPLY-001
+ type: factual
+ section: quick-start
+ sources: [{fact-id: F-APPLY-001}]
+ status: supported
+ - id: C-APPLY-CHECK-001
+ type: factual
+ section: quick-start
+ sources: [{fact-id: F-APPLY-001}]
+ status: supported
+ - id: C-MODE-BOOTSTRAP-001
+ type: factual
+ section: usage
+ sources: [{fact-id: F-MODES-001}, {fact-id: F-OUTPUT-001}]
+ status: supported
+ - id: C-MODE-AUDIT-001
+ type: factual
+ section: usage
+ sources: [{fact-id: F-MODES-001}, {fact-id: F-AUDIT-001}]
+ status: supported
+ - id: C-MODE-REFRESH-001
+ type: factual
+ section: usage
+ sources: [{fact-id: F-MODES-001}, {fact-id: F-REFRESH-001}]
+ status: supported
+ - id: C-MODE-SECTION-001
+ type: factual
+ section: usage
+ sources: [{fact-id: F-MODES-001}, {fact-id: F-SECTION-001}]
+ status: supported
+ - id: C-SOURCE-SPLIT-001
+ type: factual
+ section: safeguards
+ sources: [{fact-id: F-AUTHORITY-001}]
+ status: supported
+ - id: C-FACT-TRACE-001
+ type: factual
+ section: safeguards
+ sources: [{fact-id: F-CLAIM-001}, {fact-id: F-VERIFY-001}]
+ status: supported
+ - id: C-PRESERVE-001
+ type: factual
+ section: safeguards
+ sources: [{fact-id: F-REFRESH-001}]
+ status: supported
+ - id: C-CONFLICT-001
+ type: factual
+ section: safeguards
+ sources: [{fact-id: F-REFRESH-001}]
+ status: supported
+ - id: C-SECRET-PATH-001
+ type: factual
+ section: safeguards
+ sources: [{fact-id: F-SAFETY-001}]
+ status: supported
+ - id: C-STALE-001
+ type: factual
+ section: safeguards
+ sources: [{fact-id: F-SAFETY-001}, {fact-id: F-APPLY-001}]
+ status: supported
+ - id: C-WORKFLOW-001
+ type: factual
+ section: workflow
+ sources: [{fact-id: F-WORKFLOW-001}]
+ status: supported
+ - id: C-REWORK-001
+ type: factual
+ section: workflow
+ sources: [{fact-id: F-WORKFLOW-001}]
+ status: supported
+ - id: C-REQUEST-001
+ type: factual
+ section: inputs
+ sources: [{fact-id: F-AUTHORITY-001}, {fact-id: F-REPO-LAYOUT-001}]
+ status: supported
+ - id: C-RUN-DIR-001
+ type: factual
+ section: inputs
+ sources: [{fact-id: F-RUN-LAYOUT-001}]
+ status: supported
+ - id: C-DEV-PREREQ-001
+ type: factual
+ section: development
+ sources: [{fact-id: F-RUNTIME-001}]
+ status: supported
+ - id: C-LAYOUT-001
+ type: factual
+ section: documentation
+ sources: [{fact-id: F-REPO-LAYOUT-001}]
+ status: supported
+ - id: C-WRITING-LIMIT-001
+ type: factual
+ section: limitations
+ sources: [{fact-id: F-VERIFY-001}]
+ status: supported
+ - id: C-VERIFY-LIMIT-001
+ type: factual
+ section: limitations
+ sources: [{fact-id: F-VERIFY-001}]
+ status: supported
+ - id: C-XTOOL-LIMIT-001
+ type: factual
+ section: limitations
+ sources: [{fact-id: F-CODEX-001}]
+ status: supported
+ - id: C-BENCH-LIMIT-001
+ type: factual
+ section: limitations
+ sources: [{fact-id: F-BENCH-001}]
+ status: supported
diff --git a/runs/readme-harness/20260720-public-readme-r2/artifacts/attempt-1/prose-report.json b/runs/readme-harness/20260720-public-readme-r2/artifacts/attempt-1/prose-report.json
new file mode 100644
index 0000000..4d7f9fc
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme-r2/artifacts/attempt-1/prose-report.json
@@ -0,0 +1,16 @@
+{
+ "schema-version": 1,
+ "policy-id": "korean-reader-prose-v1",
+ "language": "ko-KR",
+ "applicable": true,
+ "scope": "candidate",
+ "state": "PASS",
+ "summary": {
+ "errors": 0,
+ "warnings": 0,
+ "sentences": 52,
+ "prose-characters": 1196,
+ "hangul-characters": 1007
+ },
+ "findings": []
+}
\ No newline at end of file
diff --git a/runs/readme-harness/20260720-public-readme-r2/artifacts/attempt-1/review-findings.yaml b/runs/readme-harness/20260720-public-readme-r2/artifacts/attempt-1/review-findings.yaml
new file mode 100644
index 0000000..dfb5e12
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme-r2/artifacts/attempt-1/review-findings.yaml
@@ -0,0 +1,123 @@
+schema-version: 1
+verdict: NEEDS_FIX
+score: 90
+scores:
+ project-specificity:
+ score: 5
+ evidence:
+ - artifact: README.candidate.md
+ section-id: quick-start
+ line-start: 56
+ line-end: 83
+ content-hash: sha256:1f849db919339542195b10e26c2db6028e2acfdc0c057fcddc8cc535932c829d
+ observation: Codex 스킬 식별자, 생성 파일, 명시적 적용 명령과 적용 전 재확인을 프로젝트 고유 경로로 연결한다.
+ reader-journey:
+ score: 5
+ evidence:
+ - artifact: README.candidate.md
+ section-id: document
+ line-start: 16
+ line-end: 85
+ content-hash: sha256:588e0fa1ad93f95c3f945ad2a8c7dcceeb414c77dd6395048955568c783a0540
+ observation: 사용자 결과, 대표 패치, Codex 요청, 생성 파일 확인, 성공 점검, 직접 적용 순서로 이어진다.
+ technical-explanation:
+ score: 4
+ evidence:
+ - artifact: README.candidate.md
+ section-id: document
+ line-start: 105
+ line-end: 125
+ content-hash: sha256:a4bd099a77602b1510fad18ef3023498c8c6c3efb700a2d4ebdf67a1182c0f0e
+ observation: 근거 분리, 추적, 보존, 충돌·비밀·변경 차단 책임을 결과 중심으로 구분한다.
+ - artifact: README.candidate.md
+ section-id: document
+ line-start: 129
+ line-end: 137
+ content-hash: sha256:47be1e061b740eb6e3acd12179b0420cb0a3c5a6df4f599df30adbb3662dd04e
+ observation: 처리 흐름과 재작성 동작을 짧게 설명하고 상세 책임은 별도 문서로 보낸다.
+ task-usability:
+ score: 4
+ evidence:
+ - artifact: README.candidate.md
+ section-id: quick-start
+ line-start: 56
+ line-end: 83
+ content-hash: sha256:1f849db919339542195b10e26c2db6028e2acfdc0c057fcddc8cc535932c829d
+ observation: 요청 예시부터 결과 파일 확인과 적용까지 한 절에서 수행할 수 있다.
+ prose-clarity:
+ score: 4
+ evidence:
+ - artifact: README.candidate.md
+ section-id: document
+ line-start: 5
+ line-end: 14
+ content-hash: sha256:c0843d3bcaf94929872e5e7ab675f77b9bbbaf66d50e8c61b6ce7d478e11c617
+ observation: 첫 문장부터 결과와 근거를 직접 밝히고 지원 범위와 미검증 범위를 분리한다.
+ - artifact: README.candidate.md
+ section-id: document
+ line-start: 195
+ line-end: 209
+ content-hash: sha256:93ace992f3430bfc7395d56e231a9c9892f959b7311d1da91f7296a8aefc29cd
+ observation: 모델 작성, 정적 확인, 도구 간 동작, 품질 비교의 한계를 짧은 항목으로 분리한다.
+ visual-judgment:
+ score: 5
+ evidence:
+ - artifact: README.candidate.md
+ section-id: document
+ line-start: 30
+ line-end: 48
+ content-hash: sha256:ad44797cc7abc92964f888bccafdc54cc71358f07057234f9975d728d91e4927
+ observation: 대표 패치를 내부 구조보다 먼저 보여 주고 전체 패치 경로를 연결한다.
+hard-gates:
+ passed: false
+ failures: [unsupported-high-risk-claim]
+reader-simulations:
+ 30-seconds:
+ outcome: PASS
+ evidence:
+ - artifact: README.candidate.md
+ section-id: document
+ line-start: 1
+ line-end: 14
+ content-hash: sha256:5b23dc0b21cf361bff806f69c8ed0e527528daefd523cca4ffe17ff9d3674196
+ observation: README 초안과 패치를 만드는 도구라는 점과 현재 Codex 범위를 첫 화면에서 확인한다.
+ 5-minutes:
+ outcome: PASS
+ evidence:
+ - artifact: README.candidate.md
+ section-id: document
+ line-start: 52
+ line-end: 139
+ content-hash: sha256:002ddd5d129170e198da9c5f2b202b0b1c35e01bcefcbfe6bd3df070c04cec7e
+ observation: 최소 사용자 경로, 네 가지 모드, 안전장치와 전체 처리 흐름을 찾을 수 있다.
+ - artifact: README.candidate.md
+ section-id: document
+ line-start: 195
+ line-end: 209
+ content-hash: sha256:93ace992f3430bfc7395d56e231a9c9892f959b7311d1da91f7296a8aefc29cd
+ observation: 검증 수준, 도구 간 동일 동작과 품질 우월성의 한계를 확인할 수 있다.
+ contributor:
+ outcome: PASS
+ evidence:
+ - artifact: README.candidate.md
+ section-id: document
+ line-start: 158
+ line-end: 191
+ content-hash: sha256:5dd4d4f75a0efbc470683bc6c995acdf3084d7416dccd012ff6bd7fe47b0b4f7
+ observation: Python 전제조건, 개발 설치와 테스트 명령, 구현·규칙·테스트 위치를 찾을 수 있다.
+findings:
+ - id: R-001
+ severity: major
+ category: technical-correctness
+ subject: C-PROOF-001
+ section: proof
+ message: 대표 패치의 적용 완료 주장은 연결된 저장소 사실의 범위를 넘으므로 검토 통과 사실로 좁혀야 한다.
+ evidence:
+ - artifact: README.candidate.md
+ section-id: proof
+ line-start: 34
+ line-end: 35
+ content-hash: sha256:00e36e843e3370132b9c62718c3da3778bb251c1def0374182edf1723ca26df2
+ observation: C-PROOF-001은 검토와 적용 완료를 함께 말하지만 F-PROOF-001에는 PASS 출처 상태만 있다.
+ route-to: README_DRAFTED
+ status: open
diff --git a/runs/readme-harness/20260720-public-readme-r2/artifacts/attempt-1/verification.json b/runs/readme-harness/20260720-public-readme-r2/artifacts/attempt-1/verification.json
new file mode 100644
index 0000000..f832c6b
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme-r2/artifacts/attempt-1/verification.json
@@ -0,0 +1,34 @@
+{
+ "schema-version": 1,
+ "state": "PASS_WITH_MANUAL",
+ "verification-level": "static",
+ "execution-verified": false,
+ "checks": {
+ "commands": {
+ "total": 3,
+ "verified": 1,
+ "manual-required": 2,
+ "failed": 0
+ },
+ "paths": {
+ "total": 7,
+ "verified": 7,
+ "failed": 0
+ },
+ "anchors": {
+ "total": 0,
+ "verified": 0,
+ "failed": 0
+ },
+ "readme-contracts": {
+ "total": 0,
+ "verified": 0,
+ "failed": 0
+ }
+ },
+ "failures": [],
+ "limitations": [
+ "manual verification required: python3 -m pip install -e \".[dev]\" (unsupported-static-verifier)",
+ "manual verification required: python3 -m pytest -q (unsupported-static-verifier)"
+ ]
+}
\ No newline at end of file
diff --git a/runs/readme-harness/20260720-public-readme-r2/artifacts/attempt-1/visual-plan.yaml b/runs/readme-harness/20260720-public-readme-r2/artifacts/attempt-1/visual-plan.yaml
new file mode 100644
index 0000000..2a6b3b4
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme-r2/artifacts/attempt-1/visual-plan.yaml
@@ -0,0 +1,31 @@
+schema-version: 1
+visuals:
+ - id: reviewed-patch-preview
+ section: proof
+ type: artifact-showcase
+ purpose: 검토와 적용을 마친 실제 README 패치의 핵심 변경을 보여 줍니다.
+ placeholder-text: 영문 중심 소개가 한국어 사용자 중심 소개로 바뀐 실제 diff 일부
+ must-show:
+ - 변경 전 영문 소개
+ - 변경 후 한국어 소개
+ relationships: []
+ emphasize:
+ - 입력 문서와 생성 문서의 차이
+ avoid:
+ - 저장소 근거가 없는 품질 우월성 표현
+ require-provenance: true
+ placement:
+ after-section-id: proof
+ accessibility:
+ alt-text: 영문 소개를 한국어 사용자 중심 소개로 바꾼 README 패치 미리보기
+ production:
+ format: diff
+ status: source-created
+ source-path: examples/readme-showcase/README.patch
+ source-hash: sha256:3f930c70600d6530afa4a6b486be7f467f8650d28f4f2b057b889ef97f545e19
+ asset:
+ path: examples/readme-showcase/README.patch
+ provenance: examples/readme-showcase/provenance.yaml
+ source-run: runs/readme-harness/20260720-review-remediation
+ sha256: sha256:3f930c70600d6530afa4a6b486be7f467f8650d28f4f2b057b889ef97f545e19
+ caption: 검토와 적용을 마친 이전 README 실행의 실제 패치 일부입니다.
diff --git a/runs/readme-harness/20260720-public-readme-r2/claim-map.yaml b/runs/readme-harness/20260720-public-readme-r2/claim-map.yaml
new file mode 100644
index 0000000..f255b31
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme-r2/claim-map.yaml
@@ -0,0 +1,31 @@
+schema-version: 1
+claims:
+ - {id: C-PROJECT-001, type: factual, section: document, sources: [{fact-id: F-PROJECT-001}], status: supported}
+ - {id: C-OUTPUT-001, type: factual, section: document, sources: [{fact-id: F-VERIFY-001}, {fact-id: F-OUTPUT-001}], status: supported}
+ - {id: C-CODEX-001, type: factual, section: document, sources: [{fact-id: F-CODEX-001}], status: supported}
+ - {id: C-XTOOL-001, type: factual, section: document, sources: [{fact-id: F-CODEX-001}], status: supported}
+ - {id: C-PROOF-001, type: factual, section: proof, sources: [{fact-id: F-PROOF-001}], status: supported}
+ - {id: C-INVOCATION-001, type: factual, section: quick-start, sources: [{fact-id: F-CODEX-001}], status: supported}
+ - {id: C-RESULTS-001, type: factual, section: quick-start, sources: [{fact-id: F-OUTPUT-001}], status: supported}
+ - {id: C-NO-AUTO-APPLY-001, type: factual, section: quick-start, sources: [{fact-id: F-APPLY-001}], status: supported}
+ - {id: C-APPLY-CHECK-001, type: factual, section: quick-start, sources: [{fact-id: F-APPLY-001}], status: supported}
+ - {id: C-MODE-BOOTSTRAP-001, type: factual, section: usage, sources: [{fact-id: F-MODES-001}, {fact-id: F-OUTPUT-001}], status: supported}
+ - {id: C-MODE-AUDIT-001, type: factual, section: usage, sources: [{fact-id: F-MODES-001}, {fact-id: F-AUDIT-001}], status: supported}
+ - {id: C-MODE-REFRESH-001, type: factual, section: usage, sources: [{fact-id: F-MODES-001}, {fact-id: F-REFRESH-001}], status: supported}
+ - {id: C-MODE-SECTION-001, type: factual, section: usage, sources: [{fact-id: F-MODES-001}, {fact-id: F-SECTION-001}], status: supported}
+ - {id: C-SOURCE-SPLIT-001, type: factual, section: safeguards, sources: [{fact-id: F-AUTHORITY-001}], status: supported}
+ - {id: C-FACT-TRACE-001, type: factual, section: safeguards, sources: [{fact-id: F-CLAIM-001}, {fact-id: F-VERIFY-001}], status: supported}
+ - {id: C-PRESERVE-001, type: factual, section: safeguards, sources: [{fact-id: F-REFRESH-001}], status: supported}
+ - {id: C-CONFLICT-001, type: factual, section: safeguards, sources: [{fact-id: F-REFRESH-001}], status: supported}
+ - {id: C-SECRET-PATH-001, type: factual, section: safeguards, sources: [{fact-id: F-SAFETY-001}], status: supported}
+ - {id: C-STALE-001, type: factual, section: safeguards, sources: [{fact-id: F-SAFETY-001}, {fact-id: F-APPLY-001}], status: supported}
+ - {id: C-WORKFLOW-001, type: factual, section: workflow, sources: [{fact-id: F-WORKFLOW-001}], status: supported}
+ - {id: C-REWORK-001, type: factual, section: workflow, sources: [{fact-id: F-WORKFLOW-001}], status: supported}
+ - {id: C-REQUEST-001, type: factual, section: inputs, sources: [{fact-id: F-AUTHORITY-001}, {fact-id: F-REPO-LAYOUT-001}], status: supported}
+ - {id: C-RUN-DIR-001, type: factual, section: inputs, sources: [{fact-id: F-RUN-LAYOUT-001}], status: supported}
+ - {id: C-DEV-PREREQ-001, type: factual, section: development, sources: [{fact-id: F-RUNTIME-001}], status: supported}
+ - {id: C-LAYOUT-001, type: factual, section: documentation, sources: [{fact-id: F-REPO-LAYOUT-001}], status: supported}
+ - {id: C-WRITING-LIMIT-001, type: factual, section: limitations, sources: [{fact-id: F-VERIFY-001}], status: supported}
+ - {id: C-VERIFY-LIMIT-001, type: factual, section: limitations, sources: [{fact-id: F-VERIFY-001}], status: supported}
+ - {id: C-XTOOL-LIMIT-001, type: factual, section: limitations, sources: [{fact-id: F-CODEX-001}], status: supported}
+ - {id: C-BENCH-LIMIT-001, type: factual, section: limitations, sources: [{fact-id: F-BENCH-001}], status: supported}
diff --git a/runs/readme-harness/20260720-public-readme-r2/prose-report.json b/runs/readme-harness/20260720-public-readme-r2/prose-report.json
new file mode 100644
index 0000000..37abafc
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme-r2/prose-report.json
@@ -0,0 +1,16 @@
+{
+ "schema-version": 1,
+ "policy-id": "korean-reader-prose-v1",
+ "language": "ko-KR",
+ "applicable": true,
+ "scope": "candidate",
+ "state": "PASS",
+ "summary": {
+ "errors": 0,
+ "warnings": 0,
+ "sentences": 52,
+ "prose-characters": 1194,
+ "hangul-characters": 1005
+ },
+ "findings": []
+}
\ No newline at end of file
diff --git a/runs/readme-harness/20260720-public-readme-r2/quality-manifest.yaml b/runs/readme-harness/20260720-public-readme-r2/quality-manifest.yaml
new file mode 100644
index 0000000..352622e
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme-r2/quality-manifest.yaml
@@ -0,0 +1,14 @@
+schema-version: 2
+mode: bootstrap
+profile: tool
+repository-snapshot-hash: sha256:2ff902bd9a7de01648f972d099614584bc26fa84c1492cec61dc6da82e4f6275
+artifacts:
+ readme-request.yaml: sha256:545161085f426a1774dec0db5d66189f817b62d5991da253115677d99746f8c2
+ repository-facts.yaml: sha256:0113f0f6acd124348d4987264ba8600492a2fe26278abb2a65309977b2ff7a69
+ readme-brief.yaml: sha256:651ac6a29ac2592ef96779b8a7387085bbdcd36575d2edd97b8bfd72a2621374
+ readme-outline.yaml: sha256:f2f5169f12e20ec51692c6341facd49689b2057fd7ea4a38b17446eb219d2f97
+ README.candidate.md: sha256:b54317f98e0bea64cc31f489caca9a541b24bbdfec3aab6af3be41d0dd4dab22
+ claim-map.yaml: sha256:194995416648414c0a18078477b0bbfd7e61ddad264efeff531bdda35ce92206
+ visual-plan.yaml: sha256:0f306a9c1ccf0c39fd636f52d4348f694bbb79e82530dbf37e08d0df063e5418
+ prose-report.json: sha256:f35a4b2bb25d3e0e1435ed3b6065313ae90e4ca4a6ef739e72c74515fb3a887f
+ review-findings.yaml: sha256:a91d19b05e2c6364dd9b424fd23d71c3829f2b244eeea9bd1a072962cfcae69e
diff --git a/runs/readme-harness/20260720-public-readme-r2/readme-brief.yaml b/runs/readme-harness/20260720-public-readme-r2/readme-brief.yaml
new file mode 100644
index 0000000..6d371bd
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme-r2/readme-brief.yaml
@@ -0,0 +1,47 @@
+schema-version: 1
+project-profile:
+ primary: tool
+audiences:
+ primary:
+ - 저장소 README를 새로 만들거나 안전하게 갱신하려는 개발자
+ secondary:
+ - 하네스 검사와 프로파일을 확장하는 기여자
+reader-outcomes:
+ - 첫 두 문장에서 README 초안과 패치를 만드는 도구임을 판단한다.
+ - Codex에 작업을 요청하고 생성된 README와 패치를 확인한다.
+ - 작업에 맞는 모드를 고르고 검토한 패치만 직접 적용한다.
+ - 개발 환경과 상세 설계는 사용자 경로 뒤에서 찾는다.
+project-story:
+ value-proposition: 저장소 사실과 문서 요구를 바탕으로 README 초안을 만들고 검토용 패치로 제공합니다.
+ problem: README 작성 도구가 없는 명령을 쓰거나 사람의 문장을 덮어쓰면 검토 비용과 적용 위험이 커집니다.
+ target-reader: README를 만들거나 갱신하려는 개발자
+ notable-traits:
+ - text: 네 가지 문서 작업을 지원하며 결과를 검토용 패치로 분리합니다.
+ fact-ids: [F-MODES-001, F-OUTPUT-001]
+ - text: 명령과 경로를 확인하고 검토 전 대상 README를 바꾸지 않습니다.
+ fact-ids: [F-VERIFY-001, F-APPLY-001]
+ - text: 공개 README에는 실제 검토를 통과한 패치 예시를 연결합니다.
+ fact-ids: [F-PROOF-001]
+ maturity: Codex용 흐름은 구현됐고 Claude와 Antigravity의 같은 동작은 아직 검증하지 않았습니다.
+ limitations:
+ - README 문장은 모델이 작성하며 검사 스크립트가 문장을 대신 만들지는 않습니다.
+ - 명령 검증은 실행 기록이 없으면 정적 확인 수준입니다.
+ - 도구 간 같은 동작과 품질 우월성은 아직 주장하지 않습니다.
+narrative-variant: tool
+reader-journey:
+ - reader-question: 이 도구가 만드는 결과는 무엇입니까?
+ section-id: overview
+ - reader-question: 실제 결과는 어떤 모습입니까?
+ section-id: proof
+ - reader-question: 가장 짧은 사용자 경로는 무엇입니까?
+ section-id: quick-start
+ - reader-question: 작업에 맞는 모드는 무엇입니까?
+ section-id: usage
+ - reader-question: 적용 전에 무엇을 확인합니까?
+ section-id: safeguards
+ - reader-question: 하네스는 어떤 순서로 일합니까?
+ section-id: workflow
+ - reader-question: 사용자에게 필요한 파일은 무엇입니까?
+ section-id: inputs
+ - reader-question: 개발과 상세 설계는 어디서 확인합니까?
+ section-id: development
diff --git a/runs/readme-harness/20260720-public-readme-r2/readme-outline.yaml b/runs/readme-harness/20260720-public-readme-r2/readme-outline.yaml
new file mode 100644
index 0000000..a13ea87
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme-r2/readme-outline.yaml
@@ -0,0 +1,78 @@
+schema-version: 1
+sections:
+ - id: overview
+ title-guidance: 무엇을 만드는가
+ level: 2
+ purpose: 프로젝트 결과와 현재 지원 범위를 첫 화면에서 설명합니다.
+ required: true
+ content-strategy: inline
+ content-requirements:
+ - README 초안과 패치
+ - Codex 지원과 다른 도구의 미검증 범위
+ - id: proof
+ title-guidance: 실제 결과
+ level: 2
+ purpose: 검토를 통과한 실제 패치 일부를 먼저 보여 줍니다.
+ required: true
+ content-strategy: inline
+ content-requirements:
+ - 실제 이전 실행의 패치 미리보기
+ - 전체 패치와 출처 링크
+ visual-slot:
+ decision: include
+ reader-question: 이 도구가 만든 실제 README 변경은 어떤 모습입니까?
+ rationale: 결과가 문서인 도구는 내부 구조도보다 실제 변경 내용을 먼저 보여 줘야 합니다.
+ purpose: 이전 실행에서 검토와 적용을 마친 README 패치 일부를 보여 줍니다.
+ - id: quick-start
+ title-guidance: 빠른 시작
+ level: 2
+ purpose: Codex 요청부터 결과 확인과 명시적 적용까지의 기본 경로를 제공합니다.
+ required: true
+ content-strategy: inline
+ content-requirements:
+ - 사용자 요청
+ - 생성 파일
+ - 성공 확인
+ - 명시적 적용
+ - id: usage
+ title-guidance: 어떤 작업을 지원하는가
+ level: 2
+ purpose: 기본 모드와 세 보조 모드를 독자 작업 기준으로 구분합니다.
+ required: true
+ content-strategy: inline
+ - id: safeguards
+ title-guidance: 안전하게 다루는 방법
+ level: 2
+ purpose: 근거 확인과 사람 작성 내용 보존, 자동 적용 금지를 설명합니다.
+ required: true
+ content-strategy: inline
+ - id: workflow
+ title-guidance: 동작 방식
+ level: 2
+ purpose: 사용자 관점의 처리 순서만 짧게 보여 줍니다.
+ required: true
+ content-strategy: inline
+ - id: inputs
+ title-guidance: 입력과 생성 파일
+ level: 2
+ purpose: 사용자가 준비하고 확인할 파일만 설명합니다.
+ required: true
+ content-strategy: inline
+ - id: development
+ title-guidance: 개발
+ level: 2
+ purpose: 기여자용 설치와 테스트 경로를 사용자 경로 뒤에 둡니다.
+ required: true
+ content-strategy: inline
+ - id: documentation
+ title-guidance: 상세 문서
+ level: 2
+ purpose: 내부 구조와 정책을 정본 문서로 연결합니다.
+ required: true
+ content-strategy: inline
+ - id: limitations
+ title-guidance: 현재 한계
+ level: 2
+ purpose: 모델 작성과 검증 수준, 도구 지원 범위를 한곳에 정리합니다.
+ required: true
+ content-strategy: inline
diff --git a/runs/readme-harness/20260720-public-readme-r2/readme-request.yaml b/runs/readme-harness/20260720-public-readme-r2/readme-request.yaml
new file mode 100644
index 0000000..afde33d
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme-r2/readme-request.yaml
@@ -0,0 +1,78 @@
+schema-version: 1
+target:
+ repository: /home/donghyeon/workspace/ai-tool/readme-harness
+ readme-path: README.md
+mode: bootstrap
+profile-override: tool
+project-intent:
+ purpose: 저장소에서 확인한 사실과 사용자가 정한 요구를 바탕으로 README 초안과 검토용 패치를 만드는 도구를 설명한다.
+ positioning: 사용자 경로를 먼저 보여 주고, 명령·경로·문장 근거 검사와 사람 작성 내용 보존은 필요한 수준에서만 설명한다.
+ maturity: 현재 Codex용 작성·검증 흐름을 지원하며 Claude와 Antigravity의 동일 동작은 아직 검증하지 않았다.
+audience:
+ primary:
+ - 저장소 README를 새로 만들거나 안전하게 갱신하려는 개발자
+ secondary:
+ - 하네스 검사와 프로파일을 확장하는 기여자
+reader-actions:
+ - 첫 두 문장에서 어떤 결과를 만드는 도구인지 판단한다.
+ - Codex에 README 작업을 요청하고 생성된 README와 패치를 확인한다.
+ - 작업 목적에 맞는 모드를 고른다.
+ - 검토한 패치만 명시적으로 적용한다.
+ - 개발 환경과 테스트 방법은 별도의 개발 절에서 찾는다.
+content-policy:
+ language: ko-KR
+ tone: 독자 행동을 먼저 밝히는 직접적인 기술 설명체
+ target-length: medium
+ preserve-existing-copy: false
+ detail-docs-policy: summary-and-link
+visual-policy:
+ mode: when-useful
+ max-visuals: 1
+ preferred-formats:
+ - diff
+ placeholder-format: HTML 주석 기반 제작 사양
+terminology-policy:
+ exact-identifiers: []
+ explain-on-first-use: {}
+ internal-only:
+ family: 작업 담당 방식
+ fan-out: 여러 담당자가 나눠 검토
+ collapse: 한 담당자가 맡아 처리
+ concrete worker: 실제 변경 담당자
+ verification family: 검증 담당 역할
+ route-to: 다시 작성할 지점
+public-surface-terms:
+ allowed:
+ - bootstrap
+ - audit
+ - refresh
+ - section-update
+ - readme-request.yaml
+ - README.generated.md
+ - README.patch
+ - requirement-driven-readme
+ explain-on-first-use: {}
+ docs-only:
+ - QUALITY_REVIEWED
+ - READY_FOR_APPLY
+ - claim-map.yaml
+ - visual-plan.yaml
+ - review-findings.yaml
+ - quality-manifest.yaml
+must-include:
+ - 한 문장 설명과 Codex 지원 범위
+ - 실제 검토를 통과한 패치 미리보기와 원본 파일 링크
+ - Codex 스킬 요청부터 생성 파일 확인, 성공 확인, 명시적 적용까지의 기본 사용자 경로
+ - bootstrap을 기본 경로로 두고 audit, refresh, section-update를 보조 경로로 설명
+ - 코드에서 확인한 사실, 사람 작성 내용 보존, 자동 적용 금지, 변경·비밀 값 차단 요약
+ - 사용자 입력과 생성 파일을 세 개에서 네 개 수준으로 요약
+ - 개발 환경 설치와 전체 테스트를 사용자 경로 뒤의 개발 절에 배치
+ - 아키텍처, 시각 자료, 상태, 사용량, 품질 비교 상세 문서 링크
+ - 현재 Codex 지원과 다른 도구의 동일 동작 미검증 한계
+must-exclude:
+ - 빠른 시작의 첫 행동으로 테스트나 개발 의존성 설치를 제시하는 구성
+ - 공개 README에서 내부 상태 이름, 내부 결과 파일, 게이트 계약을 설명하는 문장
+ - 저장소 근거 없는 성능·품질 우월성 주장
+ - 한 주장 마커가 여러 사실 문장을 덮는 구성
+ - 제품 결과보다 먼저 나오는 내부 구조도
+protected-sections: []
diff --git a/runs/readme-harness/20260720-public-readme-r2/repository-facts.yaml b/runs/readme-harness/20260720-public-readme-r2/repository-facts.yaml
new file mode 100644
index 0000000..3ddd7b7
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme-r2/repository-facts.yaml
@@ -0,0 +1,387 @@
+schema-version: 1
+repository-snapshot-hash: sha256:2ff902bd9a7de01648f972d099614584bc26fa84c1492cec61dc6da82e4f6275
+project-name: readme-harness
+languages: [Python, Markdown, YAML]
+frameworks: []
+facts:
+ - id: F-PROJECT-001
+ category: project
+ key: identity
+ value:
+ name: readme-harness
+ version: 0.1.0
+ purpose: 저장소 사실과 사용자 요구를 바탕으로 GitHub README를 분석·설계·작성·검증합니다.
+ assertion-type: declared
+ confidence: high
+ evidence:
+ - path: harness.yaml
+ source-kind: project-manifest
+ line-start: 2
+ line-end: 6
+ - path: pyproject.toml
+ source-kind: build-manifest
+ line-start: 1
+ line-end: 4
+ - id: F-RUNTIME-001
+ category: prerequisites
+ key: python-and-development
+ value:
+ python-minimum: "3.12"
+ runtime-packages: [jsonschema, PyYAML]
+ development-tool: pytest
+ assertion-type: declared
+ confidence: high
+ evidence:
+ - path: pyproject.toml
+ source-kind: build-manifest
+ line-start: 1
+ line-end: 13
+ - id: F-TOOL-PROFILE-001
+ category: audience
+ key: tool-profile
+ value:
+ primary-outcome: reviewed-patch-created
+ max-primary-steps: 4
+ development-command-as-first-step: false
+ representative-proof-required: true
+ assertion-type: declared
+ confidence: high
+ evidence:
+ - path: .agents/profiles/tool.yaml
+ source-kind: profile
+ line-start: 1
+ line-end: 21
+ - id: F-MODES-001
+ category: capability
+ key: implemented-modes
+ value: [bootstrap, audit, refresh, section-update]
+ assertion-type: declared
+ confidence: high
+ evidence:
+ - path: harness.yaml
+ source-kind: project-manifest
+ line-start: 10
+ line-end: 13
+ - id: F-WORKFLOW-001
+ category: workflow
+ key: public-flow
+ value: 사용자 요구와 저장소 근거를 분리해 계획하고, 모델 작성 뒤 검사와 독립 검토를 거쳐 패치 준비와 명시적 적용으로 이어집니다.
+ assertion-type: declared
+ confidence: high
+ evidence:
+ - path: docs/architecture.md
+ source-kind: documentation
+ line-start: 3
+ line-end: 49
+ - path: .agents/skills/requirement-driven-readme/SKILL.md
+ source-kind: skill-contract
+ line-start: 27
+ line-end: 45
+ - id: F-AUDIT-001
+ category: workflow
+ key: audit-behavior
+ value: audit는 기존 README를 점검하며 대체 README나 패치를 만들지 않습니다.
+ assertion-type: declared
+ confidence: high
+ evidence:
+ - path: docs/state-machine.md
+ source-kind: documentation
+ line-start: 19
+ line-end: 23
+ - path: harness.yaml
+ source-kind: project-manifest
+ line-start: 53
+ line-end: 55
+ - id: F-REFRESH-001
+ category: safeguard
+ key: refresh-merge-policy
+ value:
+ protected: never-modify
+ unmarked: preserve
+ managed: regenerate-or-3way-merge
+ conflict-result: block
+ post-merge-validation: required
+ assertion-type: declared
+ confidence: high
+ evidence:
+ - path: harness.yaml
+ source-kind: project-manifest
+ line-start: 82
+ line-end: 100
+ - path: docs/state-machine.md
+ source-kind: documentation
+ line-start: 25
+ line-end: 29
+ - id: F-SECTION-001
+ category: workflow
+ key: section-update-behavior
+ value: section-update는 선택한 섹션의 의존 결과를 무효화한 뒤 전체 문서 검증과 명시적 적용 경계를 다시 거칩니다.
+ assertion-type: declared
+ confidence: high
+ evidence:
+ - path: docs/state-machine.md
+ source-kind: documentation
+ line-start: 31
+ line-end: 36
+ - path: harness.yaml
+ source-kind: project-manifest
+ line-start: 116
+ line-end: 122
+ - id: F-VERIFY-001
+ category: architecture
+ key: editorial-and-verification-separation
+ value: 모델 역할이 문장을 작성하고 Python 검사가 근거, 문장, 명령, 경로, 링크, 비밀 값, 그림, 해시와 적용 경계를 확인합니다.
+ assertion-type: declared
+ confidence: high
+ evidence:
+ - path: docs/architecture.md
+ source-kind: documentation
+ line-start: 3
+ line-end: 6
+ - path: docs/architecture.md
+ source-kind: documentation
+ line-start: 40
+ line-end: 49
+ - id: F-AUTHORITY-001
+ category: trust
+ key: evidence-authority
+ value:
+ technical-facts-source: repository-facts.yaml
+ intent-source: readme-request.yaml
+ repository-content-trust: untrusted-data
+ assertion-type: declared
+ confidence: high
+ evidence:
+ - path: .agents/skills/requirement-driven-readme/SKILL.md
+ source-kind: skill-contract
+ line-start: 27
+ line-end: 29
+ - path: docs/architecture.md
+ source-kind: documentation
+ line-start: 67
+ line-end: 72
+ - id: F-CLAIM-001
+ category: safeguard
+ key: factual-claim-traceability
+ value: 사실 주장은 알려진 근거 ID를 참조해야 하며 한 claim-id 마커는 정확히 한 문장만 가리킵니다.
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: src/readme_harness/claims.py
+ source-kind: implementation
+ symbol: validate_claim_map
+ line-start: 45
+ line-end: 100
+ - id: F-PROSE-001
+ category: safeguard
+ key: reader-prose-validation
+ value: 같은 문단의 연속 줄을 합친 뒤 문장 길이와 표현을 검사하며 목록과 표의 각 항목은 따로 검사합니다.
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: src/readme_harness/prose.py
+ source-kind: implementation
+ symbol: _visible_lines
+ line-start: 82
+ line-end: 150
+ - path: tests/unit/test_prose.py
+ source-kind: test
+ symbol: test_hard_wrapped_paragraph_is_joined_before_sentence_length_check
+ line-start: 110
+ line-end: 126
+ - id: F-VISUAL-001
+ category: visual
+ key: representative-output-policy
+ value: 실제 결과 증명은 저장소의 지속 경로와 검토된 출처, 파일 해시를 가져야 합니다.
+ assertion-type: declared
+ confidence: high
+ evidence:
+ - path: docs/visuals.md
+ source-kind: documentation
+ line-start: 3
+ line-end: 27
+ - path: .agents/profiles/tool.yaml
+ source-kind: profile
+ line-start: 15
+ line-end: 21
+ - id: F-OUTPUT-001
+ category: safeguard
+ key: patch-preparation
+ value:
+ target: README.md
+ outputs: [README.generated.md, README.patch, apply-manifest.yaml]
+ checks: [repository-freshness, reviewed-artifact-hashes, target-path-containment]
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: .agents/skills/requirement-driven-readme/scripts/generate_patch.py
+ source-kind: implementation
+ symbol: main
+ line-start: 25
+ line-end: 89
+ - id: F-APPLY-001
+ category: safeguard
+ key: explicit-apply
+ value:
+ command-identifier: apply_patch.py
+ target: README.md
+ checks: [generated-hash, repository-freshness, path-containment, target-before-hash]
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: .agents/skills/requirement-driven-readme/scripts/apply_patch.py
+ source-kind: implementation
+ symbol: main
+ line-start: 22
+ line-end: 67
+ - path: harness.yaml
+ source-kind: project-manifest
+ line-start: 141
+ line-end: 148
+ - id: F-BENCH-001
+ category: limitation
+ key: quality-superiority
+ value:
+ current-status: not-run
+ claim-policy: prohibited-until-benchmark-pass
+ benchmark: benchmarks/quality-benchmark.yaml
+ assertion-type: declared
+ confidence: high
+ evidence:
+ - path: harness.yaml
+ source-kind: project-manifest
+ line-start: 109
+ line-end: 114
+ - path: docs/quality-benchmark.md
+ source-kind: documentation
+ line-start: 3
+ line-end: 36
+ - id: F-PROOF-001
+ category: representative-output
+ key: reviewed-patch-showcase
+ value:
+ path: examples/readme-showcase/README.patch
+ media-type: text/x-diff
+ source-status: PASS
+ sha256: 3f930c70600d6530afa4a6b486be7f467f8650d28f4f2b057b889ef97f545e19
+ assertion-type: declared
+ confidence: high
+ evidence:
+ - path: examples/readme-showcase/provenance.yaml
+ source-kind: provenance-record
+ line-start: 1
+ line-end: 9
+ - id: F-CODEX-001
+ category: capability
+ key: codex-skill-and-cross-tool-support
+ value:
+ skill-identifier: requirement-driven-readme
+ codex-path-drivers: implemented
+ supported-tools: [codex, antigravity, claude]
+ claude-antigravity-runtime-equivalence: phase-4-conformance-goal
+ assertion-type: derived
+ confidence: high
+ evidence:
+ - path: .agents/skills/requirement-driven-readme/SKILL.md
+ source-kind: skill-contract
+ line-start: 2
+ line-end: 9
+ - path: harness.yaml
+ source-kind: project-manifest
+ line-start: 8
+ line-end: 13
+ - path: docs/architecture.md
+ source-kind: documentation
+ line-start: 32
+ line-end: 34
+ - id: F-RUN-LAYOUT-001
+ category: layout
+ key: run-directory
+ value:
+ canonical: "runs///"
+ public-form: "runs//"
+ assertion-type: declared
+ confidence: high
+ evidence:
+ - path: harness.yaml
+ source-kind: project-manifest
+ line-start: 137
+ line-end: 139
+ - path: .agents/skills/requirement-driven-readme/SKILL.md
+ source-kind: skill-contract
+ line-start: 38
+ line-end: 39
+ - id: F-REPO-LAYOUT-001
+ category: layout
+ key: repository-paths
+ value:
+ implementation: src/readme_harness
+ rules-and-workflows: .agents
+ tests: tests
+ request-file: readme-request.yaml
+ assertion-type: derived
+ confidence: high
+ evidence:
+ - path: harness.yaml
+ source-kind: project-manifest
+ line-start: 132
+ line-end: 139
+ - path: pyproject.toml
+ source-kind: build-manifest
+ line-start: 14
+ line-end: 19
+ - path: docs/architecture.md
+ source-kind: documentation
+ line-start: 7
+ line-end: 49
+ - id: F-SAFETY-001
+ category: safeguard
+ key: stale-secret-and-path-protection
+ value:
+ stale-snapshot: blocks-patch-generation-and-apply
+ secret-values: forbidden-in-facts-and-readme
+ target-path: must-resolve-inside-repository
+ out-of-tree-symlinks: findings-not-traversal-targets
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: .agents/skills/requirement-driven-readme/scripts/generate_patch.py
+ source-kind: implementation
+ line-start: 46
+ line-end: 68
+ - path: .agents/skills/requirement-driven-readme/scripts/apply_patch.py
+ source-kind: implementation
+ line-start: 46
+ line-end: 61
+ - path: .agents/rules/repository-content-trust.md
+ source-kind: policy
+ line-start: 13
+ line-end: 28
+commands:
+ - id: CMD-001
+ command: python3 .agents/skills/requirement-driven-readme/scripts/apply_patch.py --run-dir runs// --repo /path/to/repository
+ cwd: .
+ source:
+ path: .agents/skills/requirement-driven-readme/scripts/apply_patch.py
+ source-kind: implementation
+ verification:
+ status: discovered
+ method: python-script-existence
+ - id: CMD-002
+ command: python3 -m pip install -e ".[dev]"
+ cwd: .
+ source:
+ path: pyproject.toml
+ source-kind: build-manifest
+ verification:
+ status: declared
+ method: pyproject-optional-dependencies
+ - id: CMD-003
+ command: python3 -m pytest -q
+ cwd: .
+ source:
+ path: pyproject.toml
+ source-kind: build-manifest
+ verification:
+ status: declared
+ method: pytest-configuration
diff --git a/runs/readme-harness/20260720-public-readme-r2/repository-snapshot.json b/runs/readme-harness/20260720-public-readme-r2/repository-snapshot.json
new file mode 100644
index 0000000..e9ef333
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme-r2/repository-snapshot.json
@@ -0,0 +1,7 @@
+{
+ "git-sha": "636617ccd9f20440f21339f808557c096b55fec2",
+ "dirty": true,
+ "diff-hash": "sha256:2ff902bd9a7de01648f972d099614584bc26fa84c1492cec61dc6da82e4f6275",
+ "scanned-at": null,
+ "file-count": 231
+}
\ No newline at end of file
diff --git a/runs/readme-harness/20260720-public-readme-r2/review-findings.yaml b/runs/readme-harness/20260720-public-readme-r2/review-findings.yaml
new file mode 100644
index 0000000..d53a16c
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme-r2/review-findings.yaml
@@ -0,0 +1,55 @@
+schema-version: 1
+verdict: PASS
+score: 90
+scores:
+ project-specificity:
+ score: 5
+ evidence:
+ - {artifact: README.candidate.md, section-id: quick-start, line-start: 56, line-end: 83, content-hash: "sha256:1f849db919339542195b10e26c2db6028e2acfdc0c057fcddc8cc535932c829d", observation: "Codex 스킬부터 생성 파일과 명시적 적용까지 프로젝트 고유 경로를 보여 준다."}
+ reader-journey:
+ score: 5
+ evidence:
+ - {artifact: README.candidate.md, section-id: document, line-start: 16, line-end: 85, content-hash: "sha256:b321d79f0e9891648e916dd64a486bf562e54950ad960d1d898f4a4ccf3efa72", observation: "사용자 결과와 대표 패치, 요청, 확인, 적용 순서로 이어진다."}
+ technical-explanation:
+ score: 4
+ evidence:
+ - {artifact: README.candidate.md, section-id: document, line-start: 105, line-end: 125, content-hash: "sha256:a4bd099a77602b1510fad18ef3023498c8c6c3efb700a2d4ebdf67a1182c0f0e", observation: "근거 분리와 보존, 충돌·비밀·변경 차단 책임을 결과 중심으로 구분한다."}
+ task-usability:
+ score: 4
+ evidence:
+ - {artifact: README.candidate.md, section-id: quick-start, line-start: 56, line-end: 83, content-hash: "sha256:1f849db919339542195b10e26c2db6028e2acfdc0c057fcddc8cc535932c829d", observation: "요청 예시부터 결과 파일 확인과 적용까지 한 절에서 수행할 수 있다."}
+ prose-clarity:
+ score: 4
+ evidence:
+ - {artifact: README.candidate.md, section-id: document, line-start: 5, line-end: 14, content-hash: "sha256:c0843d3bcaf94929872e5e7ab675f77b9bbbaf66d50e8c61b6ce7d478e11c617", observation: "첫 문장부터 결과와 범위를 직접 밝히며 한국어 문체 검사 경고가 없다."}
+ visual-judgment:
+ score: 5
+ evidence:
+ - {artifact: README.candidate.md, section-id: document, line-start: 30, line-end: 48, content-hash: "sha256:aa73ed11c4b75d71efa7899fbdff8803d6cbd59ba9c9c20597b1d8c6fa9dca90", observation: "검토 통과 상태의 대표 패치를 내부 구조보다 먼저 보여 준다."}
+hard-gates:
+ passed: true
+ failures: []
+reader-simulations:
+ 30-seconds:
+ outcome: PASS
+ evidence:
+ - {artifact: README.candidate.md, section-id: document, line-start: 1, line-end: 14, content-hash: "sha256:5b23dc0b21cf361bff806f69c8ed0e527528daefd523cca4ffe17ff9d3674196", observation: "README 초안과 패치를 만드는 도구와 현재 Codex 범위를 첫 화면에서 확인한다."}
+ 5-minutes:
+ outcome: PASS
+ evidence:
+ - {artifact: README.candidate.md, section-id: document, line-start: 52, line-end: 139, content-hash: "sha256:002ddd5d129170e198da9c5f2b202b0b1c35e01bcefcbfe6bd3df070c04cec7e", observation: "최소 사용자 경로, 네 모드, 안전장치와 전체 처리 흐름을 찾을 수 있다."}
+ contributor:
+ outcome: PASS
+ evidence:
+ - {artifact: README.candidate.md, section-id: document, line-start: 158, line-end: 191, content-hash: "sha256:5dd4d4f75a0efbc470683bc6c995acdf3084d7416dccd012ff6bd7fe47b0b4f7", observation: "개발 설치와 테스트 명령, 구현·규칙·테스트 위치를 찾을 수 있다."}
+findings:
+ - id: R-001
+ severity: major
+ category: technical-correctness
+ subject: C-PROOF-001
+ section: proof
+ message: 적용 완료 과잉 주장을 제거하고 검토 통과 사실만 남겼다.
+ evidence:
+ - {artifact: README.candidate.md, section-id: proof, line-start: 34, line-end: 35, content-hash: "sha256:dedc8a48d038f220392c136a4e6cf0544c53d12f6f2572744cf4f936892f4517", observation: "현재 문장은 F-PROOF-001이 기록한 검토 통과 상태만 주장한다."}
+ route-to: README_DRAFTED
+ status: resolved
diff --git a/runs/readme-harness/20260720-public-readme-r2/review.md b/runs/readme-harness/20260720-public-readme-r2/review.md
new file mode 100644
index 0000000..10cb47a
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme-r2/review.md
@@ -0,0 +1,22 @@
+# README quality review
+
+Verdict: **PASS** — 90/100
+
+## Dimension scores
+
+- project-specificity: 5/5
+- reader-journey: 5/5
+- technical-explanation: 4/5
+- task-usability: 4/5
+- prose-clarity: 4/5
+- visual-judgment: 5/5
+
+## Reader simulations
+
+- 30-seconds: PASS
+- 5-minutes: PASS
+- contributor: PASS
+
+## Findings
+
+- [major] R-001 (proof): 적용 완료 과잉 주장을 제거하고 검토 통과 사실만 남겼다.
diff --git a/runs/readme-harness/20260720-public-readme-r2/run-manifest.json b/runs/readme-harness/20260720-public-readme-r2/run-manifest.json
new file mode 100644
index 0000000..32f61f1
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme-r2/run-manifest.json
@@ -0,0 +1,12 @@
+{
+ "schema-version": 1,
+ "run-id": "20260720-public-readme-r2",
+ "repo-id": "readme-harness",
+ "mode": "bootstrap",
+ "target-repository": "/home/donghyeon/workspace/ai-tool/readme-harness",
+ "harness-version": "0.1.0",
+ "started-at": null,
+ "tool-adapter": "codex",
+ "input-hashes": {},
+ "usage": {}
+}
\ No newline at end of file
diff --git a/runs/readme-harness/20260720-public-readme-r2/state.json b/runs/readme-harness/20260720-public-readme-r2/state.json
new file mode 100644
index 0000000..0a3373e
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme-r2/state.json
@@ -0,0 +1,567 @@
+{
+ "schema-version": 1,
+ "mode": "bootstrap",
+ "current": "READY_FOR_APPLY",
+ "history": [
+ {
+ "state": "INITIALIZED"
+ },
+ {
+ "state": "INPUT_CAPTURED",
+ "gates": [
+ {
+ "name": "request",
+ "ok": true,
+ "warnings": [],
+ "data": null
+ }
+ ]
+ },
+ {
+ "state": "REPOSITORY_SNAPSHOTTED",
+ "gates": [
+ {
+ "name": "snapshot",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "diff-hash": "sha256:77b1a19a536615064a4894d23c78b2e7aa54a9ef4cf13bad194ae40565407951"
+ }
+ }
+ ]
+ },
+ {
+ "state": "FACTS_EXTRACTED",
+ "gates": [
+ {
+ "name": "facts",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "fact_ids": [
+ "F-PROJECT-001",
+ "F-RUNTIME-001",
+ "F-TOOL-PROFILE-001",
+ "F-MODES-001",
+ "F-WORKFLOW-001",
+ "F-AUDIT-001",
+ "F-REFRESH-001",
+ "F-SECTION-001",
+ "F-VERIFY-001",
+ "F-AUTHORITY-001",
+ "F-CLAIM-001",
+ "F-PROSE-001",
+ "F-VISUAL-001",
+ "F-OUTPUT-001",
+ "F-APPLY-001",
+ "F-BENCH-001",
+ "F-PROOF-001",
+ "F-CODEX-001",
+ "F-RUN-LAYOUT-001",
+ "F-REPO-LAYOUT-001",
+ "F-SAFETY-001"
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "state": "PROJECT_PROFILED",
+ "gates": [
+ {
+ "name": "profile",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "profile": "tool"
+ }
+ }
+ ]
+ },
+ {
+ "state": "README_PLANNED",
+ "gates": [
+ {
+ "name": "brief",
+ "ok": true,
+ "warnings": [],
+ "data": null
+ },
+ {
+ "name": "outline",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "section_ids": [
+ "overview",
+ "proof",
+ "quick-start",
+ "usage",
+ "safeguards",
+ "workflow",
+ "inputs",
+ "development",
+ "documentation",
+ "limitations"
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "state": "README_DRAFTED",
+ "gates": [
+ {
+ "name": "conformance",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "sections": [
+ "overview",
+ "proof",
+ "quick-start",
+ "usage",
+ "safeguards",
+ "workflow",
+ "inputs",
+ "development",
+ "documentation",
+ "limitations"
+ ]
+ }
+ },
+ {
+ "name": "claim_map",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "claims": [
+ "C-PROJECT-001",
+ "C-OUTPUT-001",
+ "C-CODEX-001",
+ "C-XTOOL-001",
+ "C-PROOF-001",
+ "C-INVOCATION-001",
+ "C-RESULTS-001",
+ "C-NO-AUTO-APPLY-001",
+ "C-APPLY-CHECK-001",
+ "C-MODE-BOOTSTRAP-001",
+ "C-MODE-AUDIT-001",
+ "C-MODE-REFRESH-001",
+ "C-MODE-SECTION-001",
+ "C-SOURCE-SPLIT-001",
+ "C-FACT-TRACE-001",
+ "C-PRESERVE-001",
+ "C-CONFLICT-001",
+ "C-SECRET-PATH-001",
+ "C-STALE-001",
+ "C-WORKFLOW-001",
+ "C-REWORK-001",
+ "C-REQUEST-001",
+ "C-RUN-DIR-001",
+ "C-DEV-PREREQ-001",
+ "C-LAYOUT-001",
+ "C-WRITING-LIMIT-001",
+ "C-VERIFY-LIMIT-001",
+ "C-XTOOL-LIMIT-001",
+ "C-BENCH-LIMIT-001"
+ ],
+ "derived-statements": {
+ "C-PROJECT-001": "저장소에서 확인한 사실과 사용자가 정한 요구를 바탕으로 README 초안을 만드는 도구입니다.",
+ "C-OUTPUT-001": "명령·링크·경로를 검사한 뒤, 사람이 검토하고 적용할 수 있는 패치를 생성합니다.",
+ "C-CODEX-001": "현재 지원하는 작성·검증 흐름은 Codex용입니다.",
+ "C-XTOOL-001": "Claude와 Antigravity에서 같은 동작을 하는지는 아직 미검증 상태입니다.",
+ "C-PROOF-001": "아래 내용은 검토와 적용을 마친 이전 실행의 패치 일부입니다.",
+ "C-INVOCATION-001": "현재 실행 경로는 Codex 작업 공간의 `requirement-driven-readme` 스킬입니다.",
+ "C-RESULTS-001": "\n작업 뒤 확인할 파일은 `README.generated.md`와 `README.patch`입니다.",
+ "C-NO-AUTO-APPLY-001": "대상 `README.md`는 적용 명령을 실행하기 전까지 바뀌지 않습니다.",
+ "C-APPLY-CHECK-001": "적용 직전에 생성 파일과 대상 README, 저장소 기준 정보가 바뀌지 않았는지 다시 확인합니다.",
+ "C-MODE-BOOTSTRAP-001": "새 README 작성과 전면 재작성의 기본 선택은 `bootstrap`입니다.",
+ "C-MODE-AUDIT-001": "현재 README의 문제만 찾는 작업은 `audit`입니다.",
+ "C-MODE-REFRESH-001": "사람이 작성한 영역을 보존하는 갱신은 `refresh`입니다.",
+ "C-MODE-SECTION-001": "한 섹션과 영향을 받는 검사 결과의 갱신은 `section-update`입니다.",
+ "C-SOURCE-SPLIT-001": "코드에서 확인한 사실과 사용자가 정한 문서 요구는 따로 둡니다.",
+ "C-FACT-TRACE-001": "명령, 경로, 버전처럼 오류 영향이 큰 정보는 근거 파일과 연결합니다.",
+ "C-PRESERVE-001": "갱신 작업은 보호 영역과 마커 밖의 사람이 작성한 문장을 보존합니다.",
+ "C-CONFLICT-001": "사람이 고친 영역과 새 초안이 충돌하면 자동 병합과 적용이 중단됩니다.",
+ "C-SECRET-PATH-001": "비밀 값이나 저장소 밖 경로가 발견되면 패치를 준비하지 않습니다.",
+ "C-STALE-001": "검토 뒤 저장소나 생성 파일이 바뀌어도 적용을 중단합니다.",
+ "C-WORKFLOW-001": "사용자 요청 → 저장소 사실 확인 → README 작성 → 명령·링크·문장 검사 → 독립 검토 → 패치 확인 → 직접 적용",
+ "C-REWORK-001": "검사에서 문제가 나오면 해당 내용을 맡은 단계부터 다시 작성합니다.",
+ "C-REQUEST-001": "`readme-request.yaml`에는 독자, 목적, 언어, 보존 범위와 그림 정책을 적습니다.",
+ "C-RUN-DIR-001": "각 작업의 파일은 `runs//` 아래에 따로 저장됩니다.",
+ "C-DEV-PREREQ-001": "개발에는 Python 3.12 이상이 필요하며, 개발 의존성에는 `pytest`가 포함됩니다.",
+ "C-LAYOUT-001": "주요 구현은 `src/readme_harness`, 규칙과 워크플로는 `.agents`, 테스트는 `tests`에 있습니다.",
+ "C-WRITING-LIMIT-001": "- README 문장은 모델이 작성하고 검사 스크립트는 준비된 파일을 확인합니다.",
+ "C-VERIFY-LIMIT-001": "- 실행 기록이 없는 명령은 정적으로만 확인합니다.",
+ "C-XTOOL-LIMIT-001": "- `Claude`와 `Antigravity`에서 `Codex`와 같은 동작을 하는지는 아직 검증하지 않았습니다.",
+ "C-BENCH-LIMIT-001": "- 블라인드 품질 비교는 아직 실행하지 않았으며 더 좋은 결과를 낸다고 주장하지 않습니다."
+ }
+ }
+ }
+ ]
+ },
+ {
+ "state": "VISUALS_PLANNED",
+ "gates": [
+ {
+ "name": "visual_plan",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "visuals": [
+ "reviewed-patch-preview"
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "state": "STRUCTURALLY_VALIDATED",
+ "gates": [
+ {
+ "name": "github_markdown",
+ "ok": true,
+ "warnings": [],
+ "data": null
+ },
+ {
+ "name": "reader_prose",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "schema-version": 1,
+ "policy-id": "korean-reader-prose-v1",
+ "language": "ko-KR",
+ "applicable": true,
+ "scope": "candidate",
+ "state": "PASS",
+ "summary": {
+ "errors": 0,
+ "warnings": 0,
+ "sentences": 52,
+ "prose-characters": 1196,
+ "hangul-characters": 1007
+ },
+ "findings": []
+ }
+ }
+ ]
+ },
+ {
+ "state": "TECHNICALLY_VERIFIED",
+ "gates": [
+ {
+ "name": "verify",
+ "ok": true,
+ "warnings": [
+ "manual verification required: python3 -m pip install -e \".[dev]\" (unsupported-static-verifier)",
+ "manual verification required: python3 -m pytest -q (unsupported-static-verifier)"
+ ],
+ "data": {
+ "schema-version": 1,
+ "state": "PASS_WITH_MANUAL",
+ "verification-level": "static",
+ "execution-verified": false,
+ "checks": {
+ "commands": {
+ "total": 3,
+ "verified": 1,
+ "manual-required": 2,
+ "failed": 0
+ },
+ "paths": {
+ "total": 7,
+ "verified": 7,
+ "failed": 0
+ },
+ "anchors": {
+ "total": 0,
+ "verified": 0,
+ "failed": 0
+ },
+ "readme-contracts": {
+ "total": 0,
+ "verified": 0,
+ "failed": 0
+ }
+ },
+ "failures": [],
+ "limitations": [
+ "manual verification required: python3 -m pip install -e \".[dev]\" (unsupported-static-verifier)",
+ "manual verification required: python3 -m pytest -q (unsupported-static-verifier)"
+ ]
+ }
+ },
+ {
+ "name": "secret_scan",
+ "ok": true,
+ "warnings": [],
+ "data": null
+ }
+ ]
+ },
+ {
+ "state": "README_PLANNED",
+ "from": "TECHNICALLY_VERIFIED",
+ "resumed": true,
+ "resume-from": "README_DRAFTED",
+ "invalidated": [
+ "README.candidate.md",
+ "claim-map.yaml",
+ "visual-plan.yaml",
+ "prose-report.json",
+ "verification.json",
+ "review-findings.yaml"
+ ]
+ },
+ {
+ "state": "README_DRAFTED",
+ "gates": [
+ {
+ "name": "conformance",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "sections": [
+ "overview",
+ "proof",
+ "quick-start",
+ "usage",
+ "safeguards",
+ "workflow",
+ "inputs",
+ "development",
+ "documentation",
+ "limitations"
+ ]
+ }
+ },
+ {
+ "name": "claim_map",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "claims": [
+ "C-PROJECT-001",
+ "C-OUTPUT-001",
+ "C-CODEX-001",
+ "C-XTOOL-001",
+ "C-PROOF-001",
+ "C-INVOCATION-001",
+ "C-RESULTS-001",
+ "C-NO-AUTO-APPLY-001",
+ "C-APPLY-CHECK-001",
+ "C-MODE-BOOTSTRAP-001",
+ "C-MODE-AUDIT-001",
+ "C-MODE-REFRESH-001",
+ "C-MODE-SECTION-001",
+ "C-SOURCE-SPLIT-001",
+ "C-FACT-TRACE-001",
+ "C-PRESERVE-001",
+ "C-CONFLICT-001",
+ "C-SECRET-PATH-001",
+ "C-STALE-001",
+ "C-WORKFLOW-001",
+ "C-REWORK-001",
+ "C-REQUEST-001",
+ "C-RUN-DIR-001",
+ "C-DEV-PREREQ-001",
+ "C-LAYOUT-001",
+ "C-WRITING-LIMIT-001",
+ "C-VERIFY-LIMIT-001",
+ "C-XTOOL-LIMIT-001",
+ "C-BENCH-LIMIT-001"
+ ],
+ "derived-statements": {
+ "C-PROJECT-001": "저장소에서 확인한 사실과 사용자가 정한 요구를 바탕으로 README 초안을 만드는 도구입니다.",
+ "C-OUTPUT-001": "명령·링크·경로를 검사한 뒤, 사람이 검토하고 적용할 수 있는 패치를 생성합니다.",
+ "C-CODEX-001": "현재 지원하는 작성·검증 흐름은 Codex용입니다.",
+ "C-XTOOL-001": "Claude와 Antigravity에서 같은 동작을 하는지는 아직 미검증 상태입니다.",
+ "C-PROOF-001": "아래 내용은 검토를 통과한 이전 실행의 패치 일부입니다.",
+ "C-INVOCATION-001": "현재 실행 경로는 Codex 작업 공간의 `requirement-driven-readme` 스킬입니다.",
+ "C-RESULTS-001": "\n작업 뒤 확인할 파일은 `README.generated.md`와 `README.patch`입니다.",
+ "C-NO-AUTO-APPLY-001": "대상 `README.md`는 적용 명령을 실행하기 전까지 바뀌지 않습니다.",
+ "C-APPLY-CHECK-001": "적용 직전에 생성 파일과 대상 README, 저장소 기준 정보가 바뀌지 않았는지 다시 확인합니다.",
+ "C-MODE-BOOTSTRAP-001": "새 README 작성과 전면 재작성의 기본 선택은 `bootstrap`입니다.",
+ "C-MODE-AUDIT-001": "현재 README의 문제만 찾는 작업은 `audit`입니다.",
+ "C-MODE-REFRESH-001": "사람이 작성한 영역을 보존하는 갱신은 `refresh`입니다.",
+ "C-MODE-SECTION-001": "한 섹션과 영향을 받는 검사 결과의 갱신은 `section-update`입니다.",
+ "C-SOURCE-SPLIT-001": "코드에서 확인한 사실과 사용자가 정한 문서 요구는 따로 둡니다.",
+ "C-FACT-TRACE-001": "명령, 경로, 버전처럼 오류 영향이 큰 정보는 근거 파일과 연결합니다.",
+ "C-PRESERVE-001": "갱신 작업은 보호 영역과 마커 밖의 사람이 작성한 문장을 보존합니다.",
+ "C-CONFLICT-001": "사람이 고친 영역과 새 초안이 충돌하면 자동 병합과 적용이 중단됩니다.",
+ "C-SECRET-PATH-001": "비밀 값이나 저장소 밖 경로가 발견되면 패치를 준비하지 않습니다.",
+ "C-STALE-001": "검토 뒤 저장소나 생성 파일이 바뀌어도 적용을 중단합니다.",
+ "C-WORKFLOW-001": "사용자 요청 → 저장소 사실 확인 → README 작성 → 명령·링크·문장 검사 → 독립 검토 → 패치 확인 → 직접 적용",
+ "C-REWORK-001": "검사에서 문제가 나오면 해당 내용을 맡은 단계부터 다시 작성합니다.",
+ "C-REQUEST-001": "`readme-request.yaml`에는 독자, 목적, 언어, 보존 범위와 그림 정책을 적습니다.",
+ "C-RUN-DIR-001": "각 작업의 파일은 `runs//` 아래에 따로 저장됩니다.",
+ "C-DEV-PREREQ-001": "개발에는 Python 3.12 이상이 필요하며, 개발 의존성에는 `pytest`가 포함됩니다.",
+ "C-LAYOUT-001": "주요 구현은 `src/readme_harness`, 규칙과 워크플로는 `.agents`, 테스트는 `tests`에 있습니다.",
+ "C-WRITING-LIMIT-001": "- README 문장은 모델이 작성하고 검사 스크립트는 준비된 파일을 확인합니다.",
+ "C-VERIFY-LIMIT-001": "- 실행 기록이 없는 명령은 정적으로만 확인합니다.",
+ "C-XTOOL-LIMIT-001": "- `Claude`와 `Antigravity`에서 `Codex`와 같은 동작을 하는지는 아직 검증하지 않았습니다.",
+ "C-BENCH-LIMIT-001": "- 블라인드 품질 비교는 아직 실행하지 않았으며 더 좋은 결과를 낸다고 주장하지 않습니다."
+ }
+ }
+ }
+ ]
+ },
+ {
+ "state": "VISUALS_PLANNED",
+ "gates": [
+ {
+ "name": "visual_plan",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "visuals": [
+ "reviewed-patch-preview"
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "state": "STRUCTURALLY_VALIDATED",
+ "gates": [
+ {
+ "name": "github_markdown",
+ "ok": true,
+ "warnings": [],
+ "data": null
+ },
+ {
+ "name": "reader_prose",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "schema-version": 1,
+ "policy-id": "korean-reader-prose-v1",
+ "language": "ko-KR",
+ "applicable": true,
+ "scope": "candidate",
+ "state": "PASS",
+ "summary": {
+ "errors": 0,
+ "warnings": 0,
+ "sentences": 52,
+ "prose-characters": 1194,
+ "hangul-characters": 1005
+ },
+ "findings": []
+ }
+ }
+ ]
+ },
+ {
+ "state": "TECHNICALLY_VERIFIED",
+ "gates": [
+ {
+ "name": "verify",
+ "ok": true,
+ "warnings": [
+ "manual verification required: python3 -m pip install -e \".[dev]\" (unsupported-static-verifier)",
+ "manual verification required: python3 -m pytest -q (unsupported-static-verifier)"
+ ],
+ "data": {
+ "schema-version": 1,
+ "state": "PASS_WITH_MANUAL",
+ "verification-level": "static",
+ "execution-verified": false,
+ "checks": {
+ "commands": {
+ "total": 3,
+ "verified": 1,
+ "manual-required": 2,
+ "failed": 0
+ },
+ "paths": {
+ "total": 7,
+ "verified": 7,
+ "failed": 0
+ },
+ "anchors": {
+ "total": 0,
+ "verified": 0,
+ "failed": 0
+ },
+ "readme-contracts": {
+ "total": 0,
+ "verified": 0,
+ "failed": 0
+ }
+ },
+ "failures": [],
+ "limitations": [
+ "manual verification required: python3 -m pip install -e \".[dev]\" (unsupported-static-verifier)",
+ "manual verification required: python3 -m pytest -q (unsupported-static-verifier)"
+ ]
+ }
+ },
+ {
+ "name": "secret_scan",
+ "ok": true,
+ "warnings": [],
+ "data": null
+ }
+ ]
+ },
+ {
+ "state": "QUALITY_REVIEWED",
+ "gates": [
+ {
+ "name": "review",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "verdict": "PASS",
+ "score": 90,
+ "findings": [
+ {
+ "id": "R-001",
+ "severity": "major",
+ "category": "technical-correctness",
+ "subject": "C-PROOF-001",
+ "section": "proof",
+ "message": "적용 완료 과잉 주장을 제거하고 검토 통과 사실만 남겼다.",
+ "evidence": [
+ {
+ "artifact": "README.candidate.md",
+ "section-id": "proof",
+ "line-start": 34,
+ "line-end": 35,
+ "content-hash": "sha256:dedc8a48d038f220392c136a4e6cf0544c53d12f6f2572744cf4f936892f4517",
+ "observation": "현재 문장은 F-PROOF-001이 기록한 검토 통과 상태만 주장한다."
+ }
+ ],
+ "route-to": "README_DRAFTED",
+ "status": "resolved"
+ }
+ ],
+ "report-valid": true
+ }
+ }
+ ]
+ },
+ {
+ "state": "READY_FOR_APPLY",
+ "gates": []
+ }
+ ],
+ "rework": {
+ "iterations": 1,
+ "findings": {
+ "sha256:9c9a7da5c0916b83": {
+ "attempts": 1,
+ "status": "open",
+ "latest-id": "R-001"
+ }
+ }
+ },
+ "reasons": [
+ "R-001"
+ ],
+ "resume-from": "README_DRAFTED"
+}
\ No newline at end of file
diff --git a/runs/readme-harness/20260720-public-readme-r2/verification.json b/runs/readme-harness/20260720-public-readme-r2/verification.json
new file mode 100644
index 0000000..f832c6b
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme-r2/verification.json
@@ -0,0 +1,34 @@
+{
+ "schema-version": 1,
+ "state": "PASS_WITH_MANUAL",
+ "verification-level": "static",
+ "execution-verified": false,
+ "checks": {
+ "commands": {
+ "total": 3,
+ "verified": 1,
+ "manual-required": 2,
+ "failed": 0
+ },
+ "paths": {
+ "total": 7,
+ "verified": 7,
+ "failed": 0
+ },
+ "anchors": {
+ "total": 0,
+ "verified": 0,
+ "failed": 0
+ },
+ "readme-contracts": {
+ "total": 0,
+ "verified": 0,
+ "failed": 0
+ }
+ },
+ "failures": [],
+ "limitations": [
+ "manual verification required: python3 -m pip install -e \".[dev]\" (unsupported-static-verifier)",
+ "manual verification required: python3 -m pytest -q (unsupported-static-verifier)"
+ ]
+}
\ No newline at end of file
diff --git a/runs/readme-harness/20260720-public-readme-r2/visual-plan.yaml b/runs/readme-harness/20260720-public-readme-r2/visual-plan.yaml
new file mode 100644
index 0000000..ebce2ed
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme-r2/visual-plan.yaml
@@ -0,0 +1,26 @@
+schema-version: 1
+visuals:
+ - id: reviewed-patch-preview
+ section: proof
+ type: artifact-showcase
+ purpose: 검토를 통과한 실제 README 패치의 핵심 변경을 보여 줍니다.
+ placeholder-text: 영문 중심 소개가 한국어 사용자 중심 소개로 바뀐 실제 diff 일부
+ must-show: [변경 전 영문 소개, 변경 후 한국어 소개]
+ relationships: []
+ emphasize: [입력 문서와 생성 문서의 차이]
+ avoid: [저장소 근거가 없는 품질 우월성 표현]
+ require-provenance: true
+ placement: {after-section-id: proof}
+ accessibility:
+ alt-text: 영문 소개를 한국어 사용자 중심 소개로 바꾼 README 패치 미리보기
+ production:
+ format: diff
+ status: source-created
+ source-path: examples/readme-showcase/README.patch
+ source-hash: sha256:3f930c70600d6530afa4a6b486be7f467f8650d28f4f2b057b889ef97f545e19
+ asset:
+ path: examples/readme-showcase/README.patch
+ provenance: examples/readme-showcase/provenance.yaml
+ source-run: runs/readme-harness/20260720-review-remediation
+ sha256: sha256:3f930c70600d6530afa4a6b486be7f467f8650d28f4f2b057b889ef97f545e19
+ caption: 검토를 통과한 이전 README 실행의 실제 패치 일부입니다.
diff --git a/runs/readme-harness/20260720-public-readme/readme-request.yaml b/runs/readme-harness/20260720-public-readme/readme-request.yaml
new file mode 100644
index 0000000..1035807
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme/readme-request.yaml
@@ -0,0 +1,78 @@
+schema-version: 1
+target:
+ repository: /home/donghyeon/workspace/ai-tool/readme-harness
+ readme-path: README.md
+mode: refresh
+profile-override: tool
+project-intent:
+ purpose: 저장소에서 확인한 사실과 사용자가 정한 요구를 바탕으로 README 초안과 검토용 패치를 만드는 도구를 설명한다.
+ positioning: 사용자 경로를 먼저 보여 주고, 명령·경로·문장 근거 검사와 사람 작성 내용 보존은 필요한 수준에서만 설명한다.
+ maturity: 현재 Codex용 작성·검증 흐름을 지원하며 Claude와 Antigravity의 동일 동작은 아직 검증하지 않았다.
+audience:
+ primary:
+ - 저장소 README를 새로 만들거나 안전하게 갱신하려는 개발자
+ secondary:
+ - 하네스 검사와 프로파일을 확장하는 기여자
+reader-actions:
+ - 첫 두 문장에서 어떤 결과를 만드는 도구인지 판단한다.
+ - Codex에 README 작업을 요청하고 생성된 README와 패치를 확인한다.
+ - 작업 목적에 맞는 모드를 고른다.
+ - 검토한 패치만 명시적으로 적용한다.
+ - 개발 환경과 테스트 방법은 별도의 개발 절에서 찾는다.
+content-policy:
+ language: ko-KR
+ tone: 독자 행동을 먼저 밝히는 직접적인 기술 설명체
+ target-length: medium
+ preserve-existing-copy: true
+ detail-docs-policy: summary-and-link
+visual-policy:
+ mode: when-useful
+ max-visuals: 1
+ preferred-formats:
+ - diff
+ placeholder-format: HTML 주석 기반 제작 사양
+terminology-policy:
+ exact-identifiers: []
+ explain-on-first-use: {}
+ internal-only:
+ family: 작업 담당 방식
+ fan-out: 여러 담당자가 나눠 검토
+ collapse: 한 담당자가 맡아 처리
+ concrete worker: 실제 변경 담당자
+ verification family: 검증 담당 역할
+ route-to: 다시 작성할 지점
+public-surface-terms:
+ allowed:
+ - bootstrap
+ - audit
+ - refresh
+ - section-update
+ - readme-request.yaml
+ - README.generated.md
+ - README.patch
+ - requirement-driven-readme
+ explain-on-first-use: {}
+ docs-only:
+ - QUALITY_REVIEWED
+ - READY_FOR_APPLY
+ - claim-map.yaml
+ - visual-plan.yaml
+ - review-findings.yaml
+ - quality-manifest.yaml
+must-include:
+ - 한 문장 설명과 Codex 지원 범위
+ - 실제 검토를 통과한 패치 미리보기와 원본 파일 링크
+ - Codex 스킬 요청부터 생성 파일 확인, 성공 확인, 명시적 적용까지의 기본 사용자 경로
+ - bootstrap을 기본 경로로 두고 audit, refresh, section-update를 보조 경로로 설명
+ - 코드에서 확인한 사실, 사람 작성 내용 보존, 자동 적용 금지, 변경·비밀 값 차단 요약
+ - 사용자 입력과 생성 파일을 세 개에서 네 개 수준으로 요약
+ - 개발 환경 설치와 전체 테스트를 사용자 경로 뒤의 개발 절에 배치
+ - 아키텍처, 시각 자료, 상태, 사용량, 품질 비교 상세 문서 링크
+ - 현재 Codex 지원과 다른 도구의 동일 동작 미검증 한계
+must-exclude:
+ - 빠른 시작의 첫 행동으로 테스트나 개발 의존성 설치를 제시하는 구성
+ - 공개 README에서 내부 상태 이름, 내부 결과 파일, 게이트 계약을 설명하는 문장
+ - 저장소 근거 없는 성능·품질 우월성 주장
+ - 한 주장 마커가 여러 사실 문장을 덮는 구성
+ - 제품 결과보다 먼저 나오는 내부 구조도
+protected-sections: []
diff --git a/runs/readme-harness/20260720-public-readme/repository-snapshot.json b/runs/readme-harness/20260720-public-readme/repository-snapshot.json
new file mode 100644
index 0000000..c4f3f2f
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme/repository-snapshot.json
@@ -0,0 +1,7 @@
+{
+ "git-sha": "636617ccd9f20440f21339f808557c096b55fec2",
+ "dirty": true,
+ "diff-hash": "sha256:77b1a19a536615064a4894d23c78b2e7aa54a9ef4cf13bad194ae40565407951",
+ "scanned-at": null,
+ "file-count": 231
+}
\ No newline at end of file
diff --git a/runs/readme-harness/20260720-public-readme/run-manifest.json b/runs/readme-harness/20260720-public-readme/run-manifest.json
new file mode 100644
index 0000000..b0a2362
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme/run-manifest.json
@@ -0,0 +1,12 @@
+{
+ "schema-version": 1,
+ "run-id": "20260720-public-readme",
+ "repo-id": "readme-harness",
+ "mode": "refresh",
+ "target-repository": "/home/donghyeon/workspace/ai-tool/readme-harness",
+ "harness-version": "0.1.0",
+ "started-at": null,
+ "tool-adapter": "codex",
+ "input-hashes": {},
+ "usage": {}
+}
\ No newline at end of file
diff --git a/runs/readme-harness/20260720-public-readme/state.json b/runs/readme-harness/20260720-public-readme/state.json
new file mode 100644
index 0000000..c301b88
--- /dev/null
+++ b/runs/readme-harness/20260720-public-readme/state.json
@@ -0,0 +1,38 @@
+{
+ "schema-version": 1,
+ "mode": "refresh",
+ "current": "REPOSITORY_SNAPSHOTTED",
+ "history": [
+ {
+ "state": "INITIALIZED"
+ },
+ {
+ "state": "INPUT_CAPTURED",
+ "gates": [
+ {
+ "name": "request",
+ "ok": true,
+ "warnings": [],
+ "data": null
+ }
+ ]
+ },
+ {
+ "state": "REPOSITORY_SNAPSHOTTED",
+ "gates": [
+ {
+ "name": "snapshot",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "diff-hash": "sha256:77b1a19a536615064a4894d23c78b2e7aa54a9ef4cf13bad194ae40565407951"
+ }
+ }
+ ]
+ }
+ ],
+ "rework": {
+ "iterations": 0,
+ "findings": {}
+ }
+}
\ No newline at end of file
diff --git a/runs/readme-harness/20260720-review-remediation/README.candidate.md b/runs/readme-harness/20260720-review-remediation/README.candidate.md
new file mode 100644
index 0000000..b870a53
--- /dev/null
+++ b/runs/readme-harness/20260720-review-remediation/README.candidate.md
@@ -0,0 +1,224 @@
+# README Harness
+
+이 하네스는 저장소의 실제 코드와 사용 목적을 바탕으로 문서 후보를 만들고,
+명령·경로·근거를 검사한 뒤 검토 가능한 패치로 제공합니다.
+
+- 새 README 작성
+- 기존 문서 점검
+- 사람 작성 영역을 보존한 갱신
+- 특정 섹션과 관련 검증 산출물의 재생성
+- 검토 후 별도로 실행하는 적용
+
+
+## 무엇을 만드는가
+
+README를 새로 만들거나 기존 문서를 안전하게 갱신하려는 개발자를 위한 도구입니다.
+
+`bootstrap`, `audit`, `refresh`, `section-update` 네 모드를 구현했습니다.
+
+저장소 근거와 사용자 요구를 분리해 읽고, 고위험 사실을 근거에 연결합니다. 그림을
+넣기로 했다면 실제 소스나 자산까지 확인하고, 품질 심사는 원문의 줄과 해시에 묶인
+근거를 사용합니다. 패치 준비가 끝나도 대상 `README.md`는 자동으로 바뀌지 않습니다.
+
+
+결정론적 Codex 경로는 구현됐습니다. 후보 문장 작성은 모델 파이프라인이 담당하며,
+다른 도구와의 런타임 동등성은 Phase 4 검증 전까지 보장하지 않습니다.
+
+
+
+## 설치
+
+`Python` 3.12 이상이 필요합니다.
+런타임 의존성은 `jsonschema`와 `PyYAML`입니다.
+개발 의존성은 `pytest`입니다.
+
+저장소 루트에서 개발 의존성을 포함한 편집 가능 설치를 실행합니다.
+
+```bash
+python3 -m pip install -e ".[dev]"
+```
+
+이 설치 명령은 프로젝트 선언에서 확인했지만, 현재 작업에서는 새 가상환경 설치까지
+실행해 증명하지 않았습니다.
+
+
+## 빠른 시작
+
+먼저 전체 테스트를 실행합니다.
+
+```bash
+python3 -m pytest -q
+```
+
+종료 코드 0과 실패 항목 없는 통과 요약이 성공 기준입니다. 이 후보는 아직 현재
+README를 바꾸지 않았으므로 최종 전체 결과는 명시적 적용 뒤 다시 확인합니다.
+
+자체 README 테스트는 이 명령을 최소 실행 경로로 요구합니다. 다른 운영체제와 새
+가상환경의 동일한 결과까지 보장하는 계약은 아닙니다.
+
+이 프로젝트는 명령 하나로 문서를 완성하는 독립 실행 도구가 아닙니다. Codex 작업 공간에서
+`requirement-driven-readme` 스킬로 대상 저장소의 `bootstrap` 실행을 요청하면 작성
+역할이 사용자 요구, 저장소 근거, 개요, 후보, 주장 지도, 그림 계획과 품질 심사
+산출물을 준비합니다.
+
+대상 저장소용 실행 디렉터리를 만듭니다.
+
+```bash
+python3 .agents/skills/requirement-driven-readme/scripts/init_run.py --repo-id demo --run-id first --mode bootstrap --target-repository /path/to/repository --tool-adapter codex
+```
+
+이 명령은 `runs/demo/first`에 상태와 실행 매니페스트를 초기화합니다.
+
+
+실행 디렉터리에 `readme-request.yaml`, `repository-facts.yaml`, `readme-brief.yaml`,
+`readme-outline.yaml`, `README.candidate.md`, `claim-map.yaml`, `visual-plan.yaml`,
+`review-findings.yaml`이 준비되면 모든 결정론적 게이트를 재생합니다.
+
+```bash
+python3 .agents/skills/requirement-driven-readme/scripts/run_bootstrap.py --run-dir runs/demo/first --repo /path/to/repository
+```
+
+드라이버는 후보를 새로 쓰지 않고 준비된 산출물을 `QUALITY_REVIEWED`까지
+검증합니다.
+
+
+## 사용 모드
+
+| 작업 | 모드 | 결과 |
+|---|---|---|
+| README가 없거나 전면 재작성 | `bootstrap` | 검증된 후보와 적용 준비용 패치 |
+| 기존 문서의 결함만 점검 | `audit` | 감사 결과와 검증 보고서, 후보·패치 없음 |
+| 사람 작성 영역을 보존한 갱신 | `refresh` | 3방향 병합과 병합본 전체 재검증 |
+| 한 섹션과 파급 산출물 갱신 | `section-update` | 관련 산출물 무효화 후 갱신 검증 재실행 |
+
+네 모드는 요청 스키마에 선언되어 있고 각 흐름의 상태·게이트 계약이 구현되어
+있습니다.
+
+
+## 요청 API, 설정과 산출물
+
+`readme-request.yaml`은 독자, 언어, 길이, 보존 범위, 공개 용어, 그림 정책을
+정합니다. 기술 사실은 `repository-facts.yaml`에 저장하고, 각 실행은
+`runs//` 아래에서 격리합니다.
+
+어댑터가 제공하는 단계별 모델 사용량은 실행 매니페스트에 누적합니다. 제공되지
+않은 값은 0으로 추정하지 않습니다.
+
+대표 산출물은 다음 순서로 이어집니다.
+
+```text
+readme-brief.yaml + readme-outline.yaml
+README.candidate.md + claim-map.yaml + visual-plan.yaml
+prose-report.json + verification.json + review-findings.yaml
+quality-manifest.yaml
+README.generated.md + README.patch + apply-manifest.yaml
+```
+
+품질 검토를 통과한 뒤 다음 명령으로 패치를 준비합니다.
+
+```bash
+python3 .agents/skills/requirement-driven-readme/scripts/generate_patch.py --run-dir runs/demo/first --repo /path/to/repository
+```
+
+이 단계는 `README.generated.md`, `README.patch`, `apply-manifest.yaml`을 만들고
+상태를 `READY_FOR_APPLY`로 전진시킵니다.
+
+검토가 끝난 패치만 별도 명령으로 적용합니다.
+
+```bash
+python3 .agents/skills/requirement-driven-readme/scripts/apply_patch.py --run-dir runs/demo/first --repo /path/to/repository
+```
+
+적용 직전에 후보·저장소·대상 README 해시와 경로 경계를 다시 검사합니다.
+
+
+
+## 동작 방식
+
+사용자 요구는 독자 흐름과 공개 용어, 그림 결정을 만듭니다. 대상 저장소에서는
+근거와 프로젝트 유형을 수집합니다. 두 입력이 합쳐진 후보와 시각 자료는 결정론적
+게이트와 독립 품질 심사를 통과해야 패치가 됩니다.
+
+```mermaid
+flowchart LR
+ T[Codex / Claude / Antigravity] --> O[실행 조정]
+ U[사용자 요구] --> P[독자 흐름·용어·그림 결정]
+ R[대상 저장소] --> E[근거 수집·프로젝트 분류]
+ O --> E
+ O --> P
+ E --> P
+ P --> W[README 작성]
+ P --> V[그림 소스·자산 생성]
+ W --> G[근거·명령·경로·문체 검사]
+ V --> G
+ G --> Q[독립 품질 심사]
+ Q -->|수정 필요| P
+ Q -->|통과| A[패치 준비·명시적 적용]
+ H[(해시 기반 실행 산출물)] --- E
+ H --- P
+ H --- G
+ H --- A
+```
+
+
+
+구성요소 책임과 컨텍스트 경계는 [아키텍처 문서](docs/architecture.md)에,
+모드별 전이는 [상태기계 문서](docs/state-machine.md)에 정리했습니다.
+
+
+## 안전장치
+
+- 명령·버전·전제조건·모듈·경로·보장·한계 주장은 저장소 근거에 연결합니다.
+- 인라인 코드의 영문 표현이 실제 식별자인지 확인하고 내부 전용 용어의 공개 노출을
+ 차단합니다.
+- 그림을 포함하기로 한 개요 결정, 계획 항목, README 마커, 생성 소스나 자산이
+ 일치해야 시각 자료 게이트를 통과합니다.
+- 품질 점수와 독자 과업 근거의 줄 범위와 해시를 실제 후보에 대조하고,
+ `review.md`는 검증된 YAML에서 렌더링합니다.
+- 감사 모드는 결과 스키마를 확인하고 산출물을 원자적으로 기록한 다음 완료 상태로
+ 전진합니다.
+- 갱신 모드는 보호 영역과 마커 밖 문장을 보존하며, 사람이 고친 관리 영역과 새
+ 후보가 충돌하면 자동 적용을 막습니다.
+- 비밀 값, 저장소 밖 경로, 오래된 스냅숏, 검토 뒤 바뀐 산출물은 패치 준비나
+ 적용을 차단합니다.
+
+시각 자료의 소스·자산·대체 텍스트·신선도 규칙은
+[시각 자료 정책](docs/visuals.md)에서 확인할 수 있습니다.
+
+
+## 테스트
+
+전체 회귀 테스트는 다음 명령으로 실행합니다.
+
+```bash
+python3 -m pytest -q
+```
+
+GitHub Actions는 의존성을 설치한 뒤 전체 테스트를 실행합니다. 실행 환경은
+Python 3.12입니다. 자체 README 테스트는 라이브러리 프로파일, 30초 독자 흐름, 최소 실행
+경로, Mermaid 그림 결정을 확인합니다.
+
+
+## 상세 문서
+
+- [구성요소와 컨텍스트 경계](docs/architecture.md)
+- [그림 결정과 소스·자산 계약](docs/visuals.md)
+- [모드별 상태와 차단 조건](docs/state-machine.md)
+- [모델 사용량 계측](docs/usage-metrics.md)
+- [블라인드 README 품질 벤치마크](docs/quality-benchmark.md)
+- [전체 설계 명세](docs/superpowers/specs/2026-07-16-readme-harness-design.md)
+
+주요 구현은 `src/readme_harness`, 스키마·규칙·워크플로는 `.agents`, 테스트는
+`tests`에 있습니다.
+
+
+## 현재 한계
+
+- 후보 작성은 LLM 파이프라인의 판단에 의존합니다. 결정론적 드라이버는 준비된
+ 산출물을 검증하고 상태를 전진시킵니다.
+- 네 모드의 결정론적 경로는 구현됐지만 도구 간 런타임 동등성은 Phase 4 검증
+ 목표입니다.
+- 명령 검증 보고서의 기본 수준은 정적 검사입니다. 실행을 별도로 기록하지 않은
+ 명령은 실제 실행 성공을 뜻하지 않습니다.
+- 여덟 저장소 유형의 블라인드 비교 계약은 마련했지만 결과 상태는 아직 `not-run`입니다.
+ `PASS` 결과 전에는 품질 우월성을 주장하지 않습니다.
diff --git a/runs/readme-harness/20260720-review-remediation/README.generated.md b/runs/readme-harness/20260720-review-remediation/README.generated.md
new file mode 100644
index 0000000..b870a53
--- /dev/null
+++ b/runs/readme-harness/20260720-review-remediation/README.generated.md
@@ -0,0 +1,224 @@
+# README Harness
+
+이 하네스는 저장소의 실제 코드와 사용 목적을 바탕으로 문서 후보를 만들고,
+명령·경로·근거를 검사한 뒤 검토 가능한 패치로 제공합니다.
+
+- 새 README 작성
+- 기존 문서 점검
+- 사람 작성 영역을 보존한 갱신
+- 특정 섹션과 관련 검증 산출물의 재생성
+- 검토 후 별도로 실행하는 적용
+
+
+## 무엇을 만드는가
+
+README를 새로 만들거나 기존 문서를 안전하게 갱신하려는 개발자를 위한 도구입니다.
+
+`bootstrap`, `audit`, `refresh`, `section-update` 네 모드를 구현했습니다.
+
+저장소 근거와 사용자 요구를 분리해 읽고, 고위험 사실을 근거에 연결합니다. 그림을
+넣기로 했다면 실제 소스나 자산까지 확인하고, 품질 심사는 원문의 줄과 해시에 묶인
+근거를 사용합니다. 패치 준비가 끝나도 대상 `README.md`는 자동으로 바뀌지 않습니다.
+
+
+결정론적 Codex 경로는 구현됐습니다. 후보 문장 작성은 모델 파이프라인이 담당하며,
+다른 도구와의 런타임 동등성은 Phase 4 검증 전까지 보장하지 않습니다.
+
+
+
+## 설치
+
+`Python` 3.12 이상이 필요합니다.
+런타임 의존성은 `jsonschema`와 `PyYAML`입니다.
+개발 의존성은 `pytest`입니다.
+
+저장소 루트에서 개발 의존성을 포함한 편집 가능 설치를 실행합니다.
+
+```bash
+python3 -m pip install -e ".[dev]"
+```
+
+이 설치 명령은 프로젝트 선언에서 확인했지만, 현재 작업에서는 새 가상환경 설치까지
+실행해 증명하지 않았습니다.
+
+
+## 빠른 시작
+
+먼저 전체 테스트를 실행합니다.
+
+```bash
+python3 -m pytest -q
+```
+
+종료 코드 0과 실패 항목 없는 통과 요약이 성공 기준입니다. 이 후보는 아직 현재
+README를 바꾸지 않았으므로 최종 전체 결과는 명시적 적용 뒤 다시 확인합니다.
+
+자체 README 테스트는 이 명령을 최소 실행 경로로 요구합니다. 다른 운영체제와 새
+가상환경의 동일한 결과까지 보장하는 계약은 아닙니다.
+
+이 프로젝트는 명령 하나로 문서를 완성하는 독립 실행 도구가 아닙니다. Codex 작업 공간에서
+`requirement-driven-readme` 스킬로 대상 저장소의 `bootstrap` 실행을 요청하면 작성
+역할이 사용자 요구, 저장소 근거, 개요, 후보, 주장 지도, 그림 계획과 품질 심사
+산출물을 준비합니다.
+
+대상 저장소용 실행 디렉터리를 만듭니다.
+
+```bash
+python3 .agents/skills/requirement-driven-readme/scripts/init_run.py --repo-id demo --run-id first --mode bootstrap --target-repository /path/to/repository --tool-adapter codex
+```
+
+이 명령은 `runs/demo/first`에 상태와 실행 매니페스트를 초기화합니다.
+
+
+실행 디렉터리에 `readme-request.yaml`, `repository-facts.yaml`, `readme-brief.yaml`,
+`readme-outline.yaml`, `README.candidate.md`, `claim-map.yaml`, `visual-plan.yaml`,
+`review-findings.yaml`이 준비되면 모든 결정론적 게이트를 재생합니다.
+
+```bash
+python3 .agents/skills/requirement-driven-readme/scripts/run_bootstrap.py --run-dir runs/demo/first --repo /path/to/repository
+```
+
+드라이버는 후보를 새로 쓰지 않고 준비된 산출물을 `QUALITY_REVIEWED`까지
+검증합니다.
+
+
+## 사용 모드
+
+| 작업 | 모드 | 결과 |
+|---|---|---|
+| README가 없거나 전면 재작성 | `bootstrap` | 검증된 후보와 적용 준비용 패치 |
+| 기존 문서의 결함만 점검 | `audit` | 감사 결과와 검증 보고서, 후보·패치 없음 |
+| 사람 작성 영역을 보존한 갱신 | `refresh` | 3방향 병합과 병합본 전체 재검증 |
+| 한 섹션과 파급 산출물 갱신 | `section-update` | 관련 산출물 무효화 후 갱신 검증 재실행 |
+
+네 모드는 요청 스키마에 선언되어 있고 각 흐름의 상태·게이트 계약이 구현되어
+있습니다.
+
+
+## 요청 API, 설정과 산출물
+
+`readme-request.yaml`은 독자, 언어, 길이, 보존 범위, 공개 용어, 그림 정책을
+정합니다. 기술 사실은 `repository-facts.yaml`에 저장하고, 각 실행은
+`runs//` 아래에서 격리합니다.
+
+어댑터가 제공하는 단계별 모델 사용량은 실행 매니페스트에 누적합니다. 제공되지
+않은 값은 0으로 추정하지 않습니다.
+
+대표 산출물은 다음 순서로 이어집니다.
+
+```text
+readme-brief.yaml + readme-outline.yaml
+README.candidate.md + claim-map.yaml + visual-plan.yaml
+prose-report.json + verification.json + review-findings.yaml
+quality-manifest.yaml
+README.generated.md + README.patch + apply-manifest.yaml
+```
+
+품질 검토를 통과한 뒤 다음 명령으로 패치를 준비합니다.
+
+```bash
+python3 .agents/skills/requirement-driven-readme/scripts/generate_patch.py --run-dir runs/demo/first --repo /path/to/repository
+```
+
+이 단계는 `README.generated.md`, `README.patch`, `apply-manifest.yaml`을 만들고
+상태를 `READY_FOR_APPLY`로 전진시킵니다.
+
+검토가 끝난 패치만 별도 명령으로 적용합니다.
+
+```bash
+python3 .agents/skills/requirement-driven-readme/scripts/apply_patch.py --run-dir runs/demo/first --repo /path/to/repository
+```
+
+적용 직전에 후보·저장소·대상 README 해시와 경로 경계를 다시 검사합니다.
+
+
+
+## 동작 방식
+
+사용자 요구는 독자 흐름과 공개 용어, 그림 결정을 만듭니다. 대상 저장소에서는
+근거와 프로젝트 유형을 수집합니다. 두 입력이 합쳐진 후보와 시각 자료는 결정론적
+게이트와 독립 품질 심사를 통과해야 패치가 됩니다.
+
+```mermaid
+flowchart LR
+ T[Codex / Claude / Antigravity] --> O[실행 조정]
+ U[사용자 요구] --> P[독자 흐름·용어·그림 결정]
+ R[대상 저장소] --> E[근거 수집·프로젝트 분류]
+ O --> E
+ O --> P
+ E --> P
+ P --> W[README 작성]
+ P --> V[그림 소스·자산 생성]
+ W --> G[근거·명령·경로·문체 검사]
+ V --> G
+ G --> Q[독립 품질 심사]
+ Q -->|수정 필요| P
+ Q -->|통과| A[패치 준비·명시적 적용]
+ H[(해시 기반 실행 산출물)] --- E
+ H --- P
+ H --- G
+ H --- A
+```
+
+
+
+구성요소 책임과 컨텍스트 경계는 [아키텍처 문서](docs/architecture.md)에,
+모드별 전이는 [상태기계 문서](docs/state-machine.md)에 정리했습니다.
+
+
+## 안전장치
+
+- 명령·버전·전제조건·모듈·경로·보장·한계 주장은 저장소 근거에 연결합니다.
+- 인라인 코드의 영문 표현이 실제 식별자인지 확인하고 내부 전용 용어의 공개 노출을
+ 차단합니다.
+- 그림을 포함하기로 한 개요 결정, 계획 항목, README 마커, 생성 소스나 자산이
+ 일치해야 시각 자료 게이트를 통과합니다.
+- 품질 점수와 독자 과업 근거의 줄 범위와 해시를 실제 후보에 대조하고,
+ `review.md`는 검증된 YAML에서 렌더링합니다.
+- 감사 모드는 결과 스키마를 확인하고 산출물을 원자적으로 기록한 다음 완료 상태로
+ 전진합니다.
+- 갱신 모드는 보호 영역과 마커 밖 문장을 보존하며, 사람이 고친 관리 영역과 새
+ 후보가 충돌하면 자동 적용을 막습니다.
+- 비밀 값, 저장소 밖 경로, 오래된 스냅숏, 검토 뒤 바뀐 산출물은 패치 준비나
+ 적용을 차단합니다.
+
+시각 자료의 소스·자산·대체 텍스트·신선도 규칙은
+[시각 자료 정책](docs/visuals.md)에서 확인할 수 있습니다.
+
+
+## 테스트
+
+전체 회귀 테스트는 다음 명령으로 실행합니다.
+
+```bash
+python3 -m pytest -q
+```
+
+GitHub Actions는 의존성을 설치한 뒤 전체 테스트를 실행합니다. 실행 환경은
+Python 3.12입니다. 자체 README 테스트는 라이브러리 프로파일, 30초 독자 흐름, 최소 실행
+경로, Mermaid 그림 결정을 확인합니다.
+
+
+## 상세 문서
+
+- [구성요소와 컨텍스트 경계](docs/architecture.md)
+- [그림 결정과 소스·자산 계약](docs/visuals.md)
+- [모드별 상태와 차단 조건](docs/state-machine.md)
+- [모델 사용량 계측](docs/usage-metrics.md)
+- [블라인드 README 품질 벤치마크](docs/quality-benchmark.md)
+- [전체 설계 명세](docs/superpowers/specs/2026-07-16-readme-harness-design.md)
+
+주요 구현은 `src/readme_harness`, 스키마·규칙·워크플로는 `.agents`, 테스트는
+`tests`에 있습니다.
+
+
+## 현재 한계
+
+- 후보 작성은 LLM 파이프라인의 판단에 의존합니다. 결정론적 드라이버는 준비된
+ 산출물을 검증하고 상태를 전진시킵니다.
+- 네 모드의 결정론적 경로는 구현됐지만 도구 간 런타임 동등성은 Phase 4 검증
+ 목표입니다.
+- 명령 검증 보고서의 기본 수준은 정적 검사입니다. 실행을 별도로 기록하지 않은
+ 명령은 실제 실행 성공을 뜻하지 않습니다.
+- 여덟 저장소 유형의 블라인드 비교 계약은 마련했지만 결과 상태는 아직 `not-run`입니다.
+ `PASS` 결과 전에는 품질 우월성을 주장하지 않습니다.
diff --git a/runs/readme-harness/20260720-review-remediation/README.patch b/runs/readme-harness/20260720-review-remediation/README.patch
new file mode 100644
index 0000000..7270323
--- /dev/null
+++ b/runs/readme-harness/20260720-review-remediation/README.patch
@@ -0,0 +1,295 @@
+--- README.md (current)
++++ README.md (candidate)
+@@ -1,77 +1,224 @@
+ # README Harness
+
+-A GitHub-README-specialized harness built around a shared core with entrypoints
+-for **Codex**, **Antigravity**, and **Claude**. It does not "prettify" READMEs —
+-it analyzes the facts that exist in a repository, judges project type and
+-audience, then iteratively produces and maintains a README with a readable
+-structure, verified run instructions, and planned (not decorative) visuals.
+-
+-> **Status:** `bootstrap`, `audit`, `refresh`, and `section-update` have
+-> deterministic Codex-path drivers and gates. The repository does **not** yet
+-> claim Claude/Antigravity runtime equivalence; that remains the Phase 4
+-> conformance goal.
+-
+-## Core idea
+-
+-Two authority sources: the **repository** (technical facts, always
+-evidence-backed) and **`readme-request.yaml`** (why the project exists, audience,
+-language, length, what to preserve). Every state transition is blocked by a
+-deterministic gate script. High-risk factual claims—commands, versions,
+-prerequisites, modules, dependency directions, endpoints, guarantees, and
+-limitations—are traced to repository facts via `claim-map.yaml`.
+-
+-## Layout
++이 하네스는 저장소의 실제 코드와 사용 목적을 바탕으로 문서 후보를 만들고,
++명령·경로·근거를 검사한 뒤 검토 가능한 패치로 제공합니다.
++
++- 새 README 작성
++- 기존 문서 점검
++- 사람 작성 영역을 보존한 갱신
++- 특정 섹션과 관련 검증 산출물의 재생성
++- 검토 후 별도로 실행하는 적용
++
++
++## 무엇을 만드는가
++
++README를 새로 만들거나 기존 문서를 안전하게 갱신하려는 개발자를 위한 도구입니다.
++
++`bootstrap`, `audit`, `refresh`, `section-update` 네 모드를 구현했습니다.
++
++저장소 근거와 사용자 요구를 분리해 읽고, 고위험 사실을 근거에 연결합니다. 그림을
++넣기로 했다면 실제 소스나 자산까지 확인하고, 품질 심사는 원문의 줄과 해시에 묶인
++근거를 사용합니다. 패치 준비가 끝나도 대상 `README.md`는 자동으로 바뀌지 않습니다.
++
++
++결정론적 Codex 경로는 구현됐습니다. 후보 문장 작성은 모델 파이프라인이 담당하며,
++다른 도구와의 런타임 동등성은 Phase 4 검증 전까지 보장하지 않습니다.
++
++
++
++## 설치
++
++`Python` 3.12 이상이 필요합니다.
++런타임 의존성은 `jsonschema`와 `PyYAML`입니다.
++개발 의존성은 `pytest`입니다.
++
++저장소 루트에서 개발 의존성을 포함한 편집 가능 설치를 실행합니다.
++
++```bash
++python3 -m pip install -e ".[dev]"
++```
++
++이 설치 명령은 프로젝트 선언에서 확인했지만, 현재 작업에서는 새 가상환경 설치까지
++실행해 증명하지 않았습니다.
++
++
++## 빠른 시작
++
++먼저 전체 테스트를 실행합니다.
++
++```bash
++python3 -m pytest -q
++```
++
++종료 코드 0과 실패 항목 없는 통과 요약이 성공 기준입니다. 이 후보는 아직 현재
++README를 바꾸지 않았으므로 최종 전체 결과는 명시적 적용 뒤 다시 확인합니다.
++
++자체 README 테스트는 이 명령을 최소 실행 경로로 요구합니다. 다른 운영체제와 새
++가상환경의 동일한 결과까지 보장하는 계약은 아닙니다.
++
++이 프로젝트는 명령 하나로 문서를 완성하는 독립 실행 도구가 아닙니다. Codex 작업 공간에서
++`requirement-driven-readme` 스킬로 대상 저장소의 `bootstrap` 실행을 요청하면 작성
++역할이 사용자 요구, 저장소 근거, 개요, 후보, 주장 지도, 그림 계획과 품질 심사
++산출물을 준비합니다.
++
++대상 저장소용 실행 디렉터리를 만듭니다.
++
++```bash
++python3 .agents/skills/requirement-driven-readme/scripts/init_run.py --repo-id demo --run-id first --mode bootstrap --target-repository /path/to/repository --tool-adapter codex
++```
++
++이 명령은 `runs/demo/first`에 상태와 실행 매니페스트를 초기화합니다.
++
++
++실행 디렉터리에 `readme-request.yaml`, `repository-facts.yaml`, `readme-brief.yaml`,
++`readme-outline.yaml`, `README.candidate.md`, `claim-map.yaml`, `visual-plan.yaml`,
++`review-findings.yaml`이 준비되면 모든 결정론적 게이트를 재생합니다.
++
++```bash
++python3 .agents/skills/requirement-driven-readme/scripts/run_bootstrap.py --run-dir runs/demo/first --repo /path/to/repository
++```
++
++드라이버는 후보를 새로 쓰지 않고 준비된 산출물을 `QUALITY_REVIEWED`까지
++검증합니다.
++
++
++## 사용 모드
++
++| 작업 | 모드 | 결과 |
++|---|---|---|
++| README가 없거나 전면 재작성 | `bootstrap` | 검증된 후보와 적용 준비용 패치 |
++| 기존 문서의 결함만 점검 | `audit` | 감사 결과와 검증 보고서, 후보·패치 없음 |
++| 사람 작성 영역을 보존한 갱신 | `refresh` | 3방향 병합과 병합본 전체 재검증 |
++| 한 섹션과 파급 산출물 갱신 | `section-update` | 관련 산출물 무효화 후 갱신 검증 재실행 |
++
++네 모드는 요청 스키마에 선언되어 있고 각 흐름의 상태·게이트 계약이 구현되어
++있습니다.
++
++
++## 요청 API, 설정과 산출물
++
++`readme-request.yaml`은 독자, 언어, 길이, 보존 범위, 공개 용어, 그림 정책을
++정합니다. 기술 사실은 `repository-facts.yaml`에 저장하고, 각 실행은
++`runs//` 아래에서 격리합니다.
++
++어댑터가 제공하는 단계별 모델 사용량은 실행 매니페스트에 누적합니다. 제공되지
++않은 값은 0으로 추정하지 않습니다.
++
++대표 산출물은 다음 순서로 이어집니다.
+
+ ```text
+-.agents/ portable core shared by all three tools
+- skills/requirement-driven-readme/{SKILL.md,references/,scripts/}
+- workflows/ profiles/ schemas/ rules/ rubrics/ templates/ adapters/
+-AGENTS.md / GEMINI.md / CLAUDE.md thin tool entrypoints
+-.codex/ .claude/ tool-native subagents & config
+-src/readme_harness/ deterministic gate logic (Python)
+-runs/// per-run artifacts (git-ignored)
+-```
+-
+-## Modes
+-
+-`bootstrap` · `refresh` · `audit` · `section-update` are implemented. Candidate
+-authoring remains an LLM role; state transitions, merge/apply safety, and
+-verification are deterministic.
+-
+-```bash
+-# Claude
+-/readme-harness bootstrap
+-# Codex / Antigravity: follow AGENTS.md / GEMINI.md
+-```
+-
+-## State machine
+-
+-`INITIALIZED → INPUT_CAPTURED → REPOSITORY_SNAPSHOTTED → FACTS_EXTRACTED →
+-PROJECT_PROFILED → README_PLANNED → README_DRAFTED → VISUALS_PLANNED →
+-STRUCTURALLY_VALIDATED → TECHNICALLY_VERIFIED → QUALITY_REVIEWED →
+-READY_FOR_APPLY → APPLIED`
+-
+-`READY_FOR_APPLY` writes `README.generated.md` + `README.patch`; applying to the
+-target README is an explicit step. The reviewed candidate is sealed in
+-`quality-manifest.yaml`; apply rechecks repository freshness, target and
+-generated hashes, and path containment through `apply-manifest.yaml`.
+-
+-After the logical roles have authored the run artifacts, the bootstrap gates
+-can be replayed as one deterministic command:
+-
+-```bash
+-python3 .agents/skills/requirement-driven-readme/scripts/run_bootstrap.py \
+- --run-dir runs// --repo /path/to/repository
+-```
+-
+-The driver stops at `QUALITY_REVIEWED`. `generate_patch.py` prepares the sealed
+-candidate, and `apply_patch.py` is the separate explicit apply step.
+-
+-## Development
++readme-brief.yaml + readme-outline.yaml
++README.candidate.md + claim-map.yaml + visual-plan.yaml
++prose-report.json + verification.json + review-findings.yaml
++quality-manifest.yaml
++README.generated.md + README.patch + apply-manifest.yaml
++```
++
++품질 검토를 통과한 뒤 다음 명령으로 패치를 준비합니다.
++
++```bash
++python3 .agents/skills/requirement-driven-readme/scripts/generate_patch.py --run-dir runs/demo/first --repo /path/to/repository
++```
++
++이 단계는 `README.generated.md`, `README.patch`, `apply-manifest.yaml`을 만들고
++상태를 `READY_FOR_APPLY`로 전진시킵니다.
++
++검토가 끝난 패치만 별도 명령으로 적용합니다.
++
++```bash
++python3 .agents/skills/requirement-driven-readme/scripts/apply_patch.py --run-dir runs/demo/first --repo /path/to/repository
++```
++
++적용 직전에 후보·저장소·대상 README 해시와 경로 경계를 다시 검사합니다.
++
++
++
++## 동작 방식
++
++사용자 요구는 독자 흐름과 공개 용어, 그림 결정을 만듭니다. 대상 저장소에서는
++근거와 프로젝트 유형을 수집합니다. 두 입력이 합쳐진 후보와 시각 자료는 결정론적
++게이트와 독립 품질 심사를 통과해야 패치가 됩니다.
++
++```mermaid
++flowchart LR
++ T[Codex / Claude / Antigravity] --> O[실행 조정]
++ U[사용자 요구] --> P[독자 흐름·용어·그림 결정]
++ R[대상 저장소] --> E[근거 수집·프로젝트 분류]
++ O --> E
++ O --> P
++ E --> P
++ P --> W[README 작성]
++ P --> V[그림 소스·자산 생성]
++ W --> G[근거·명령·경로·문체 검사]
++ V --> G
++ G --> Q[독립 품질 심사]
++ Q -->|수정 필요| P
++ Q -->|통과| A[패치 준비·명시적 적용]
++ H[(해시 기반 실행 산출물)] --- E
++ H --- P
++ H --- G
++ H --- A
++```
++
++
++
++구성요소 책임과 컨텍스트 경계는 [아키텍처 문서](docs/architecture.md)에,
++모드별 전이는 [상태기계 문서](docs/state-machine.md)에 정리했습니다.
++
++
++## 안전장치
++
++- 명령·버전·전제조건·모듈·경로·보장·한계 주장은 저장소 근거에 연결합니다.
++- 인라인 코드의 영문 표현이 실제 식별자인지 확인하고 내부 전용 용어의 공개 노출을
++ 차단합니다.
++- 그림을 포함하기로 한 개요 결정, 계획 항목, README 마커, 생성 소스나 자산이
++ 일치해야 시각 자료 게이트를 통과합니다.
++- 품질 점수와 독자 과업 근거의 줄 범위와 해시를 실제 후보에 대조하고,
++ `review.md`는 검증된 YAML에서 렌더링합니다.
++- 감사 모드는 결과 스키마를 확인하고 산출물을 원자적으로 기록한 다음 완료 상태로
++ 전진합니다.
++- 갱신 모드는 보호 영역과 마커 밖 문장을 보존하며, 사람이 고친 관리 영역과 새
++ 후보가 충돌하면 자동 적용을 막습니다.
++- 비밀 값, 저장소 밖 경로, 오래된 스냅숏, 검토 뒤 바뀐 산출물은 패치 준비나
++ 적용을 차단합니다.
++
++시각 자료의 소스·자산·대체 텍스트·신선도 규칙은
++[시각 자료 정책](docs/visuals.md)에서 확인할 수 있습니다.
++
++
++## 테스트
++
++전체 회귀 테스트는 다음 명령으로 실행합니다.
+
+ ```bash
+ python3 -m pytest -q
+ ```
+
+-Design spec: `docs/superpowers/specs/2026-07-16-readme-harness-design.md`.
+-Phase 1 plan: `docs/superpowers/plans/2026-07-16-readme-harness-phase1.md`.
++GitHub Actions는 의존성을 설치한 뒤 전체 테스트를 실행합니다. 실행 환경은
++Python 3.12입니다. 자체 README 테스트는 라이브러리 프로파일, 30초 독자 흐름, 최소 실행
++경로, Mermaid 그림 결정을 확인합니다.
++
++
++## 상세 문서
++
++- [구성요소와 컨텍스트 경계](docs/architecture.md)
++- [그림 결정과 소스·자산 계약](docs/visuals.md)
++- [모드별 상태와 차단 조건](docs/state-machine.md)
++- [모델 사용량 계측](docs/usage-metrics.md)
++- [블라인드 README 품질 벤치마크](docs/quality-benchmark.md)
++- [전체 설계 명세](docs/superpowers/specs/2026-07-16-readme-harness-design.md)
++
++주요 구현은 `src/readme_harness`, 스키마·규칙·워크플로는 `.agents`, 테스트는
++`tests`에 있습니다.
++
++
++## 현재 한계
++
++- 후보 작성은 LLM 파이프라인의 판단에 의존합니다. 결정론적 드라이버는 준비된
++ 산출물을 검증하고 상태를 전진시킵니다.
++- 네 모드의 결정론적 경로는 구현됐지만 도구 간 런타임 동등성은 Phase 4 검증
++ 목표입니다.
++- 명령 검증 보고서의 기본 수준은 정적 검사입니다. 실행을 별도로 기록하지 않은
++ 명령은 실제 실행 성공을 뜻하지 않습니다.
++- 여덟 저장소 유형의 블라인드 비교 계약은 마련했지만 결과 상태는 아직 `not-run`입니다.
++ `PASS` 결과 전에는 품질 우월성을 주장하지 않습니다.
diff --git a/runs/readme-harness/20260720-review-remediation/apply-manifest.yaml b/runs/readme-harness/20260720-review-remediation/apply-manifest.yaml
new file mode 100644
index 0000000..9a18275
--- /dev/null
+++ b/runs/readme-harness/20260720-review-remediation/apply-manifest.yaml
@@ -0,0 +1,7 @@
+schema-version: 1
+mode: bootstrap
+target-rel: README.md
+generated-hash: sha256:dd241b6b8b7a0972086226c73b217128d98224cf30ab87505a6d5e8e0d2dcedf
+target-before-hash: sha256:53b671528d4f99b6e806145e7b687b61a5a443ceffb1fd225059f92fdc50c456
+repository-snapshot-hash: sha256:8ea3e3693ce644a2576f9a8670088a36e5964ac8edaca5b279f7281e44aa428b
+review-score: 90
diff --git a/runs/readme-harness/20260720-review-remediation/claim-map.yaml b/runs/readme-harness/20260720-review-remediation/claim-map.yaml
new file mode 100644
index 0000000..672935e
--- /dev/null
+++ b/runs/readme-harness/20260720-review-remediation/claim-map.yaml
@@ -0,0 +1,160 @@
+schema-version: 1
+claims:
+ - id: C-PROJECT-001
+ type: factual
+ statement: 명령·경로·근거를 검사한 뒤 검토 가능한 패치로 제공합니다.
+ section: overview
+ sources: [{fact-id: F-PROJECT-001}]
+ status: supported
+ - id: C-MODE-001
+ type: factual
+ statement: '`bootstrap`, `audit`, `refresh`, `section-update` 네 모드를 구현했습니다.'
+ section: overview
+ sources: [{fact-id: F-MODE-001}]
+ status: supported
+ - id: C-SAFETY-SUMMARY-001
+ type: factual
+ statement: '패치 준비가 끝나도 대상 `README.md`는 자동으로 바뀌지 않습니다.'
+ section: overview
+ sources: [{fact-id: F-APPLY-001}]
+ status: supported
+ - id: C-LIMIT-001
+ type: factual
+ statement: 다른 도구와의 런타임 동등성은 Phase 4 검증 전까지 보장하지 않습니다.
+ section: overview
+ sources: [{fact-id: F-TOOL-001}, {fact-id: F-LIMIT-001}]
+ status: supported
+ - id: C-RUNTIME-001
+ type: factual
+ section: installation
+ sources: [{fact-id: F-RUNTIME-001}, {fact-id: F-DEPENDENCY-001}]
+ status: supported
+ - id: C-INSTALL-001
+ type: factual
+ statement: 실행해 증명하지 않았습니다.
+ section: installation
+ sources: [{fact-id: F-DEPENDENCY-001}]
+ status: supported
+ - id: C-TEST-COMMAND-001
+ type: factual
+ statement: 가상환경의 동일한 결과까지 보장하는 계약은 아닙니다.
+ section: quick-start
+ sources: [{fact-id: F-SELF-README-001}, {fact-id: F-LIMIT-001}]
+ status: supported
+ - id: C-AUTHORING-001
+ type: factual
+ section: quick-start
+ sources: [{fact-id: F-AUTHORING-001}, {fact-id: F-DRIVER-001}]
+ status: supported
+ - id: C-INIT-001
+ type: factual
+ statement: '이 명령은 `runs/demo/first`에 상태와 실행 매니페스트를 초기화합니다.'
+ section: quick-start
+ sources: [{fact-id: F-DRIVER-001}]
+ status: supported
+ - id: C-BOOTSTRAP-001
+ type: factual
+ statement: 검증합니다.
+ section: quick-start
+ sources: [{fact-id: F-DRIVER-001}, {fact-id: F-STATE-001}]
+ status: supported
+ - id: C-USAGE-001
+ type: factual
+ statement: 네 모드는 요청 스키마에 선언되어 있고 각 흐름의 상태·게이트 계약이 구현되어
+ section: usage
+ sources: [{fact-id: F-MODE-001}, {fact-id: F-STATE-001}]
+ status: supported
+ - id: C-INPUT-001
+ type: factual
+ statement: '`runs//` 아래에서 격리합니다.'
+ section: api
+ sources: [{fact-id: F-ARTIFACT-001}, {fact-id: F-LAYOUT-001}]
+ status: supported
+ - id: C-USAGE-METRICS-001
+ type: factual
+ section: api
+ sources: [{fact-id: F-USAGE-001}]
+ status: supported
+ - id: C-PREPARE-001
+ type: factual
+ statement: '상태를 `READY_FOR_APPLY`로 전진시킵니다.'
+ section: api
+ sources: [{fact-id: F-APPLY-001}]
+ status: supported
+ - id: C-APPLY-001
+ type: factual
+ statement: 적용 직전에 후보·저장소·대상 README 해시와 경로 경계를 다시 검사합니다.
+ section: api
+ sources: [{fact-id: F-APPLY-001}]
+ status: supported
+ - id: C-FLOW-001
+ type: factual
+ statement: 게이트와 독립 품질 심사를 통과해야 패치가 됩니다.
+ section: architecture
+ sources: [{fact-id: F-STATE-001}, {fact-id: F-REVIEW-001}, {fact-id: F-APPLY-001}]
+ status: supported
+ - id: C-TERM-001
+ type: factual
+ statement: 차단합니다.
+ section: safeguards
+ sources: [{fact-id: F-TERM-001}]
+ status: supported
+ - id: C-VISUAL-001
+ type: factual
+ statement: 일치해야 시각 자료 게이트를 통과합니다.
+ section: safeguards
+ sources: [{fact-id: F-VISUAL-001}]
+ status: supported
+ - id: C-REVIEW-001
+ type: factual
+ statement: '`review.md`는 검증된 YAML에서 렌더링합니다.'
+ section: safeguards
+ sources: [{fact-id: F-REVIEW-001}]
+ status: supported
+ - id: C-AUDIT-001
+ type: factual
+ statement: 전진합니다.
+ section: safeguards
+ sources: [{fact-id: F-AUDIT-001}]
+ status: supported
+ - id: C-MERGE-001
+ type: factual
+ statement: 후보가 충돌하면 자동 적용을 막습니다.
+ section: safeguards
+ sources: [{fact-id: F-MERGE-001}]
+ status: supported
+ - id: C-APPLY-SAFETY-001
+ type: factual
+ statement: 적용을 차단합니다.
+ section: safeguards
+ sources: [{fact-id: F-APPLY-001}]
+ status: supported
+ - id: C-CI-001
+ type: factual
+ statement: 경로, Mermaid 그림 결정을 확인합니다.
+ section: tests
+ sources: [{fact-id: F-CI-001}, {fact-id: F-SELF-README-001}]
+ status: supported
+ - id: C-LAYOUT-001
+ type: factual
+ statement: '`tests`에 있습니다.'
+ section: documentation
+ sources: [{fact-id: F-LAYOUT-001}]
+ status: supported
+ - id: C-LIMIT-002
+ type: factual
+ statement: 목표입니다.
+ section: limitations
+ sources: [{fact-id: F-TOOL-001}, {fact-id: F-LIMIT-001}]
+ status: supported
+ - id: C-VERIFY-LIMIT-001
+ type: factual
+ statement: 명령은 실제 실행 성공을 뜻하지 않습니다.
+ section: limitations
+ sources: [{fact-id: F-LIMIT-001}]
+ status: supported
+ - id: C-BENCH-LIMIT-001
+ type: factual
+ section: limitations
+ sources: [{fact-id: F-BENCH-001}]
+ status: supported
diff --git a/runs/readme-harness/20260720-review-remediation/prose-report.json b/runs/readme-harness/20260720-review-remediation/prose-report.json
new file mode 100644
index 0000000..b60e97d
--- /dev/null
+++ b/runs/readme-harness/20260720-review-remediation/prose-report.json
@@ -0,0 +1,31 @@
+{
+ "schema-version": 1,
+ "policy-id": "korean-reader-prose-v1",
+ "language": "ko-KR",
+ "applicable": true,
+ "scope": "candidate",
+ "state": "PASS_WITH_WARNINGS",
+ "summary": {
+ "errors": 0,
+ "warnings": 1,
+ "sentences": 108,
+ "prose-characters": 2081,
+ "hangul-characters": 1839
+ },
+ "findings": [
+ {
+ "rule-id": "KO-REPEATED-ENDING",
+ "severity": "warning",
+ "line": 4,
+ "section": "README Harness",
+ "region-kind": "candidate",
+ "excerpt": "합니다 (29/43문장)",
+ "message": "같은 문장 종결이 이어져 설명이 기계적으로 들릴 수 있습니다.",
+ "suggestion": "정의, 절차, 제한에 맞춰 현재형 동사와 명사형 표제를 섞어 쓰세요.",
+ "source-ids": [
+ "NIKL-EASY-PUBLIC-LANGUAGE"
+ ],
+ "id": "P-001"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/runs/readme-harness/20260720-review-remediation/quality-manifest.yaml b/runs/readme-harness/20260720-review-remediation/quality-manifest.yaml
new file mode 100644
index 0000000..c07f150
--- /dev/null
+++ b/runs/readme-harness/20260720-review-remediation/quality-manifest.yaml
@@ -0,0 +1,14 @@
+schema-version: 2
+mode: bootstrap
+profile: library
+repository-snapshot-hash: sha256:8ea3e3693ce644a2576f9a8670088a36e5964ac8edaca5b279f7281e44aa428b
+artifacts:
+ readme-request.yaml: sha256:5aaa41c2d4131ea1587660751c73b6a92894c684737fb3315de44dd210e03a0f
+ repository-facts.yaml: sha256:61f1fb4b892ca6b21ad4a54634e687f2e231d1582315ff37bda31b28e4a68735
+ readme-brief.yaml: sha256:a17a7877ee3799ddd9e240f75fd59f285f79d8f95364c701f61fa0b280f89529
+ readme-outline.yaml: sha256:9748f1e59bfb884044e685970f319fca3e54c8b7b1cdad7861993cd15cf0e57b
+ README.candidate.md: sha256:dd241b6b8b7a0972086226c73b217128d98224cf30ab87505a6d5e8e0d2dcedf
+ claim-map.yaml: sha256:886526bb672493d1846270540b422858f2a68985b2be5c79cdddd8a285e77ee6
+ visual-plan.yaml: sha256:8e610350b341ce517de9a39746f83c62f0e97197916d41b3f857e67c4ce153d7
+ prose-report.json: sha256:6c34d9c7d068786688dea529478b5a88ef2017b05d772b45c32374f1888a17fb
+ review-findings.yaml: sha256:6d19d78927d7255f39ef7fb3f859dca715d2128ed1b96ab5bad3d65bc8aeaa32
diff --git a/runs/readme-harness/20260720-review-remediation/readme-brief.yaml b/runs/readme-harness/20260720-review-remediation/readme-brief.yaml
new file mode 100644
index 0000000..e72a031
--- /dev/null
+++ b/runs/readme-harness/20260720-review-remediation/readme-brief.yaml
@@ -0,0 +1,47 @@
+schema-version: 1
+project-profile:
+ primary: library
+ secondary: [documentation-tooling]
+audiences:
+ primary:
+ - 저장소 README를 만들거나 갱신하는 개발자
+ secondary:
+ - 결정론적 게이트와 도구 어댑터를 확장하는 기여자
+reader-outcomes:
+ - 프로젝트가 만드는 결과와 안전 경계를 30초 안에 설명한다.
+ - 의존성을 설치하고 전체 테스트로 개발 환경을 확인한다.
+ - 네 가지 모드 중 자기 작업에 맞는 경로를 선택한다.
+ - 후보를 검증하고 패치를 준비한 뒤 명시적으로 적용한다.
+project-story:
+ value-proposition: 저장소 코드와 사용자 요구를 근거로 README 후보를 만들고 검증 가능한 패치로 전달한다.
+ problem: README 자동 작성은 실행 명령과 구조 설명이 실제 저장소와 어긋나거나 기존 문서를 훼손하기 쉽다.
+ target-reader: README를 새로 만들거나 안전하게 갱신하려는 개발자
+ notable-traits:
+ - text: 저장소 사실과 사용자 의도를 분리하고 고위험 주장을 근거에 연결한다.
+ fact-ids: [F-PROJECT-001, F-STATE-001]
+ - text: 포함한 그림은 개요 결정부터 실제 소스 또는 자산까지 교차 검증한다.
+ fact-ids: [F-VISUAL-001]
+ - text: 품질 심사 근거는 실제 README 줄 범위와 해시에 묶인다.
+ fact-ids: [F-REVIEW-001]
+ - text: 패치 준비와 대상 README 적용이 분리되고 적용 직전에 상태와 해시를 다시 검사한다.
+ fact-ids: [F-APPLY-001]
+ maturity: Codex 경로의 네 모드 드라이버는 구현됐으나 후보 작성은 LLM 경계에 있고 도구 간 동등성은 아직 검증하지 않았다.
+ limitations:
+ - 후보 작성 자체는 결정론적 코드가 아니라 LLM 파이프라인이 담당한다.
+ - Claude와 Antigravity의 런타임 동등성은 Phase 4 전에는 주장하지 않는다.
+narrative-variant: library
+reader-journey:
+ - reader-question: 무엇을 만들고 어떤 문제를 막습니까?
+ section-id: overview
+ - reader-question: 로컬에서 설치와 테스트를 어떻게 확인합니까?
+ section-id: quick-start
+ - reader-question: 내 작업에는 어떤 모드를 선택해야 합니까?
+ section-id: usage
+ - reader-question: 저장소 분석부터 적용까지 어떤 흐름으로 동작합니까?
+ section-id: architecture
+ - reader-question: 어떤 오류와 문서 훼손을 차단합니까?
+ section-id: safeguards
+ - reader-question: 기여 전에 무엇을 검증해야 합니까?
+ section-id: tests
+ - reader-question: 상세 계약은 어디에서 확인합니까?
+ section-id: documentation
diff --git a/runs/readme-harness/20260720-review-remediation/readme-outline.yaml b/runs/readme-harness/20260720-review-remediation/readme-outline.yaml
new file mode 100644
index 0000000..712c4e6
--- /dev/null
+++ b/runs/readme-harness/20260720-review-remediation/readme-outline.yaml
@@ -0,0 +1,129 @@
+schema-version: 1
+sections:
+ - id: overview
+ title-guidance: 무엇을 만드는가
+ level: 2
+ purpose: 프로젝트의 결과, 대상 독자, 사실 근거와 명시적 적용이라는 핵심 경계를 첫 화면에서 설명한다.
+ required: true
+ content-strategy: inline
+ target-doc: null
+ content-requirements:
+ - 저장소 사실과 사용자 요구를 바탕으로 README 후보와 패치를 만든다는 한 문장 정의
+ - bootstrap, audit, refresh, section-update 네 작업 결과
+ - 후보 작성은 LLM 경계이고 도구 간 동등성을 아직 주장하지 않는다는 제한
+ visual-slot:
+ decision: exclude
+ reader-question: 프로젝트 정체성을 이해하는 데 그림이 필요한가?
+ rationale: 결과와 안전 경계는 짧은 정의와 목록으로 더 직접적으로 전달된다.
+ - id: installation
+ title-guidance: 설치
+ level: 2
+ purpose: 필요한 Python 버전과 개발 의존성 설치 명령을 제시한다.
+ required: true
+ content-strategy: inline
+ target-doc: null
+ content-requirements:
+ - Python 3.12 이상
+ - editable 개발 설치 명령
+ - id: quick-start
+ title-guidance: 빠른 시작
+ level: 2
+ purpose: 설치 후 전체 테스트를 실행하고 첫 bootstrap run을 초기화하는 최소 경로를 제공한다.
+ required: true
+ content-strategy: inline
+ target-doc: null
+ content-requirements:
+ - 테스트 명령과 통과 신호
+ - init_run 명령과 생성 위치
+ - 독립형 생성 CLI가 아니라 Codex 스킬 요청으로 작성 산출물을 준비한다는 경계
+ - 준비해야 할 작성 산출물과 run_bootstrap으로 게이트를 재생하는 조건
+ visual-slot:
+ decision: exclude
+ reader-question: 세 개의 순차 명령을 이해하는 데 그림이 필요한가?
+ rationale: 복사 가능한 명령과 각 성공 신호가 그림보다 정확하다.
+ - id: usage
+ title-guidance: 사용 모드
+ level: 2
+ purpose: 독자 작업을 기준으로 네 가지 모드의 선택 조건과 결과를 구분한다.
+ required: true
+ content-strategy: inline
+ target-doc: null
+ content-requirements:
+ - 새 문서 작성, 기존 문서 점검, 안전 갱신, 부분 갱신의 선택 기준
+ - audit은 후보나 패치를 만들지 않는다는 차이
+ - id: api
+ title-guidance: 요청 API, 설정과 산출물
+ level: 2
+ purpose: 사용자 의도 파일, 실행 디렉터리, 후보·검증·패치 산출물의 대응을 설명한다.
+ required: true
+ content-strategy: inline
+ target-doc: null
+ content-requirements:
+ - readme-request의 역할
+ - runs 경로와 주요 산출물
+ - 어댑터 제공 모델 사용량과 미제공 값 비추정 원칙
+ - patch 준비와 apply 명령의 분리
+ - id: architecture
+ title-guidance: 동작 방식
+ level: 2
+ purpose: 사용자 요구와 저장소 근거가 계획·작성·시각화·게이트·품질 심사·적용으로 흐르는 구조를 한 화면에서 설명한다.
+ required: true
+ content-strategy: inline
+ target-doc: null
+ content-requirements:
+ - 의미 판단과 결정론적 검증의 경계
+ - 실패 시 계획 단계로 돌아가는 재작업 흐름
+ - 해시 기반 산출물 저장소
+ visual-slot:
+ decision: include
+ reader-question: 저장소 근거와 사용자 요구가 어떻게 검토 가능한 패치로 변합니까?
+ rationale: 두 입력이 계획에서 합쳐지고 작성과 그림이 검증으로 모인 뒤 품질 심사에서 재작업 또는 적용으로 갈라지는 관계는 산문보다 흐름도가 빠르다.
+ purpose: 저장소 분석부터 독립 품질 심사와 명시적 적용까지의 데이터 흐름과 재작업 경계를 보여준다.
+ - id: safeguards
+ title-guidance: 안전장치
+ level: 2
+ purpose: 사실·명령·경로·비밀 값·시각 자료·품질 근거·보호 영역·적용 경계를 구체적으로 설명한다.
+ required: true
+ content-strategy: inline
+ target-doc: null
+ content-requirements:
+ - 근거 없는 고위험 주장 차단
+ - 공개 용어와 그림 완성도 계약
+ - 감사 산출물 검증과 갱신 보호 영역
+ - 패치 준비 후 별도 apply
+ - id: tests
+ title-guidance: 테스트
+ level: 2
+ purpose: 전체 회귀 테스트 명령과 자체 README 품질 계약을 설명한다.
+ required: true
+ content-strategy: inline
+ target-doc: null
+ content-requirements:
+ - 전체 pytest 명령
+ - CI가 같은 명령을 실행한다는 사실
+ - 자체 README 독자 과업과 시각 결정 테스트
+ - id: documentation
+ title-guidance: 상세 문서
+ level: 2
+ purpose: 아키텍처, 시각 자료, 상태기계, 설계 명세로 독자를 안내한다.
+ required: true
+ content-strategy: summary-link
+ target-doc: docs/
+ content-requirements:
+ - architecture.md
+ - visuals.md
+ - state-machine.md
+ - usage-metrics.md
+ - quality-benchmark.md
+ - 설계 명세
+ - id: limitations
+ title-guidance: 현재 한계
+ level: 2
+ purpose: 결정론 게이트와 LLM 후보 작성의 경계, 도구 간 동등성 미검증 상태를 명시한다.
+ required: true
+ content-strategy: inline
+ target-doc: null
+ content-requirements:
+ - 후보 작성은 LLM 파이프라인
+ - cross-tool equivalence는 Phase 4 목표
+ - 블라인드 품질 비교는 아직 not-run이며 PASS 전 우월성 주장 금지
diff --git a/runs/readme-harness/20260720-review-remediation/readme-request.yaml b/runs/readme-harness/20260720-review-remediation/readme-request.yaml
new file mode 100644
index 0000000..f355eba
--- /dev/null
+++ b/runs/readme-harness/20260720-review-remediation/readme-request.yaml
@@ -0,0 +1,57 @@
+schema-version: 1
+target:
+ repository: /home/donghyeon/workspace/ai-tool/readme-harness
+ readme-path: README.md
+mode: bootstrap
+profile-override: library
+project-intent:
+ purpose: 저장소의 실제 코드와 사용자 요구를 바탕으로 검증 가능한 README 후보와 명시적으로 적용할 패치를 만드는 하네스를 설명한다.
+ positioning: 사실 추적과 적용 안전성뿐 아니라 독자 과업, 공개 용어, 실제 시각 자료, 근거가 고정된 품질 심사를 함께 다루는 README 제작 도구다.
+ maturity: Codex 경로의 bootstrap, audit, refresh, section-update는 구현됐고 도구 간 런타임 동등성은 아직 주장하지 않는다.
+audience:
+ primary:
+ - 저장소 README를 새로 만들거나 안전하게 갱신하려는 개발자
+ secondary:
+ - 하네스의 게이트와 워크플로를 확장하는 기여자
+reader-actions:
+ - 이 프로젝트가 어떤 결과를 만들고 무엇을 보장하는지 30초 안에 판단한다.
+ - 개발 환경을 준비하고 전체 테스트를 실행해 설치 상태를 확인한다.
+ - 작업에 맞는 bootstrap, audit, refresh, section-update 모드를 고른다.
+ - 생성된 패치를 검토한 뒤 별도의 명시적 적용 단계를 실행한다.
+content-policy:
+ language: ko-KR
+ tone: 직접적이고 검증 수준을 분명히 밝히는 기술 설명체
+ target-length: medium
+ preserve-existing-copy: false
+ detail-docs-policy: summary-and-link
+visual-policy:
+ mode: when-useful
+ max-visuals: 1
+ preferred-formats:
+ - mermaid
+ placeholder-format: HTML 주석 기반 제작 사양
+terminology-policy:
+ exact-identifiers: []
+ explain-on-first-use: {}
+ internal-only:
+ family: 작업 담당 방식
+ fan-out: 여러 담당자가 나눠 검토
+ collapse: 한 담당자가 맡아 처리
+ concrete worker: 실제 변경 담당자
+ verification family: 검증 담당 역할
+ route-to: 재작업 시작 상태
+must-include:
+ - 한 문장 가치 제안과 대상 독자
+ - 설치 전제조건과 복사 가능한 첫 테스트 경로
+ - 네 가지 모드의 독자 작업 기준 선택법
+ - 저장소 분석부터 패치 적용까지의 한 화면 처리 흐름
+ - 사실, 명령, 경로, 비밀 값, 보호 영역, 품질 근거에 대한 안전장치
+ - 생성되는 주요 산출물과 명시적 적용 경계
+ - Codex 경로 구현 범위와 도구 간 동등성 한계
+ - 아키텍처, 시각화, 상태기계 상세 문서 링크
+must-exclude:
+ - 저장소 근거 없는 최상 품질, 성능, 생산 준비 완료 주장
+ - 전체 상태 이름과 내부 역할 배치를 첫 화면에서 장황하게 나열하는 설명
+ - 내부 오케스트레이션 영문 용어를 독자용 개념처럼 노출하는 문장
+ - 검증되지 않은 설치·실행 명령
+protected-sections: []
diff --git a/runs/readme-harness/20260720-review-remediation/repository-facts.yaml b/runs/readme-harness/20260720-review-remediation/repository-facts.yaml
new file mode 100644
index 0000000..5fef832
--- /dev/null
+++ b/runs/readme-harness/20260720-review-remediation/repository-facts.yaml
@@ -0,0 +1,363 @@
+schema-version: 1
+repository-snapshot-hash: sha256:8ea3e3693ce644a2576f9a8670088a36e5964ac8edaca5b279f7281e44aa428b
+project-name: readme-harness
+languages: [Python]
+frameworks: [jsonschema, PyYAML, pytest]
+facts:
+ - id: F-PROJECT-001
+ category: purpose
+ key: harness-description
+ value: 저장소 사실과 사용자 요구를 바탕으로 GitHub README를 분석·설계·작성·검증하는 하네스
+ assertion-type: declared
+ confidence: high
+ evidence:
+ - path: harness.yaml
+ line-start: 2
+ line-end: 13
+ source-kind: harness-configuration
+ - id: F-RUNTIME-001
+ category: prerequisite
+ key: python-version
+ value: Python >=3.12
+ assertion-type: declared
+ confidence: high
+ evidence:
+ - path: pyproject.toml
+ line-start: 1
+ line-end: 5
+ source-kind: build-configuration
+ - id: F-DEPENDENCY-001
+ category: dependency
+ key: runtime-and-dev-dependencies
+ value: [jsonschema>=4.20, PyYAML>=6.0, pytest>=8.0]
+ assertion-type: declared
+ confidence: high
+ evidence:
+ - path: pyproject.toml
+ line-start: 5
+ line-end: 8
+ source-kind: build-configuration
+ - id: F-MODE-001
+ category: capability
+ key: implemented-modes
+ value: [bootstrap, audit, refresh, section-update]
+ assertion-type: declared
+ confidence: high
+ evidence:
+ - path: harness.yaml
+ line-start: 10
+ line-end: 13
+ source-kind: harness-configuration
+ - id: F-TOOL-001
+ category: compatibility
+ key: tool-boundary
+ value:
+ supported-tools: [codex, antigravity, claude]
+ deterministic-codex-drivers: implemented
+ cross-tool-equivalence: phase-4
+ assertion-type: declared
+ confidence: high
+ evidence:
+ - path: harness.yaml
+ line-start: 8
+ line-end: 13
+ source-kind: harness-configuration
+ - path: harness.yaml
+ line-start: 99
+ line-end: 107
+ source-kind: capability-boundary
+ - id: F-STATE-001
+ category: workflow
+ key: bootstrap-gates
+ value:
+ states: [INPUT_CAPTURED, REPOSITORY_SNAPSHOTTED, FACTS_EXTRACTED, PROJECT_PROFILED, README_PLANNED, README_DRAFTED, VISUALS_PLANNED, STRUCTURALLY_VALIDATED, TECHNICALLY_VERIFIED, QUALITY_REVIEWED]
+ final-preparation: READY_FOR_APPLY
+ final-apply: APPLIED
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: src/readme_harness/state.py
+ line-start: 71
+ line-end: 83
+ source-kind: state-machine-code
+ - id: F-VISUAL-001
+ category: visual-contract
+ key: included-visual-completeness
+ value: 개요 include 섹션, visual plan 섹션, README visual id, 요청 모드에 맞는 생성 소스 또는 자산을 함께 검사
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: src/readme_harness/visuals.py
+ line-start: 77
+ line-end: 183
+ source-kind: validator-code
+ - id: F-DRIVER-001
+ category: workflow
+ key: bootstrap-driver-boundary
+ value:
+ init-run: runs//에 state.json과 run-manifest.json을 생성
+ bootstrap-driver: 준비된 authoring artifacts를 QUALITY_REVIEWED까지 검증하며 후보나 대상 README를 작성하지 않음
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: .agents/skills/requirement-driven-readme/scripts/init_run.py
+ line-start: 10
+ line-end: 37
+ source-kind: driver-code
+ - path: .agents/skills/requirement-driven-readme/scripts/run_bootstrap.py
+ line-start: 1
+ line-end: 7
+ source-kind: driver-code
+ - id: F-AUTHORING-001
+ category: usage
+ key: model-authoring-boundary
+ value: 독립형 종단 간 생성 CLI가 아니라 도구가 requirement-driven-readme 스킬을 로드하고 모델 역할이 작성 산출물을 준비한 뒤 결정론 드라이버가 검증하는 구조
+ assertion-type: declared
+ confidence: high
+ evidence:
+ - path: AGENTS.md
+ line-start: 1
+ line-end: 14
+ source-kind: codex-entrypoint
+ - path: harness.yaml
+ line-start: 100
+ line-end: 109
+ source-kind: capability-boundary
+ - id: F-TERM-001
+ category: prose-contract
+ key: public-terminology
+ value: 인라인 코드 식별자를 repository-facts.yaml과 대조하고 내부 전용 용어 노출과 첫 사용 설명을 검사
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: src/readme_harness/prose.py
+ line-start: 120
+ line-end: 207
+ source-kind: validator-code
+ - path: src/readme_harness/prose.py
+ line-start: 286
+ line-end: 379
+ source-kind: validator-code
+ - id: F-CLASSIFY-001
+ category: classification
+ key: root-first-python-classification
+ value: 루트 선언을 우선하고 테스트·픽스처·예제·샘플·vendor를 주 분류 신호에서 제외하며 pyproject.toml을 CLI·서비스·라이브러리로 구분
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: src/readme_harness/scan.py
+ line-start: 14
+ line-end: 103
+ source-kind: scanner-code
+ - path: src/readme_harness/classify.py
+ line-start: 6
+ line-end: 29
+ source-kind: classifier-code
+ - id: F-REVIEW-001
+ category: quality-contract
+ key: hash-bound-review-evidence
+ value: 품질 근거의 artifact, section-id, line-start, line-end, content-hash를 실제 README와 대조하고 review.md를 YAML에서 렌더링
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: src/readme_harness/review.py
+ line-start: 18
+ line-end: 103
+ source-kind: review-validator-code
+ - id: F-AUDIT-001
+ category: audit-contract
+ key: validated-atomic-audit-completion
+ value: audit findings를 스키마 검증하고 산출물을 원자적으로 기록한 뒤 AUDIT_COMPLETED로 전이
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: .agents/skills/requirement-driven-readme/scripts/run_audit.py
+ line-start: 107
+ line-end: 134
+ source-kind: audit-driver-code
+ - id: F-APPLY-001
+ category: safety
+ key: explicit-apply-boundary
+ value:
+ prepared-artifacts: [README.generated.md, README.patch, apply-manifest.yaml]
+ checks: [reviewed-artifact-hashes, repository-freshness, generated-hash, target-before-hash, path-containment]
+ target-write: explicit apply_patch.py only
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: harness.yaml
+ line-start: 134
+ line-end: 141
+ source-kind: apply-policy
+ - path: .agents/skills/requirement-driven-readme/scripts/apply_patch.py
+ line-start: 22
+ line-end: 67
+ source-kind: apply-driver-code
+ - id: F-MERGE-001
+ category: safety
+ key: refresh-preservation
+ value: refresh는 protected와 unmarked 영역을 보존하고 서로 다른 managed 편집을 manual-required 충돌로 기록
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: src/readme_harness/merge.py
+ line-start: 7
+ line-end: 79
+ source-kind: merge-code
+ - id: F-LAYOUT-001
+ category: structure
+ key: primary-paths
+ value: [.agents, src/readme_harness, tests, docs/architecture.md, docs/visuals.md, docs/state-machine.md, runs]
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: harness.yaml
+ line-start: 125
+ line-end: 132
+ source-kind: harness-configuration
+ - path: docs/architecture.md
+ line-start: 1
+ line-end: 1
+ source-kind: documentation
+ - path: docs/visuals.md
+ line-start: 1
+ line-end: 1
+ source-kind: documentation
+ - path: docs/state-machine.md
+ line-start: 1
+ line-end: 1
+ source-kind: documentation
+ - id: F-ARTIFACT-001
+ category: artifact-contract
+ key: primary-authoring-artifacts
+ value: [README.md, readme-request.yaml, repository-facts.yaml, readme-brief.yaml, readme-outline.yaml, README.candidate.md, claim-map.yaml, visual-plan.yaml, prose-report.json, verification.json, review-findings.yaml, review.md, quality-manifest.yaml, audit-findings.yaml, audit-report.md, README.generated.md, README.patch, apply-manifest.yaml, runs/demo/first, runs//, requirement-driven-readme, bootstrap]
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: .agents/skills/requirement-driven-readme/scripts/run_bootstrap.py
+ line-start: 46
+ line-end: 56
+ source-kind: bootstrap-driver-code
+ - path: harness.yaml
+ line-start: 134
+ line-end: 141
+ source-kind: apply-policy
+ - id: F-SELF-README-001
+ category: readme-contract
+ key: own-readme-quality-tests
+ value: [library profile quality audit, 30-second reader order, python3 -m pytest -q, Mermaid, harness-flow]
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: tests/unit/test_own_readme_quality.py
+ line-start: 14
+ line-end: 38
+ source-kind: repository-owned-readme-test
+ - id: F-CI-001
+ category: testing
+ key: continuous-integration
+ value: GitHub Actions는 Python 3.12에서 개발 의존성을 설치하고 python -m pytest -q를 실행
+ assertion-type: declared
+ confidence: high
+ evidence:
+ - path: .github/workflows/ci.yml
+ line-start: 1
+ line-end: 17
+ source-kind: ci-workflow
+ - id: F-USAGE-001
+ category: observability
+ key: adapter-supplied-model-usage
+ value: 어댑터가 제공한 단계별 입력·캐시 입력·출력 토큰과 컨텍스트 파일 기여를 run-manifest.json에 누적하며 미제공 값은 추정하지 않음
+ assertion-type: observed
+ confidence: high
+ evidence:
+ - path: src/readme_harness/usage.py
+ line-start: 11
+ line-end: 66
+ source-kind: usage-recorder-code
+ - path: docs/usage-metrics.md
+ line-start: 1
+ line-end: 29
+ source-kind: usage-documentation
+ - id: F-BENCH-001
+ category: limitation
+ key: quality-superiority-gate
+ value:
+ repository-types: 8
+ arms: [human-maintained, single-prompt, harness]
+ current-status: not-run
+ required-status: PASS
+ superiority-claims: prohibited-until-benchmark-pass
+ assertion-type: declared
+ confidence: high
+ evidence:
+ - path: benchmarks/quality-benchmark.yaml
+ line-start: 1
+ line-end: 37
+ source-kind: benchmark-contract
+ - path: harness.yaml
+ line-start: 108
+ line-end: 114
+ source-kind: capability-boundary
+ - id: F-LIMIT-001
+ category: limitation
+ key: candidate-generation-boundary
+ value: 후보 작성은 LLM pipeline이며 결정론 코어가 아니고 도구 간 런타임 동등성은 phase-4 목표
+ assertion-type: declared
+ confidence: high
+ evidence:
+ - path: harness.yaml
+ line-start: 99
+ line-end: 107
+ source-kind: capability-boundary
+commands:
+ - id: CMD-001
+ command: python3 -m pip install -e ".[dev]"
+ cwd: .
+ source:
+ path: pyproject.toml
+ verification:
+ status: discovered
+ method: pyproject dependencies and editable install syntax
+ - id: CMD-002
+ command: python3 -m pytest -q
+ cwd: .
+ source:
+ path: pyproject.toml
+ verification:
+ status: executed
+ method: pytest execution in current workspace
+ level: execution
+ limitations: [운영체제와 새 가상환경에서의 설치까지 증명하지는 않음]
+ - id: CMD-003
+ command: python3 .agents/skills/requirement-driven-readme/scripts/init_run.py --repo-id demo --run-id first --mode bootstrap --target-repository /path/to/repository --tool-adapter codex
+ cwd: .
+ source:
+ path: .agents/skills/requirement-driven-readme/scripts/init_run.py
+ verification:
+ status: static-verified
+ method: python script path exists
+ - id: CMD-004
+ command: python3 .agents/skills/requirement-driven-readme/scripts/run_bootstrap.py --run-dir runs/demo/first --repo /path/to/repository
+ cwd: .
+ source:
+ path: .agents/skills/requirement-driven-readme/scripts/run_bootstrap.py
+ verification:
+ status: static-verified
+ method: python script path exists
+ - id: CMD-005
+ command: python3 .agents/skills/requirement-driven-readme/scripts/generate_patch.py --run-dir runs/demo/first --repo /path/to/repository
+ cwd: .
+ source:
+ path: .agents/skills/requirement-driven-readme/scripts/generate_patch.py
+ verification:
+ status: static-verified
+ method: python script path exists
+ - id: CMD-006
+ command: python3 .agents/skills/requirement-driven-readme/scripts/apply_patch.py --run-dir runs/demo/first --repo /path/to/repository
+ cwd: .
+ source:
+ path: .agents/skills/requirement-driven-readme/scripts/apply_patch.py
+ verification:
+ status: static-verified
+ method: python script path exists
diff --git a/runs/readme-harness/20260720-review-remediation/repository-snapshot.json b/runs/readme-harness/20260720-review-remediation/repository-snapshot.json
new file mode 100644
index 0000000..da9e807
--- /dev/null
+++ b/runs/readme-harness/20260720-review-remediation/repository-snapshot.json
@@ -0,0 +1,7 @@
+{
+ "git-sha": "636617ccd9f20440f21339f808557c096b55fec2",
+ "dirty": true,
+ "diff-hash": "sha256:8ea3e3693ce644a2576f9a8670088a36e5964ac8edaca5b279f7281e44aa428b",
+ "scanned-at": null,
+ "file-count": 228
+}
\ No newline at end of file
diff --git a/runs/readme-harness/20260720-review-remediation/review-findings.yaml b/runs/readme-harness/20260720-review-remediation/review-findings.yaml
new file mode 100644
index 0000000..f7a11f5
--- /dev/null
+++ b/runs/readme-harness/20260720-review-remediation/review-findings.yaml
@@ -0,0 +1,144 @@
+schema-version: 1
+verdict: PASS
+score: 90
+scores:
+ project-specificity:
+ score: 5
+ evidence:
+ - artifact: README.candidate.md
+ section-id: overview
+ line-start: 12
+ line-end: 26
+ content-hash: sha256:e6881327a3a749eecb74b02636fbc9c3d254ce9b952896f59c7093d0d89e2799
+ observation: 주 독자를 README 작성·갱신 개발자로 명시하고 네 모드와 근거·적용 경계, 런타임 동등성 한계를 프로젝트 고유 특성으로 설명한다.
+ reader-journey:
+ score: 5
+ evidence:
+ - artifact: README.candidate.md
+ section-id: overview
+ line-start: 12
+ line-end: 26
+ content-hash: sha256:e6881327a3a749eecb74b02636fbc9c3d254ce9b952896f59c7093d0d89e2799
+ observation: 대상 독자, 제공 결과, 핵심 안전 경계와 구현 한계가 첫 개요에 모여 있어 후속 과업을 빠르게 판단할 수 있다.
+ - artifact: README.candidate.md
+ section-id: usage
+ line-start: 84
+ line-end: 95
+ content-hash: sha256:1cb56273e71777d93e55ce3eee23094d33f4d6d66b8e56d5f57b842107c8857a
+ observation: 네 모드를 새 작성, 감사, 보존 갱신, 부분 갱신이라는 독자 작업과 결과 기준으로 바로 선택할 수 있다.
+ technical-explanation:
+ score: 4
+ evidence:
+ - artifact: README.candidate.md
+ section-id: architecture
+ line-start: 135
+ line-end: 166
+ content-hash: sha256:f39304dc61c0a017a37676b2077d572aaf9c8bd78b24ae51eb125762d41ef623
+ observation: 사용자 요구와 저장소 근거가 계획, 작성, 시각 자료, 결정론적 검사, 독립 심사와 재작업으로 이어지는 책임과 흐름을 설명한다.
+ - artifact: README.candidate.md
+ section-id: safeguards
+ line-start: 168
+ line-end: 186
+ content-hash: sha256:f4aeba8e1e5aae86600fc4f2c70f10da1b67120222cf8c45912b88e9882fc509
+ observation: 용어·시각 자료·품질 근거·갱신 보호에 해당하는 검증 책임과 차단 조건을 구체적인 계약으로 구분한다.
+ task-usability:
+ score: 4
+ evidence:
+ - artifact: README.candidate.md
+ section-id: installation
+ line-start: 28
+ line-end: 42
+ content-hash: sha256:0854377cd971afc6408b317ba1308f319f8a2025bef86dfac262ab253e999565
+ observation: 전제조건, 복사 가능한 설치 명령과 새 가상환경에서의 미검증 범위를 함께 밝혀 설치 판단이 가능하다.
+ - artifact: README.candidate.md
+ section-id: quick-start
+ line-start: 44
+ line-end: 82
+ content-hash: sha256:ee017689603496487003245c0cb4e00a7be4ac3a0eec8921a5edb111da68d78b
+ observation: 테스트 성공 기준, 모델 기반 작성 경계, 준비 산출물과 초기화·검증 명령을 순서대로 제시한다.
+ - artifact: README.candidate.md
+ section-id: api
+ line-start: 97
+ line-end: 133
+ content-hash: sha256:86cc70fd60e94877c1de9c3db099c67df7b18adedfebff01dc84217329d11fa0
+ observation: 입력, 주요 산출물, 패치 준비와 명시적 적용 명령을 분리해 검토 후 작업을 안전하게 수행할 수 있다.
+ prose-clarity:
+ score: 4
+ evidence:
+ - artifact: README.candidate.md
+ section-id: installation
+ line-start: 28
+ line-end: 42
+ content-hash: sha256:0854377cd971afc6408b317ba1308f319f8a2025bef86dfac262ab253e999565
+ observation: 런타임과 패키지 식별자를 인라인 코드로 구별하고 전제조건과 검증 한계를 직접적인 한국어로 설명한다.
+ - artifact: README.candidate.md
+ section-id: quick-start
+ line-start: 44
+ line-end: 82
+ content-hash: sha256:ee017689603496487003245c0cb4e00a7be4ac3a0eec8921a5edb111da68d78b
+ observation: 독립 실행 도구가 아니라는 제한과 독자가 요청할 행동을 먼저 밝히며 기술 식별자는 인라인 코드로 구별한다.
+ - artifact: README.candidate.md
+ section-id: safeguards
+ line-start: 168
+ line-end: 186
+ content-hash: sha256:f4aeba8e1e5aae86600fc4f2c70f10da1b67120222cf8c45912b88e9882fc509
+ observation: 반복 종결 경고는 있으나 항목 구조와 구체적인 현재형 동사가 함께 쓰여 이해를 방해하지 않는다.
+ visual-judgment:
+ score: 5
+ evidence:
+ - artifact: README.candidate.md
+ section-id: architecture
+ line-start: 135
+ line-end: 166
+ content-hash: sha256:f39304dc61c0a017a37676b2077d572aaf9c8bd78b24ae51eb125762d41ef623
+ observation: 단일 Mermaid 흐름도가 두 입력의 결합, 작성과 그림의 합류, 독립 심사, 재작업과 명시적 적용을 한 화면에 보여 준다.
+hard-gates:
+ passed: true
+ failures: []
+reader-simulations:
+ 30-seconds:
+ outcome: PASS
+ evidence:
+ - artifact: README.candidate.md
+ section-id: overview
+ line-start: 12
+ line-end: 26
+ content-hash: sha256:e6881327a3a749eecb74b02636fbc9c3d254ce9b952896f59c7093d0d89e2799
+ observation: 도구의 정체성, 안전 목적과 README를 작성·갱신하는 개발자라는 대상을 모두 확인할 수 있다.
+ 5-minutes:
+ outcome: PASS
+ evidence:
+ - artifact: README.candidate.md
+ section-id: quick-start
+ line-start: 44
+ line-end: 82
+ content-hash: sha256:ee017689603496487003245c0cb4e00a7be4ac3a0eec8921a5edb111da68d78b
+ observation: 테스트 성공 기준, 모델 기반 작성 요청, 준비 산출물, 초기화와 결정론적 게이트 재생 순서를 확인할 수 있다.
+ - artifact: README.candidate.md
+ section-id: architecture
+ line-start: 135
+ line-end: 166
+ content-hash: sha256:f39304dc61c0a017a37676b2077d572aaf9c8bd78b24ae51eb125762d41ef623
+ observation: 요구와 근거가 작성·검사·독립 심사·재작업·적용으로 이어지는 전체 구조를 한 화면에서 식별할 수 있다.
+ - artifact: README.candidate.md
+ section-id: limitations
+ line-start: 214
+ line-end: 224
+ content-hash: sha256:10ae2331d6b1858e08b4affefc718b064393da0947295bf78246e4f6eb6c2038
+ observation: 모델 작성 의존성, 도구 간 동등성 미검증, 정적 명령 검증과 미실행 품질 벤치마크를 현재 한계로 구분한다.
+ contributor:
+ outcome: PASS
+ evidence:
+ - artifact: README.candidate.md
+ section-id: tests
+ line-start: 188
+ line-end: 199
+ content-hash: sha256:7eb8e5a521f7d6a821377078e40f288a27fd197437a9bd25922013f5a11bc927
+ observation: 전체 테스트 명령, CI 환경과 자체 README 계약 범위를 기여 전에 확인할 수 있다.
+ - artifact: README.candidate.md
+ section-id: documentation
+ line-start: 201
+ line-end: 212
+ content-hash: sha256:97129977e42c81be1ff70cdfa2402147fed9366468c0e39dc48ba71b1c0259b2
+ observation: 구현·규칙·테스트 위치를 구분하고 아키텍처·상태기계·계측·벤치마크 상세 문서로 이동할 수 있다.
+findings: []
diff --git a/runs/readme-harness/20260720-review-remediation/review.md b/runs/readme-harness/20260720-review-remediation/review.md
new file mode 100644
index 0000000..e19e1d1
--- /dev/null
+++ b/runs/readme-harness/20260720-review-remediation/review.md
@@ -0,0 +1,22 @@
+# README quality review
+
+Verdict: **PASS** — 90/100
+
+## Dimension scores
+
+- project-specificity: 5/5
+- reader-journey: 5/5
+- technical-explanation: 4/5
+- task-usability: 4/5
+- prose-clarity: 4/5
+- visual-judgment: 5/5
+
+## Reader simulations
+
+- 30-seconds: PASS
+- 5-minutes: PASS
+- contributor: PASS
+
+## Findings
+
+No findings.
diff --git a/runs/readme-harness/20260720-review-remediation/run-manifest.json b/runs/readme-harness/20260720-review-remediation/run-manifest.json
new file mode 100644
index 0000000..6012994
--- /dev/null
+++ b/runs/readme-harness/20260720-review-remediation/run-manifest.json
@@ -0,0 +1,12 @@
+{
+ "schema-version": 1,
+ "run-id": "20260720-review-remediation",
+ "repo-id": "readme-harness",
+ "mode": "bootstrap",
+ "target-repository": "/home/donghyeon/workspace/ai-tool/readme-harness",
+ "harness-version": "0.1.0",
+ "started-at": null,
+ "tool-adapter": "codex",
+ "input-hashes": {},
+ "usage": {}
+}
diff --git a/runs/readme-harness/20260720-review-remediation/state.json b/runs/readme-harness/20260720-review-remediation/state.json
new file mode 100644
index 0000000..76cfc1e
--- /dev/null
+++ b/runs/readme-harness/20260720-review-remediation/state.json
@@ -0,0 +1,347 @@
+{
+ "schema-version": 1,
+ "mode": "bootstrap",
+ "current": "APPLIED",
+ "history": [
+ {
+ "state": "INITIALIZED"
+ },
+ {
+ "state": "INPUT_CAPTURED",
+ "gates": [
+ {
+ "name": "request",
+ "ok": true,
+ "warnings": [],
+ "data": null
+ }
+ ]
+ },
+ {
+ "state": "REPOSITORY_SNAPSHOTTED",
+ "gates": [
+ {
+ "name": "snapshot",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "diff-hash": "sha256:8ea3e3693ce644a2576f9a8670088a36e5964ac8edaca5b279f7281e44aa428b"
+ }
+ }
+ ]
+ },
+ {
+ "state": "FACTS_EXTRACTED",
+ "gates": [
+ {
+ "name": "facts",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "fact_ids": [
+ "F-PROJECT-001",
+ "F-RUNTIME-001",
+ "F-DEPENDENCY-001",
+ "F-MODE-001",
+ "F-TOOL-001",
+ "F-STATE-001",
+ "F-VISUAL-001",
+ "F-DRIVER-001",
+ "F-AUTHORING-001",
+ "F-TERM-001",
+ "F-CLASSIFY-001",
+ "F-REVIEW-001",
+ "F-AUDIT-001",
+ "F-APPLY-001",
+ "F-MERGE-001",
+ "F-LAYOUT-001",
+ "F-ARTIFACT-001",
+ "F-SELF-README-001",
+ "F-CI-001",
+ "F-USAGE-001",
+ "F-BENCH-001",
+ "F-LIMIT-001"
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "state": "PROJECT_PROFILED",
+ "gates": [
+ {
+ "name": "profile",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "profile": "library"
+ }
+ }
+ ]
+ },
+ {
+ "state": "README_PLANNED",
+ "gates": [
+ {
+ "name": "brief",
+ "ok": true,
+ "warnings": [],
+ "data": null
+ },
+ {
+ "name": "outline",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "section_ids": [
+ "overview",
+ "installation",
+ "quick-start",
+ "usage",
+ "api",
+ "architecture",
+ "safeguards",
+ "tests",
+ "documentation",
+ "limitations"
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "state": "README_DRAFTED",
+ "gates": [
+ {
+ "name": "conformance",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "sections": [
+ "overview",
+ "installation",
+ "quick-start",
+ "usage",
+ "api",
+ "architecture",
+ "safeguards",
+ "tests",
+ "documentation",
+ "limitations"
+ ]
+ }
+ },
+ {
+ "name": "claim_map",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "claims": [
+ "C-PROJECT-001",
+ "C-MODE-001",
+ "C-SAFETY-SUMMARY-001",
+ "C-LIMIT-001",
+ "C-RUNTIME-001",
+ "C-INSTALL-001",
+ "C-TEST-COMMAND-001",
+ "C-AUTHORING-001",
+ "C-INIT-001",
+ "C-BOOTSTRAP-001",
+ "C-USAGE-001",
+ "C-INPUT-001",
+ "C-USAGE-METRICS-001",
+ "C-PREPARE-001",
+ "C-APPLY-001",
+ "C-FLOW-001",
+ "C-TERM-001",
+ "C-VISUAL-001",
+ "C-REVIEW-001",
+ "C-AUDIT-001",
+ "C-MERGE-001",
+ "C-APPLY-SAFETY-001",
+ "C-CI-001",
+ "C-LAYOUT-001",
+ "C-LIMIT-002",
+ "C-VERIFY-LIMIT-001",
+ "C-BENCH-LIMIT-001"
+ ],
+ "derived-statements": {
+ "C-PROJECT-001": "이 하네스는 저장소의 실제 코드와 사용 목적을 바탕으로 문서 후보를 만들고,\n명령·경로·근거를 검사한 뒤 검토 가능한 패치로 제공합니다.",
+ "C-MODE-001": "`bootstrap`, `audit`, `refresh`, `section-update` 네 모드를 구현했습니다.",
+ "C-SAFETY-SUMMARY-001": "저장소 근거와 사용자 요구를 분리해 읽고, 고위험 사실을 근거에 연결합니다. 그림을\n넣기로 했다면 실제 소스나 자산까지 확인하고, 품질 심사는 원문의 줄과 해시에 묶인\n근거를 사용합니다. 패치 준비가 끝나도 대상 `README.md`는 자동으로 바뀌지 않습니다.",
+ "C-LIMIT-001": "결정론적 Codex 경로는 구현됐습니다. 후보 문장 작성은 모델 파이프라인이 담당하며,\n다른 도구와의 런타임 동등성은 Phase 4 검증 전까지 보장하지 않습니다.",
+ "C-RUNTIME-001": "`Python` 3.12 이상이 필요합니다.\n런타임 의존성은 `jsonschema`와 `PyYAML`입니다.\n개발 의존성은 `pytest`입니다.",
+ "C-INSTALL-001": "이 설치 명령은 프로젝트 선언에서 확인했지만, 현재 작업에서는 새 가상환경 설치까지\n실행해 증명하지 않았습니다.",
+ "C-TEST-COMMAND-001": "자체 README 테스트는 이 명령을 최소 실행 경로로 요구합니다. 다른 운영체제와 새\n가상환경의 동일한 결과까지 보장하는 계약은 아닙니다.",
+ "C-AUTHORING-001": "이 프로젝트는 명령 하나로 문서를 완성하는 독립 실행 도구가 아닙니다. Codex 작업 공간에서\n`requirement-driven-readme` 스킬로 대상 저장소의 `bootstrap` 실행을 요청하면 작성\n역할이 사용자 요구, 저장소 근거, 개요, 후보, 주장 지도, 그림 계획과 품질 심사\n산출물을 준비합니다.",
+ "C-INIT-001": "이 명령은 `runs/demo/first`에 상태와 실행 매니페스트를 초기화합니다.",
+ "C-BOOTSTRAP-001": "드라이버는 후보를 새로 쓰지 않고 준비된 산출물을 `QUALITY_REVIEWED`까지\n검증합니다.",
+ "C-USAGE-001": "네 모드는 요청 스키마에 선언되어 있고 각 흐름의 상태·게이트 계약이 구현되어\n있습니다.",
+ "C-INPUT-001": "`readme-request.yaml`은 독자, 언어, 길이, 보존 범위, 공개 용어, 그림 정책을\n정합니다. 기술 사실은 `repository-facts.yaml`에 저장하고, 각 실행은\n`runs//` 아래에서 격리합니다.",
+ "C-USAGE-METRICS-001": "어댑터가 제공하는 단계별 모델 사용량은 실행 매니페스트에 누적합니다. 제공되지\n않은 값은 0으로 추정하지 않습니다.",
+ "C-PREPARE-001": "이 단계는 `README.generated.md`, `README.patch`, `apply-manifest.yaml`을 만들고\n상태를 `READY_FOR_APPLY`로 전진시킵니다.",
+ "C-APPLY-001": "적용 직전에 후보·저장소·대상 README 해시와 경로 경계를 다시 검사합니다.",
+ "C-FLOW-001": "사용자 요구는 독자 흐름과 공개 용어, 그림 결정을 만듭니다. 대상 저장소에서는\n근거와 프로젝트 유형을 수집합니다. 두 입력이 합쳐진 후보와 시각 자료는 결정론적\n게이트와 독립 품질 심사를 통과해야 패치가 됩니다.",
+ "C-TERM-001": "- 명령·버전·전제조건·모듈·경로·보장·한계 주장은 저장소 근거에 연결합니다.\n- 인라인 코드의 영문 표현이 실제 식별자인지 확인하고 내부 전용 용어의 공개 노출을\n 차단합니다.",
+ "C-VISUAL-001": "- 명령·버전·전제조건·모듈·경로·보장·한계 주장은 저장소 근거에 연결합니다.\n- 인라인 코드의 영문 표현이 실제 식별자인지 확인하고 내부 전용 용어의 공개 노출을\n 차단합니다. \n- 그림을 포함하기로 한 개요 결정, 계획 항목, README 마커, 생성 소스나 자산이\n 일치해야 시각 자료 게이트를 통과합니다.",
+ "C-REVIEW-001": "- 명령·버전·전제조건·모듈·경로·보장·한계 주장은 저장소 근거에 연결합니다.\n- 인라인 코드의 영문 표현이 실제 식별자인지 확인하고 내부 전용 용어의 공개 노출을\n 차단합니다. \n- 그림을 포함하기로 한 개요 결정, 계획 항목, README 마커, 생성 소스나 자산이\n 일치해야 시각 자료 게이트를 통과합니다. \n- 품질 점수와 독자 과업 근거의 줄 범위와 해시를 실제 후보에 대조하고,\n `review.md`는 검증된 YAML에서 렌더링합니다.",
+ "C-AUDIT-001": "- 명령·버전·전제조건·모듈·경로·보장·한계 주장은 저장소 근거에 연결합니다.\n- 인라인 코드의 영문 표현이 실제 식별자인지 확인하고 내부 전용 용어의 공개 노출을\n 차단합니다. \n- 그림을 포함하기로 한 개요 결정, 계획 항목, README 마커, 생성 소스나 자산이\n 일치해야 시각 자료 게이트를 통과합니다. \n- 품질 점수와 독자 과업 근거의 줄 범위와 해시를 실제 후보에 대조하고,\n `review.md`는 검증된 YAML에서 렌더링합니다. \n- 감사 모드는 결과 스키마를 확인하고 산출물을 원자적으로 기록한 다음 완료 상태로\n 전진합니다.",
+ "C-MERGE-001": "- 명령·버전·전제조건·모듈·경로·보장·한계 주장은 저장소 근거에 연결합니다.\n- 인라인 코드의 영문 표현이 실제 식별자인지 확인하고 내부 전용 용어의 공개 노출을\n 차단합니다. \n- 그림을 포함하기로 한 개요 결정, 계획 항목, README 마커, 생성 소스나 자산이\n 일치해야 시각 자료 게이트를 통과합니다. \n- 품질 점수와 독자 과업 근거의 줄 범위와 해시를 실제 후보에 대조하고,\n `review.md`는 검증된 YAML에서 렌더링합니다. \n- 감사 모드는 결과 스키마를 확인하고 산출물을 원자적으로 기록한 다음 완료 상태로\n 전진합니다. \n- 갱신 모드는 보호 영역과 마커 밖 문장을 보존하며, 사람이 고친 관리 영역과 새\n 후보가 충돌하면 자동 적용을 막습니다.",
+ "C-APPLY-SAFETY-001": "- 명령·버전·전제조건·모듈·경로·보장·한계 주장은 저장소 근거에 연결합니다.\n- 인라인 코드의 영문 표현이 실제 식별자인지 확인하고 내부 전용 용어의 공개 노출을\n 차단합니다. \n- 그림을 포함하기로 한 개요 결정, 계획 항목, README 마커, 생성 소스나 자산이\n 일치해야 시각 자료 게이트를 통과합니다. \n- 품질 점수와 독자 과업 근거의 줄 범위와 해시를 실제 후보에 대조하고,\n `review.md`는 검증된 YAML에서 렌더링합니다. \n- 감사 모드는 결과 스키마를 확인하고 산출물을 원자적으로 기록한 다음 완료 상태로\n 전진합니다. \n- 갱신 모드는 보호 영역과 마커 밖 문장을 보존하며, 사람이 고친 관리 영역과 새\n 후보가 충돌하면 자동 적용을 막습니다. \n- 비밀 값, 저장소 밖 경로, 오래된 스냅숏, 검토 뒤 바뀐 산출물은 패치 준비나\n 적용을 차단합니다.",
+ "C-CI-001": "GitHub Actions는 의존성을 설치한 뒤 전체 테스트를 실행합니다. 실행 환경은\nPython 3.12입니다. 자체 README 테스트는 라이브러리 프로파일, 30초 독자 흐름, 최소 실행\n경로, Mermaid 그림 결정을 확인합니다.",
+ "C-LAYOUT-001": "주요 구현은 `src/readme_harness`, 스키마·규칙·워크플로는 `.agents`, 테스트는\n`tests`에 있습니다.",
+ "C-LIMIT-002": "- 후보 작성은 LLM 파이프라인의 판단에 의존합니다. 결정론적 드라이버는 준비된\n 산출물을 검증하고 상태를 전진시킵니다.\n- 네 모드의 결정론적 경로는 구현됐지만 도구 간 런타임 동등성은 Phase 4 검증\n 목표입니다.",
+ "C-VERIFY-LIMIT-001": "- 후보 작성은 LLM 파이프라인의 판단에 의존합니다. 결정론적 드라이버는 준비된\n 산출물을 검증하고 상태를 전진시킵니다.\n- 네 모드의 결정론적 경로는 구현됐지만 도구 간 런타임 동등성은 Phase 4 검증\n 목표입니다. \n- 명령 검증 보고서의 기본 수준은 정적 검사입니다. 실행을 별도로 기록하지 않은\n 명령은 실제 실행 성공을 뜻하지 않습니다.",
+ "C-BENCH-LIMIT-001": "- 후보 작성은 LLM 파이프라인의 판단에 의존합니다. 결정론적 드라이버는 준비된\n 산출물을 검증하고 상태를 전진시킵니다.\n- 네 모드의 결정론적 경로는 구현됐지만 도구 간 런타임 동등성은 Phase 4 검증\n 목표입니다. \n- 명령 검증 보고서의 기본 수준은 정적 검사입니다. 실행을 별도로 기록하지 않은\n 명령은 실제 실행 성공을 뜻하지 않습니다. \n- 여덟 저장소 유형의 블라인드 비교 계약은 마련했지만 결과 상태는 아직 `not-run`입니다.\n `PASS` 결과 전에는 품질 우월성을 주장하지 않습니다."
+ }
+ }
+ }
+ ]
+ },
+ {
+ "state": "VISUALS_PLANNED",
+ "gates": [
+ {
+ "name": "visual_plan",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "visuals": [
+ "harness-flow"
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "state": "STRUCTURALLY_VALIDATED",
+ "gates": [
+ {
+ "name": "github_markdown",
+ "ok": true,
+ "warnings": [],
+ "data": null
+ },
+ {
+ "name": "reader_prose",
+ "ok": true,
+ "warnings": [
+ "KO-REPEATED-ENDING line 4: 같은 문장 종결이 이어져 설명이 기계적으로 들릴 수 있습니다."
+ ],
+ "data": {
+ "schema-version": 1,
+ "policy-id": "korean-reader-prose-v1",
+ "language": "ko-KR",
+ "applicable": true,
+ "scope": "candidate",
+ "state": "PASS_WITH_WARNINGS",
+ "summary": {
+ "errors": 0,
+ "warnings": 1,
+ "sentences": 108,
+ "prose-characters": 2081,
+ "hangul-characters": 1839
+ },
+ "findings": [
+ {
+ "rule-id": "KO-REPEATED-ENDING",
+ "severity": "warning",
+ "line": 4,
+ "section": "README Harness",
+ "region-kind": "candidate",
+ "excerpt": "합니다 (29/43문장)",
+ "message": "같은 문장 종결이 이어져 설명이 기계적으로 들릴 수 있습니다.",
+ "suggestion": "정의, 절차, 제한에 맞춰 현재형 동사와 명사형 표제를 섞어 쓰세요.",
+ "source-ids": [
+ "NIKL-EASY-PUBLIC-LANGUAGE"
+ ],
+ "id": "P-001"
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "state": "TECHNICALLY_VERIFIED",
+ "gates": [
+ {
+ "name": "verify",
+ "ok": true,
+ "warnings": [
+ "manual verification required: python3 -m pip install -e \".[dev]\" (unsupported-static-verifier)",
+ "manual verification required: python3 -m pytest -q (unsupported-static-verifier)"
+ ],
+ "data": {
+ "schema-version": 1,
+ "state": "PASS_WITH_MANUAL",
+ "verification-level": "static",
+ "execution-verified": false,
+ "checks": {
+ "commands": {
+ "total": 6,
+ "verified": 4,
+ "manual-required": 2,
+ "failed": 0
+ },
+ "paths": {
+ "total": 9,
+ "verified": 9,
+ "failed": 0
+ },
+ "anchors": {
+ "total": 0,
+ "verified": 0,
+ "failed": 0
+ },
+ "readme-contracts": {
+ "total": 0,
+ "verified": 0,
+ "failed": 0
+ }
+ },
+ "failures": [],
+ "limitations": [
+ "manual verification required: python3 -m pip install -e \".[dev]\" (unsupported-static-verifier)",
+ "manual verification required: python3 -m pytest -q (unsupported-static-verifier)"
+ ]
+ }
+ },
+ {
+ "name": "secret_scan",
+ "ok": true,
+ "warnings": [],
+ "data": null
+ }
+ ]
+ },
+ {
+ "state": "QUALITY_REVIEWED",
+ "gates": [
+ {
+ "name": "review",
+ "ok": true,
+ "warnings": [],
+ "data": {
+ "verdict": "PASS",
+ "score": 90,
+ "findings": [],
+ "report-valid": true
+ }
+ }
+ ]
+ },
+ {
+ "state": "READY_FOR_APPLY",
+ "gates": []
+ },
+ {
+ "state": "APPLIED",
+ "gates": []
+ }
+ ],
+ "rework": {
+ "iterations": 0,
+ "findings": {}
+ }
+}
\ No newline at end of file
diff --git a/runs/readme-harness/20260720-review-remediation/verification.json b/runs/readme-harness/20260720-review-remediation/verification.json
new file mode 100644
index 0000000..c11a6cf
--- /dev/null
+++ b/runs/readme-harness/20260720-review-remediation/verification.json
@@ -0,0 +1,34 @@
+{
+ "schema-version": 1,
+ "state": "PASS_WITH_MANUAL",
+ "verification-level": "static",
+ "execution-verified": false,
+ "checks": {
+ "commands": {
+ "total": 6,
+ "verified": 4,
+ "manual-required": 2,
+ "failed": 0
+ },
+ "paths": {
+ "total": 9,
+ "verified": 9,
+ "failed": 0
+ },
+ "anchors": {
+ "total": 0,
+ "verified": 0,
+ "failed": 0
+ },
+ "readme-contracts": {
+ "total": 0,
+ "verified": 0,
+ "failed": 0
+ }
+ },
+ "failures": [],
+ "limitations": [
+ "manual verification required: python3 -m pip install -e \".[dev]\" (unsupported-static-verifier)",
+ "manual verification required: python3 -m pytest -q (unsupported-static-verifier)"
+ ]
+}
\ No newline at end of file
diff --git a/runs/readme-harness/20260720-review-remediation/visual-plan.yaml b/runs/readme-harness/20260720-review-remediation/visual-plan.yaml
new file mode 100644
index 0000000..0e5a19a
--- /dev/null
+++ b/runs/readme-harness/20260720-review-remediation/visual-plan.yaml
@@ -0,0 +1,40 @@
+schema-version: 1
+visuals:
+ - id: harness-flow
+ section: architecture
+ type: request-flow
+ purpose: 저장소 분석과 사용자 요구가 후보 작성, 그림 생성, 결정론적 게이트, 독립 품질 심사를 거쳐 패치와 명시적 적용으로 이어지는 흐름을 보여준다.
+ placeholder-text: 왼쪽의 두 입력이 계획에서 합쳐지고 작성과 그림이 검증으로 모인 뒤 품질 심사에서 재작업 또는 적용으로 갈라지는 Mermaid 흐름도다.
+ must-show:
+ - 사용자 요구와 대상 저장소라는 두 입력
+ - 독자 흐름·용어·그림 결정과 저장소 근거·프로젝트 분류
+ - README 작성과 그림 소스·자산 생성
+ - 근거·명령·경로·문체 검사와 독립 품질 심사
+ - 수정 필요 시 계획으로 돌아가는 재작업
+ - 통과 후 패치 준비와 명시적 적용
+ - 해시 기반 실행 산출물
+ relationships:
+ - 사용자 요구 -> 독자 흐름·용어·그림 결정
+ - 대상 저장소 -> 근거 수집·프로젝트 분류
+ - 근거 수집·프로젝트 분류 -> 독자 흐름·용어·그림 결정
+ - 계획 -> README 작성
+ - 계획 -> 그림 소스·자산 생성
+ - README 작성 + 그림 -> 결정론적 검사
+ - 결정론적 검사 -> 독립 품질 심사
+ - 독립 품질 심사 -> 계획 (수정 필요)
+ - 독립 품질 심사 -> 패치 준비·명시적 적용 (통과)
+ emphasize:
+ - 의미 판단과 결정론적 검증의 경계를 별도 노드로 나눈다.
+ - 재작업 화살표와 정방향 적용 흐름을 다른 라벨로 구분한다.
+ - 해시 기반 산출물이 분석·계획·검증·적용에 연결됨을 보인다.
+ avoid:
+ - 전체 내부 상태 이름을 노드에 나열하지 않는다.
+ - Claude와 Antigravity 런타임 동등성을 구현 완료처럼 표현하지 않는다.
+ - 자동 적용처럼 보이는 우회 경로를 만들지 않는다.
+ placement:
+ after-section-id: architecture
+ accessibility:
+ alt-text: 사용자 요구와 대상 저장소에서 출발해 계획, README와 그림 작성, 결정론적 검사, 독립 품질 심사를 거친다. 수정이 필요하면 계획으로 돌아가고 통과하면 패치를 준비한 뒤 별도로 적용한다.
+ production:
+ format: mermaid
+ status: embedded
diff --git a/src/readme_harness.egg-info/PKG-INFO b/src/readme_harness.egg-info/PKG-INFO
new file mode 100644
index 0000000..6347a30
--- /dev/null
+++ b/src/readme_harness.egg-info/PKG-INFO
@@ -0,0 +1,7 @@
+Metadata-Version: 2.4
+Name: readme-harness
+Version: 0.2.0
+Requires-Python: >=3.12
+Requires-Dist: PyYAML>=6.0
+Provides-Extra: dev
+Requires-Dist: pytest>=8.0; extra == "dev"
diff --git a/src/readme_harness.egg-info/SOURCES.txt b/src/readme_harness.egg-info/SOURCES.txt
new file mode 100644
index 0000000..eec5247
--- /dev/null
+++ b/src/readme_harness.egg-info/SOURCES.txt
@@ -0,0 +1,26 @@
+README.md
+pyproject.toml
+src/readme_harness/__init__.py
+src/readme_harness/claims.py
+src/readme_harness/cli.py
+src/readme_harness/common.py
+src/readme_harness/core.py
+src/readme_harness/facts.py
+src/readme_harness/gh_markdown.py
+src/readme_harness/markers.py
+src/readme_harness/patch.py
+src/readme_harness/paths.py
+src/readme_harness/quality.py
+src/readme_harness/readme_parse.py
+src/readme_harness/review.py
+src/readme_harness/scan.py
+src/readme_harness/secrets.py
+src/readme_harness/verify.py
+src/readme_harness.egg-info/PKG-INFO
+src/readme_harness.egg-info/SOURCES.txt
+src/readme_harness.egg-info/dependency_links.txt
+src/readme_harness.egg-info/entry_points.txt
+src/readme_harness.egg-info/requires.txt
+src/readme_harness.egg-info/top_level.txt
+tests/test_lean_harness.py
+tests/test_quality_fixtures.py
\ No newline at end of file
diff --git a/src/readme_harness.egg-info/dependency_links.txt b/src/readme_harness.egg-info/dependency_links.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/src/readme_harness.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/src/readme_harness.egg-info/entry_points.txt b/src/readme_harness.egg-info/entry_points.txt
new file mode 100644
index 0000000..41baa93
--- /dev/null
+++ b/src/readme_harness.egg-info/entry_points.txt
@@ -0,0 +1,2 @@
+[console_scripts]
+readme-harness = readme_harness.cli:main
diff --git a/src/readme_harness.egg-info/requires.txt b/src/readme_harness.egg-info/requires.txt
new file mode 100644
index 0000000..52da150
--- /dev/null
+++ b/src/readme_harness.egg-info/requires.txt
@@ -0,0 +1,4 @@
+PyYAML>=6.0
+
+[dev]
+pytest>=8.0
diff --git a/src/readme_harness.egg-info/top_level.txt b/src/readme_harness.egg-info/top_level.txt
new file mode 100644
index 0000000..d76e496
--- /dev/null
+++ b/src/readme_harness.egg-info/top_level.txt
@@ -0,0 +1 @@
+readme_harness
diff --git a/src/readme_harness/__init__.py b/src/readme_harness/__init__.py
new file mode 100644
index 0000000..ea0612f
--- /dev/null
+++ b/src/readme_harness/__init__.py
@@ -0,0 +1,7 @@
+"""A small, review-first README writing harness."""
+
+__version__ = "0.2.0"
+
+from .core import build_readme
+
+__all__ = ["build_readme"]
diff --git a/src/readme_harness/__pycache__/__init__.cpython-312.pyc b/src/readme_harness/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 0000000..7158cf3
Binary files /dev/null and b/src/readme_harness/__pycache__/__init__.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/audit.cpython-312.pyc b/src/readme_harness/__pycache__/audit.cpython-312.pyc
new file mode 100644
index 0000000..8b118f6
Binary files /dev/null and b/src/readme_harness/__pycache__/audit.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/benchmark.cpython-312.pyc b/src/readme_harness/__pycache__/benchmark.cpython-312.pyc
new file mode 100644
index 0000000..0f5af59
Binary files /dev/null and b/src/readme_harness/__pycache__/benchmark.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/brief.cpython-312.pyc b/src/readme_harness/__pycache__/brief.cpython-312.pyc
new file mode 100644
index 0000000..ea9853b
Binary files /dev/null and b/src/readme_harness/__pycache__/brief.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/claims.cpython-312.pyc b/src/readme_harness/__pycache__/claims.cpython-312.pyc
new file mode 100644
index 0000000..96ccb92
Binary files /dev/null and b/src/readme_harness/__pycache__/claims.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/classify.cpython-312.pyc b/src/readme_harness/__pycache__/classify.cpython-312.pyc
new file mode 100644
index 0000000..bb2718d
Binary files /dev/null and b/src/readme_harness/__pycache__/classify.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/cli.cpython-312.pyc b/src/readme_harness/__pycache__/cli.cpython-312.pyc
new file mode 100644
index 0000000..12a7d19
Binary files /dev/null and b/src/readme_harness/__pycache__/cli.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/common.cpython-312.pyc b/src/readme_harness/__pycache__/common.cpython-312.pyc
new file mode 100644
index 0000000..7563ceb
Binary files /dev/null and b/src/readme_harness/__pycache__/common.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/conformance.cpython-312.pyc b/src/readme_harness/__pycache__/conformance.cpython-312.pyc
new file mode 100644
index 0000000..4058bb8
Binary files /dev/null and b/src/readme_harness/__pycache__/conformance.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/core.cpython-312.pyc b/src/readme_harness/__pycache__/core.cpython-312.pyc
new file mode 100644
index 0000000..69b6354
Binary files /dev/null and b/src/readme_harness/__pycache__/core.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/facts.cpython-312.pyc b/src/readme_harness/__pycache__/facts.cpython-312.pyc
new file mode 100644
index 0000000..812c3db
Binary files /dev/null and b/src/readme_harness/__pycache__/facts.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/gh_markdown.cpython-312.pyc b/src/readme_harness/__pycache__/gh_markdown.cpython-312.pyc
new file mode 100644
index 0000000..3e16814
Binary files /dev/null and b/src/readme_harness/__pycache__/gh_markdown.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/markers.cpython-312.pyc b/src/readme_harness/__pycache__/markers.cpython-312.pyc
new file mode 100644
index 0000000..5850b40
Binary files /dev/null and b/src/readme_harness/__pycache__/markers.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/merge.cpython-312.pyc b/src/readme_harness/__pycache__/merge.cpython-312.pyc
new file mode 100644
index 0000000..d7207ae
Binary files /dev/null and b/src/readme_harness/__pycache__/merge.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/outline.cpython-312.pyc b/src/readme_harness/__pycache__/outline.cpython-312.pyc
new file mode 100644
index 0000000..bccec7d
Binary files /dev/null and b/src/readme_harness/__pycache__/outline.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/patch.cpython-312.pyc b/src/readme_harness/__pycache__/patch.cpython-312.pyc
new file mode 100644
index 0000000..0251655
Binary files /dev/null and b/src/readme_harness/__pycache__/patch.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/paths.cpython-312.pyc b/src/readme_harness/__pycache__/paths.cpython-312.pyc
new file mode 100644
index 0000000..e43eaa5
Binary files /dev/null and b/src/readme_harness/__pycache__/paths.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/postmerge.cpython-312.pyc b/src/readme_harness/__pycache__/postmerge.cpython-312.pyc
new file mode 100644
index 0000000..f43ab34
Binary files /dev/null and b/src/readme_harness/__pycache__/postmerge.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/prose.cpython-312.pyc b/src/readme_harness/__pycache__/prose.cpython-312.pyc
new file mode 100644
index 0000000..2c25d86
Binary files /dev/null and b/src/readme_harness/__pycache__/prose.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/quality.cpython-312.pyc b/src/readme_harness/__pycache__/quality.cpython-312.pyc
new file mode 100644
index 0000000..efc62ce
Binary files /dev/null and b/src/readme_harness/__pycache__/quality.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/readme_parse.cpython-312.pyc b/src/readme_harness/__pycache__/readme_parse.cpython-312.pyc
new file mode 100644
index 0000000..1a83822
Binary files /dev/null and b/src/readme_harness/__pycache__/readme_parse.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/refresh.cpython-312.pyc b/src/readme_harness/__pycache__/refresh.cpython-312.pyc
new file mode 100644
index 0000000..b78da2f
Binary files /dev/null and b/src/readme_harness/__pycache__/refresh.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/regions.cpython-312.pyc b/src/readme_harness/__pycache__/regions.cpython-312.pyc
new file mode 100644
index 0000000..1af857f
Binary files /dev/null and b/src/readme_harness/__pycache__/regions.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/request.cpython-312.pyc b/src/readme_harness/__pycache__/request.cpython-312.pyc
new file mode 100644
index 0000000..61cede2
Binary files /dev/null and b/src/readme_harness/__pycache__/request.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/review.cpython-312.pyc b/src/readme_harness/__pycache__/review.cpython-312.pyc
new file mode 100644
index 0000000..8581d9b
Binary files /dev/null and b/src/readme_harness/__pycache__/review.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/rework.cpython-312.pyc b/src/readme_harness/__pycache__/rework.cpython-312.pyc
new file mode 100644
index 0000000..b4d9f9d
Binary files /dev/null and b/src/readme_harness/__pycache__/rework.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/scan.cpython-312.pyc b/src/readme_harness/__pycache__/scan.cpython-312.pyc
new file mode 100644
index 0000000..1c5da4d
Binary files /dev/null and b/src/readme_harness/__pycache__/scan.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/schema.cpython-312.pyc b/src/readme_harness/__pycache__/schema.cpython-312.pyc
new file mode 100644
index 0000000..e88e172
Binary files /dev/null and b/src/readme_harness/__pycache__/schema.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/secrets.cpython-312.pyc b/src/readme_harness/__pycache__/secrets.cpython-312.pyc
new file mode 100644
index 0000000..4ec6de0
Binary files /dev/null and b/src/readme_harness/__pycache__/secrets.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/section_update.cpython-312.pyc b/src/readme_harness/__pycache__/section_update.cpython-312.pyc
new file mode 100644
index 0000000..cd06a27
Binary files /dev/null and b/src/readme_harness/__pycache__/section_update.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/snapshot.cpython-312.pyc b/src/readme_harness/__pycache__/snapshot.cpython-312.pyc
new file mode 100644
index 0000000..581fa23
Binary files /dev/null and b/src/readme_harness/__pycache__/snapshot.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/state.cpython-312.pyc b/src/readme_harness/__pycache__/state.cpython-312.pyc
new file mode 100644
index 0000000..28e054f
Binary files /dev/null and b/src/readme_harness/__pycache__/state.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/usage.cpython-312.pyc b/src/readme_harness/__pycache__/usage.cpython-312.pyc
new file mode 100644
index 0000000..e61e39c
Binary files /dev/null and b/src/readme_harness/__pycache__/usage.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/verify.cpython-312.pyc b/src/readme_harness/__pycache__/verify.cpython-312.pyc
new file mode 100644
index 0000000..2f778ce
Binary files /dev/null and b/src/readme_harness/__pycache__/verify.cpython-312.pyc differ
diff --git a/src/readme_harness/__pycache__/visuals.cpython-312.pyc b/src/readme_harness/__pycache__/visuals.cpython-312.pyc
new file mode 100644
index 0000000..86b0364
Binary files /dev/null and b/src/readme_harness/__pycache__/visuals.cpython-312.pyc differ
diff --git a/src/readme_harness/claims.py b/src/readme_harness/claims.py
new file mode 100644
index 0000000..ea5e8db
--- /dev/null
+++ b/src/readme_harness/claims.py
@@ -0,0 +1,132 @@
+from __future__ import annotations
+
+import re
+
+from .common import GateResult, sha256_bytes
+
+_HARNESS_COMMENT = re.compile(
+ r"",
+ re.IGNORECASE,
+)
+
+
+def reader_markdown(markdown: str) -> str:
+ """Return exactly what a GitHub reader should see: ordinary Markdown only."""
+ cleaned = _HARNESS_COMMENT.sub("", markdown)
+ cleaned = re.sub(r"[ \t]+\n", "\n", cleaned)
+ cleaned = re.sub(r"\n{3,}", "\n\n", cleaned).strip()
+ return cleaned + "\n"
+
+
+def blocks(markdown: str) -> list[dict]:
+ """Split reader Markdown into addressable section blocks.
+
+ Paragraphs, individual list items, whole tables, and fenced code blocks are
+ stable review units. They let the harness keep claims outside the README.
+ """
+ markdown = reader_markdown(markdown)
+ result: list[dict] = []
+ section = "document"
+ counts: dict[str, int] = {}
+ buffer: list[str] = []
+ kind = "paragraph"
+ in_fence = False
+
+ def flush() -> None:
+ nonlocal buffer, kind
+ text = "\n".join(buffer).strip()
+ if text:
+ index = counts.get(section, 0)
+ result.append({
+ "section": section,
+ "block": index,
+ "kind": kind,
+ "text": text,
+ "text-hash": sha256_bytes(text.encode("utf-8")),
+ })
+ counts[section] = index + 1
+ buffer = []
+ kind = "paragraph"
+
+ for line in markdown.splitlines():
+ heading = re.match(r"^#{1,6}\s+(.+?)\s*$", line)
+ if heading and not in_fence:
+ flush()
+ section = re.sub(r"[*_`~]", "", heading.group(1)).strip()
+ continue
+ if line.lstrip().startswith("```"):
+ if not in_fence:
+ flush()
+ kind = "code"
+ buffer.append(line)
+ in_fence = not in_fence
+ if not in_fence:
+ flush()
+ continue
+ if in_fence:
+ buffer.append(line)
+ continue
+ if not line.strip():
+ flush()
+ continue
+ if re.match(r"^\s*(?:[-*+] |\d+[.)]\s+)", line):
+ flush()
+ kind = "list-item"
+ buffer = [line]
+ flush()
+ continue
+ if "|" in line:
+ if kind != "table" and buffer:
+ flush()
+ kind = "table"
+ buffer.append(line)
+ continue
+ if kind == "table":
+ flush()
+ buffer.append(line)
+ flush()
+ return result
+
+
+def bind_claims(markdown: str, bindings: list[dict]) -> tuple[list[dict], list[str]]:
+ available = {(item["section"], item["block"]): item for item in blocks(markdown)}
+ claims: list[dict] = []
+ errors: list[str] = []
+ for binding in bindings:
+ key = (binding.get("section"), binding.get("block"))
+ block = available.get(key)
+ if block is None:
+ errors.append(f"claim binding refers to unknown block: {key[0]}[{key[1]}]")
+ continue
+ claims.append({
+ "section": key[0],
+ "block": key[1],
+ "kind": block["kind"],
+ "text-hash": block["text-hash"],
+ "fact-ids": list(binding.get("fact-ids", [])),
+ })
+ return claims, errors
+
+
+def validate_external_claims(markdown: str, claims: list[dict], fact_ids: set[str]) -> GateResult:
+ available = {(item["section"], item["block"]): item for item in blocks(markdown)}
+ errors: list[str] = []
+ seen: set[tuple[str, int]] = set()
+ for claim in claims:
+ key = (claim.get("section"), claim.get("block"))
+ if key in seen:
+ errors.append(f"duplicate claim binding: {key[0]}[{key[1]}]")
+ seen.add(key)
+ block = available.get(key)
+ if block is None:
+ errors.append(f"claim refers to missing block: {key[0]}[{key[1]}]")
+ continue
+ if claim.get("text-hash") != block["text-hash"]:
+ errors.append(f"claim hash is stale: {key[0]}[{key[1]}]")
+ sources = claim.get("fact-ids", [])
+ if not sources:
+ errors.append(f"claim has no fact ids: {key[0]}[{key[1]}]")
+ for fact_id in sources:
+ if fact_id not in fact_ids:
+ errors.append(f"claim refers to unknown fact id: {fact_id}")
+ return GateResult.failed(errors) if errors else GateResult.passed({"claims": len(claims)})
diff --git a/src/readme_harness/cli.py b/src/readme_harness/cli.py
new file mode 100644
index 0000000..6c470a2
--- /dev/null
+++ b/src/readme_harness/cli.py
@@ -0,0 +1,66 @@
+from __future__ import annotations
+
+import argparse
+import sys
+
+from .core import apply_reviewed_readme, audit_readme, build_readme
+
+
+def _parser() -> argparse.ArgumentParser:
+ parser = argparse.ArgumentParser(prog="readme-harness")
+ sub = parser.add_subparsers(dest="command", required=True)
+ generate = sub.add_parser("generate", help="validate a draft and prepare a patch")
+ generate.add_argument("repository")
+ generate.add_argument("--draft", required=True)
+ generate.add_argument("--request")
+ generate.add_argument("--facts")
+ generate.add_argument("--review")
+ generate.add_argument("--output-dir")
+ generate.add_argument("--target", default="README.md")
+ audit = sub.add_parser("audit", help="inspect an existing README without rewriting it")
+ audit.add_argument("repository")
+ audit.add_argument("--readme")
+ audit.add_argument("--facts")
+ audit.add_argument("--output-dir")
+ apply = sub.add_parser("apply", help="apply a separately reviewed READY build")
+ apply.add_argument("repository")
+ apply.add_argument("--output-dir")
+ apply.add_argument("--target", default="README.md")
+ return parser
+
+
+def main(argv=None) -> int:
+ args = _parser().parse_args(argv)
+ if args.command == "apply":
+ apply_reviewed_readme(args.repository, output_dir=args.output_dir, target=args.target)
+ return 0
+ if args.command == "audit":
+ result = audit_readme(
+ args.repository, readme=args.readme, facts=args.facts,
+ output_dir=args.output_dir,
+ )
+ print(f"{result.status}: {result.output_dir}")
+ for warning in result.warnings:
+ print(f"warning: {warning}", file=sys.stderr)
+ for error in result.errors:
+ print(f"error: {error}", file=sys.stderr)
+ return 0 if result.status == "PASS" else 1
+ result = build_readme(
+ args.repository,
+ args.draft,
+ request=args.request,
+ facts=args.facts,
+ review=args.review,
+ output_dir=args.output_dir,
+ target_readme=args.target,
+ )
+ print(f"{result.status}: {result.output_dir}")
+ for warning in result.warnings:
+ print(f"warning: {warning}", file=sys.stderr)
+ for error in result.errors:
+ print(f"error: {error}", file=sys.stderr)
+ return 0 if result.status in {"READY", "REVIEW_REQUIRED"} else 1
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/src/readme_harness/common.py b/src/readme_harness/common.py
new file mode 100644
index 0000000..5ec3030
--- /dev/null
+++ b/src/readme_harness/common.py
@@ -0,0 +1,78 @@
+from __future__ import annotations
+
+import hashlib
+import json
+import os
+import sys
+from dataclasses import dataclass, field
+from pathlib import Path
+from typing import Any
+
+import yaml
+
+
+@dataclass
+class GateResult:
+ ok: bool
+ errors: list[str] = field(default_factory=list)
+ warnings: list[str] = field(default_factory=list)
+ data: dict | None = None
+
+ @classmethod
+ def passed(cls, data: dict | None = None, warnings: list[str] | None = None) -> "GateResult":
+ return cls(True, [], warnings or [], data)
+
+ @classmethod
+ def failed(
+ cls,
+ errors: list[str],
+ warnings: list[str] | None = None,
+ data: dict | None = None,
+ ) -> "GateResult":
+ return cls(False, list(errors), warnings or [], data)
+
+
+def load_yaml(path: str | Path) -> Any:
+ return yaml.safe_load(Path(path).read_text(encoding="utf-8"))
+
+
+def atomic_write_text(text: str, path: str | Path) -> None:
+ """Replace a text artifact only after its complete contents are on disk."""
+ p = Path(path)
+ tmp = p.with_name(p.name + ".tmp")
+ tmp.write_text(text, encoding="utf-8")
+ os.replace(tmp, p)
+
+
+def dump_yaml(obj: Any, path: str | Path) -> None:
+ atomic_write_text(
+ yaml.safe_dump(obj, allow_unicode=True, sort_keys=False), path
+ )
+
+
+def load_json(path: str | Path) -> Any:
+ return json.loads(Path(path).read_text(encoding="utf-8"))
+
+
+def dump_json(obj: Any, path: str | Path) -> None:
+ """Atomically write JSON (temp file + os.replace) so a crash mid-write never
+ leaves a half-written state file."""
+ atomic_write_text(json.dumps(obj, ensure_ascii=False, indent=2), path)
+
+
+def sha256_bytes(b: bytes) -> str:
+ return "sha256:" + hashlib.sha256(b).hexdigest()
+
+
+def sha256_file(path: str | Path) -> str:
+ return sha256_bytes(Path(path).read_bytes())
+
+
+def emit(result: GateResult) -> int:
+ for w in result.warnings:
+ print(f"warning: {w}", file=sys.stderr)
+ if result.ok:
+ return 0
+ for e in result.errors:
+ print(f"error: {e}", file=sys.stderr)
+ return 1
diff --git a/src/readme_harness/core.py b/src/readme_harness/core.py
new file mode 100644
index 0000000..b53501e
--- /dev/null
+++ b/src/readme_harness/core.py
@@ -0,0 +1,249 @@
+from __future__ import annotations
+
+import json
+import os
+from copy import deepcopy
+from dataclasses import dataclass
+from pathlib import Path
+
+import yaml
+
+from . import claims, gh_markdown, quality, secrets, verify
+from .common import GateResult, atomic_write_text, dump_json, sha256_bytes, sha256_file
+from .facts import extract_repository_facts, validate_fact_data
+from .patch import apply_candidate, generate_patch
+from .paths import PathEscapeError, resolve_inside_repo
+from .review import validate_review_data
+
+
+@dataclass(frozen=True)
+class BuildResult:
+ status: str
+ output_dir: Path
+ errors: tuple[str, ...]
+ warnings: tuple[str, ...]
+
+ @property
+ def ok(self) -> bool:
+ return self.status == "READY"
+
+
+def _load(value):
+ if value is None:
+ return None
+ if isinstance(value, dict):
+ return deepcopy(value)
+ path = Path(value)
+ text = path.read_text(encoding="utf-8")
+ return json.loads(text) if path.suffix == ".json" else yaml.safe_load(text)
+
+
+def _result(name: str, result: GateResult) -> dict:
+ return {"name": name, "ok": result.ok, "errors": result.errors, "warnings": result.warnings, "data": result.data}
+
+
+def _target(repo: Path, candidate) -> tuple[Path, str]:
+ try:
+ resolved = resolve_inside_repo(repo, candidate or "README.md")
+ except PathEscapeError as exc:
+ raise ValueError(f"README target must stay inside the repository: {candidate}") from exc
+ return resolved, resolved.relative_to(repo).as_posix()
+
+
+def _file_hash(path: Path) -> str:
+ return sha256_file(path) if path.is_file() else "missing"
+
+
+def repository_hash(repository, *, ignored=()) -> str:
+ """Hash repository paths and contents without following symlinks.
+
+ Git metadata, caches, build output, and the harness output directory are
+ excluded. A symlink contributes its link target text, never outside bytes.
+ """
+ repo = Path(repository).resolve()
+ ignored_real = {Path(path).resolve() for path in ignored}
+ ignored_names = {
+ ".git", ".readme-harness", ".pytest_cache", "__pycache__", ".gradle",
+ ".venv", "node_modules", "build", "dist",
+ }
+ chunks: list[bytes] = []
+ for root, dirs, files in os.walk(repo, followlinks=False):
+ root_path = Path(root)
+ dirs[:] = sorted(
+ name for name in dirs
+ if name not in ignored_names
+ and (root_path / name).resolve() not in ignored_real
+ )
+ for name in sorted(files):
+ path = root_path / name
+ if name.endswith(".pyc") or path.resolve() in ignored_real:
+ continue
+ relative = path.relative_to(repo).as_posix().encode("utf-8")
+ if path.is_symlink():
+ content = f"symlink:{os.readlink(path)}".encode("utf-8")
+ else:
+ content = path.read_bytes()
+ chunks.extend((relative, b"\0", content, b"\0"))
+ return sha256_bytes(b"".join(chunks))
+
+
+def build_readme(
+ repository,
+ draft,
+ *,
+ request=None,
+ facts=None,
+ review=None,
+ output_dir=None,
+ target_readme="README.md",
+) -> BuildResult:
+ """Validate a writer's draft and prepare a reviewable README patch.
+
+ The function has no lifecycle state machine. Re-running it replaces four
+ deterministic artifacts; an optional fifth artifact records the separate
+ review. It never modifies the repository README.
+ """
+ repo = Path(repository).resolve()
+ out = Path(output_dir).resolve() if output_dir else repo / ".readme-harness"
+ out.mkdir(parents=True, exist_ok=True)
+ request_data = _load(request) or {}
+ if request_data.get("mode", "generate") != "generate":
+ raise ValueError("Lean Core supports generate only; use audit for inspection")
+ facts_data = _load(facts) or extract_repository_facts(repo)
+ raw_draft = Path(draft).read_text(encoding="utf-8") if not isinstance(draft, str) or "\n" not in draft else draft
+ generated = claims.reader_markdown(raw_draft)
+ target, target_relative = _target(repo, target_readme)
+ baseline_repository_hash = repository_hash(repo, ignored=(out,))
+ baseline_target_hash = _file_hash(target)
+
+ bindings = facts_data.pop("claim-bindings", None)
+ if bindings is not None:
+ bound, binding_errors = claims.bind_claims(generated, bindings)
+ facts_data["claims"] = bound
+ else:
+ binding_errors = []
+
+ generated_path = out / "README.generated.md"
+ facts_path = out / "facts.json"
+ atomic_write_text(generated, generated_path)
+ dump_json(facts_data, facts_path)
+
+ fact_ids = {item.get("id") for item in facts_data.get("facts", []) if item.get("id")}
+ gates = [
+ ("facts", validate_fact_data(facts_data, repo)),
+ ("markdown", gh_markdown.validate_github_markdown(generated_path)),
+ ("commands-paths-links", verify.verify_readme(generated_path, facts_path, repo)),
+ ("secrets", secrets.scan_secret_leaks(generated_path, facts_path)),
+ ("reader-quality", quality.validate_reader_quality(generated)),
+ ("external-claims", claims.validate_external_claims(generated, facts_data.get("claims", []), fact_ids)),
+ ]
+ if binding_errors:
+ gates.append(("claim-bindings", GateResult.failed(binding_errors)))
+
+ review_data = _load(review)
+ review_gate = validate_review_data(review_data, generated) if review_data else None
+ if review_data:
+ dump_json(review_data, out / "review.json")
+ elif (out / "review.json").exists():
+ (out / "review.json").unlink()
+
+ errors = [f"{name}: {error}" for name, result in gates for error in result.errors]
+ warnings = [f"{name}: {warning}" for name, result in gates for warning in result.warnings]
+ if errors:
+ status = "FAILED"
+ elif review_gate is None:
+ status = "REVIEW_REQUIRED"
+ elif review_gate.ok:
+ status = "READY"
+ else:
+ status = "NEEDS_REVISION" if review_data.get("verdict") == "NEEDS_FIX" else "BLOCKED"
+ errors.extend(f"review: {error}" for error in review_gate.errors)
+
+ patch_path = out / "README.patch"
+ if status in {"REVIEW_REQUIRED", "READY"}:
+ atomic_write_text(generate_patch(generated, target), patch_path)
+ elif patch_path.exists():
+ patch_path.unlink()
+ verdict = "PASS" if status == "READY" else ("PENDING" if status == "REVIEW_REQUIRED" else "FAIL")
+ validation = {
+ "schema-version": 1,
+ "status": status,
+ "verdict": verdict,
+ "reviewed": status == "READY",
+ "repository-hash": baseline_repository_hash,
+ "generated-readme-hash": sha256_bytes(generated.encode("utf-8")),
+ "target-readme-hash": baseline_target_hash,
+ "target-path": target_relative,
+ "review-hash": sha256_file(out / "review.json") if review_data else None,
+ "checks": [_result(name, result) for name, result in gates],
+ "review": _result("review", review_gate) if review_gate else None,
+ "errors": errors,
+ "warnings": warnings,
+ }
+ dump_json(validation, out / "validation.json")
+ return BuildResult(status, out, tuple(errors), tuple(warnings))
+
+
+def audit_readme(repository, *, readme=None, facts=None, output_dir=None) -> BuildResult:
+ """Inspect an existing README without producing a candidate or patch."""
+ repo = Path(repository).resolve()
+ try:
+ source = resolve_inside_repo(repo, readme or "README.md")
+ except PathEscapeError as exc:
+ raise ValueError("audited README must stay inside the repository") from exc
+ out = Path(output_dir).resolve() if output_dir else repo / ".readme-harness"
+ out.mkdir(parents=True, exist_ok=True)
+ facts_data = _load(facts) or extract_repository_facts(repo)
+ facts_path = out / "facts.json"
+ dump_json(facts_data, facts_path)
+ markdown = claims.reader_markdown(source.read_text(encoding="utf-8"))
+ fact_ids = {item.get("id") for item in facts_data.get("facts", []) if item.get("id")}
+ gates = [
+ ("facts", validate_fact_data(facts_data, repo)),
+ ("markdown", gh_markdown.validate_github_markdown(source)),
+ ("commands-paths-links", verify.verify_readme(source, facts_path, repo)),
+ ("secrets", secrets.scan_secret_leaks(source, facts_path)),
+ ("reader-quality", quality.validate_reader_quality(markdown)),
+ ("external-claims", claims.validate_external_claims(markdown, facts_data.get("claims", []), fact_ids)),
+ ]
+ errors = [f"{name}: {error}" for name, result in gates for error in result.errors]
+ warnings = [f"{name}: {warning}" for name, result in gates for warning in result.warnings]
+ status = "PASS" if not errors else "FAILED"
+ dump_json({
+ "schema-version": 1,
+ "status": status,
+ "checks": [_result(name, result) for name, result in gates],
+ "errors": errors,
+ "warnings": warnings,
+ }, out / "validation.json")
+ return BuildResult(status, out, tuple(errors), tuple(warnings))
+
+
+def apply_reviewed_readme(repository, *, output_dir=None, target="README.md") -> None:
+ """Explicitly apply only a READY build; this is never called by build_readme."""
+ repo = Path(repository).resolve()
+ out = Path(output_dir).resolve() if output_dir else repo / ".readme-harness"
+ validation = json.loads((out / "validation.json").read_text(encoding="utf-8"))
+ if validation.get("status") != "READY" or validation.get("verdict") != "PASS" or not validation.get("reviewed"):
+ raise ValueError("README build is not READY; a passing separate review is required")
+ target_path, target_relative = _target(repo, target)
+ if target_relative != validation.get("target-path"):
+ raise ValueError("apply target differs from the reviewed target")
+ generated_path = out / "README.generated.md"
+ generated = generated_path.read_text(encoding="utf-8")
+ if sha256_bytes(generated.encode("utf-8")) != validation.get("generated-readme-hash"):
+ raise ValueError("README.generated.md changed after validation")
+ review_path = out / "review.json"
+ if not review_path.is_file():
+ raise ValueError("review.json is missing")
+ if sha256_file(review_path) != validation.get("review-hash"):
+ raise ValueError("review.json changed after validation")
+ review_data = json.loads(review_path.read_text(encoding="utf-8"))
+ review_gate = validate_review_data(review_data, generated)
+ if not review_gate.ok:
+ raise ValueError("review.json no longer approves README.generated.md")
+ if _file_hash(target_path) != validation.get("target-readme-hash"):
+ raise ValueError("target README changed after patch generation")
+ if repository_hash(repo, ignored=(out,)) != validation.get("repository-hash"):
+ raise ValueError("repository changed after validation")
+ apply_candidate(generated, target_path)
diff --git a/src/readme_harness/facts.py b/src/readme_harness/facts.py
new file mode 100644
index 0000000..317dd8b
--- /dev/null
+++ b/src/readme_harness/facts.py
@@ -0,0 +1,161 @@
+from __future__ import annotations
+
+import json
+import re
+import tomllib
+from pathlib import Path
+
+from .common import GateResult
+from .paths import PathEscapeError, resolve_inside_repo
+from .scan import scan_repository
+
+
+def _project_name(repo: Path) -> tuple[str, str]:
+ pyproject = repo / "pyproject.toml"
+ if pyproject.is_file() and not pyproject.is_symlink():
+ try:
+ name = tomllib.loads(pyproject.read_text(encoding="utf-8")).get("project", {}).get("name")
+ if name:
+ return str(name), "pyproject.toml"
+ except (OSError, tomllib.TOMLDecodeError):
+ pass
+ package = repo / "package.json"
+ if package.is_file() and not package.is_symlink():
+ try:
+ name = json.loads(package.read_text(encoding="utf-8")).get("name")
+ if name:
+ return str(name), "package.json"
+ except (OSError, json.JSONDecodeError):
+ pass
+ settings = next((
+ p for p in (repo / "settings.gradle.kts", repo / "settings.gradle")
+ if p.is_file() and not p.is_symlink()
+ ), None)
+ if settings:
+ match = re.search(r"rootProject\.name\s*=\s*['\"]([^'\"]+)['\"]", settings.read_text(encoding="utf-8"))
+ if match:
+ return match.group(1), settings.name
+ return repo.name, "."
+
+
+def _commands(repo: Path) -> list[dict]:
+ commands: list[tuple[str, str]] = []
+ pyproject = repo / "pyproject.toml"
+ if pyproject.is_file() and not pyproject.is_symlink():
+ try:
+ project = tomllib.loads(pyproject.read_text(encoding="utf-8")).get("project", {})
+ for name in sorted({*project.get("scripts", {}), *project.get("gui-scripts", {})}):
+ commands.append((name, "pyproject.toml"))
+ except (OSError, tomllib.TOMLDecodeError):
+ pass
+ package = repo / "package.json"
+ if package.is_file() and not package.is_symlink():
+ try:
+ scripts = json.loads(package.read_text(encoding="utf-8")).get("scripts", {})
+ commands.extend((f"npm run {name}", "package.json") for name in sorted(scripts))
+ except (OSError, json.JSONDecodeError):
+ pass
+ makefile = repo / "Makefile"
+ if makefile.is_file() and not makefile.is_symlink():
+ targets = re.findall(r"(?m)^([A-Za-z0-9_.-]+)\s*:(?![=])", makefile.read_text(encoding="utf-8"))
+ commands.extend((f"make {name}", "Makefile") for name in sorted(set(targets)) if not name.startswith("."))
+ for build_name in ("build.gradle.kts", "build.gradle"):
+ build = repo / build_name
+ if not build.is_file() or build.is_symlink():
+ continue
+ text = build.read_text(encoding="utf-8")
+ tasks = set(re.findall(r"tasks\.(?:register|named|create)\(\s*['\"]([A-Za-z0-9_-]+)['\"]", text))
+ tasks |= set(re.findall(r"(?m)^\s*task\s+([A-Za-z0-9_-]+)", text))
+ commands.extend((f"./gradlew {name}", build_name) for name in sorted(tasks))
+ unique: list[dict] = []
+ for command, source in commands:
+ if any(item["command"] == command for item in unique):
+ continue
+ unique.append({
+ "id": f"CMD-{len(unique) + 1:03d}",
+ "command": command,
+ "cwd": ".",
+ "source": {"path": source},
+ "verification": {"status": "discovered"},
+ })
+ return unique
+
+
+def extract_repository_facts(repo_path) -> dict:
+ """Collect a compact, deterministic fact inventory for the writer.
+
+ This is deliberately an inventory, not a prose plan or a lifecycle log.
+ A writer may add evidence-backed facts and external claim bindings before
+ calling :func:`build_readme`.
+ """
+ repo = Path(repo_path).resolve()
+ inventory = scan_repository(repo)
+ name, name_source = _project_name(repo)
+ evidence_path = inventory["build-files"][0] if inventory["build-files"] else name_source
+ facts = [
+ {
+ "id": "F-PROJECT-NAME",
+ "category": "identity",
+ "key": "project-name",
+ "value": name,
+ "evidence": [{"path": name_source, "source-kind": "project-metadata"}],
+ },
+ {
+ "id": "F-REPOSITORY-INVENTORY",
+ "category": "structure",
+ "key": "inventory",
+ "value": inventory,
+ "evidence": [{"path": evidence_path, "source-kind": "repository-scan"}],
+ },
+ ]
+ return {
+ "schema-version": 1,
+ "project-name": name,
+ "inventory": inventory,
+ "facts": facts,
+ "commands": _commands(repo),
+ "claims": [],
+ }
+
+
+def validate_fact_data(data: dict, repo_path) -> GateResult:
+ repo = Path(repo_path).resolve()
+ errors: list[str] = []
+ fact_ids: list[str] = []
+ if not isinstance(data, dict) or data.get("schema-version") != 1:
+ return GateResult.failed(["facts.json must be a schema-version 1 object"])
+ if not data.get("project-name"):
+ errors.append("facts.json is missing project-name")
+ for fact in data.get("facts", []):
+ fact_id = fact.get("id")
+ if not fact_id:
+ errors.append("fact without id")
+ continue
+ fact_ids.append(fact_id)
+ if not fact.get("evidence"):
+ errors.append(f"{fact_id}: fact has no evidence")
+ for evidence in fact.get("evidence", []):
+ path = evidence.get("path")
+ if not path:
+ errors.append(f"{fact_id}: evidence has no path")
+ continue
+ try:
+ target = resolve_inside_repo(repo, path)
+ except PathEscapeError:
+ errors.append(f"{fact_id}: evidence path escapes repository: {path}")
+ continue
+ if not target.exists():
+ errors.append(f"{fact_id}: evidence path not found: {path}")
+ if len(fact_ids) != len(set(fact_ids)):
+ errors.append("duplicate fact ids")
+ commands = [item.get("command") for item in data.get("commands", [])]
+ if len(commands) != len(set(commands)):
+ errors.append("duplicate commands")
+ return GateResult.failed(errors) if errors else GateResult.passed({"fact-ids": fact_ids})
+
+
+def validate_facts(facts_path, repo_path, schema_dir=None, snapshot_path=None) -> GateResult:
+ """Compatibility wrapper for callers that still pass a path."""
+ path = Path(facts_path)
+ data = json.loads(path.read_text(encoding="utf-8")) if path.suffix == ".json" else __import__("yaml").safe_load(path.read_text(encoding="utf-8"))
+ return validate_fact_data(data, repo_path)
diff --git a/src/readme_harness/gh_markdown.py b/src/readme_harness/gh_markdown.py
new file mode 100644
index 0000000..9600549
--- /dev/null
+++ b/src/readme_harness/gh_markdown.py
@@ -0,0 +1,40 @@
+from __future__ import annotations
+
+import re
+from pathlib import Path
+
+from .common import GateResult
+from . import markers
+
+
+def _anchor(text: str) -> str:
+ a = text.strip().lower()
+ a = re.sub(r"[^\w\s-]", "", a)
+ return re.sub(r"\s+", "-", a)
+
+
+def validate_github_markdown(readme_path) -> GateResult:
+ md = Path(readme_path).read_text(encoding="utf-8")
+ errors: list[str] = []
+ if md.count("```") % 2 != 0:
+ errors.append("unclosed code fence (odd number of ``` markers)")
+ hs = markers.headings(md)
+ prev = 0
+ for level, text in hs:
+ if prev and level > prev + 1:
+ errors.append(f"heading level skip: h{prev} -> h{level} at '{text}'")
+ prev = level
+ anchors = [_anchor(t) for _, t in hs]
+ dupes = sorted({a for a in anchors if anchors.count(a) > 1})
+ if dupes:
+ errors.append(f"duplicate heading anchors: {dupes}")
+ for m in re.finditer(r"\]\((file://[^)]*|/home/[^)]*)\)", md):
+ errors.append(f"local/absolute link not portable: {m.group(1)}")
+ for m in re.finditer(r"(?]*>", md, re.IGNORECASE | re.DOTALL):
+ alt = re.search(r"\balt\s*=\s*(['\"])(.*?)\1", tag.group(0), re.IGNORECASE | re.DOTALL)
+ if alt is None or not alt.group(2).strip():
+ errors.append("HTML image without alt text")
+ return GateResult.failed(errors) if errors else GateResult.passed()
diff --git a/src/readme_harness/markers.py b/src/readme_harness/markers.py
new file mode 100644
index 0000000..83468e6
--- /dev/null
+++ b/src/readme_harness/markers.py
@@ -0,0 +1,38 @@
+from __future__ import annotations
+
+import re
+
+
+def _marker(md: str, key: str) -> list[str]:
+ return re.findall(rf"", md)
+
+
+def section_ids(md: str) -> list[str]:
+ return _marker(md, "section-id")
+
+
+def claim_ids(md: str) -> list[str]:
+ return _marker(md, "claim-id")
+
+
+def visual_slot_ids(md: str) -> list[str]:
+ return _marker(md, "visual-slot")
+
+
+def visual_ids(md: str) -> list[str]:
+ return _marker(md, "visual-id")
+
+
+def headings(md: str) -> list[tuple[int, str]]:
+ out: list[tuple[int, str]] = []
+ in_fence = False
+ for line in md.splitlines():
+ if line.lstrip().startswith("```"):
+ in_fence = not in_fence
+ continue
+ if in_fence:
+ continue
+ m = re.match(r"(#{1,6})\s+(.*)", line)
+ if m:
+ out.append((len(m.group(1)), m.group(2).strip()))
+ return out
diff --git a/src/readme_harness/patch.py b/src/readme_harness/patch.py
new file mode 100644
index 0000000..b26bc6f
--- /dev/null
+++ b/src/readme_harness/patch.py
@@ -0,0 +1,24 @@
+from __future__ import annotations
+
+import difflib
+import os
+from pathlib import Path
+
+
+def generate_patch(candidate_md: str, target_readme) -> str:
+ target = Path(target_readme)
+ old = target.read_text(encoding="utf-8").splitlines(keepends=True) if target.exists() else []
+ new = candidate_md.splitlines(keepends=True)
+ return "".join(
+ difflib.unified_diff(
+ old, new, fromfile="README.md (current)", tofile="README.md (candidate)"
+ )
+ )
+
+
+def apply_candidate(candidate_md: str, target_readme) -> None:
+ target = Path(target_readme)
+ target.parent.mkdir(parents=True, exist_ok=True)
+ temporary = target.with_name(target.name + ".readme-harness.tmp")
+ temporary.write_text(candidate_md, encoding="utf-8")
+ os.replace(temporary, target)
diff --git a/src/readme_harness/paths.py b/src/readme_harness/paths.py
new file mode 100644
index 0000000..39bf6ac
--- /dev/null
+++ b/src/readme_harness/paths.py
@@ -0,0 +1,56 @@
+"""Repository path containment.
+
+Every file access that starts from a repo-relative path (fact evidence, README
+links, repository hashing, apply targets) must go through here so a repository cannot make the
+harness read outside its own tree via `../`, an absolute path, or a symlink that
+escapes the root.
+"""
+
+from __future__ import annotations
+
+from pathlib import Path
+
+
+class PathEscapeError(Exception):
+ def __init__(self, candidate):
+ super().__init__(f"path escapes repository: {candidate}")
+ self.candidate = candidate
+
+
+def resolve_inside_repo(repo, candidate) -> Path:
+ """Resolve `candidate` against `repo` and ensure it stays inside the repo.
+
+ Raises PathEscapeError for `../` escape, absolute paths outside the repo,
+ symlinks that resolve outside the repo, and circular/unresolvable symlinks.
+ """
+ repo_real = Path(repo).resolve()
+ cand = Path(candidate)
+ base = cand if cand.is_absolute() else (repo_real / cand)
+ try:
+ target_real = base.resolve()
+ except (OSError, RuntimeError) as exc: # ELOOP / circular symlink
+ raise PathEscapeError(candidate) from exc
+ if repo_real != target_real and repo_real not in target_real.parents:
+ raise PathEscapeError(candidate)
+ return target_real
+
+
+def is_inside_repo(repo, candidate) -> bool:
+ try:
+ resolve_inside_repo(repo, candidate)
+ return True
+ except PathEscapeError:
+ return False
+
+
+def safe_exists(repo, candidate) -> bool:
+ """True only if `candidate` resolves inside `repo` AND the target exists.
+
+ A broken symlink (inside the repo but pointing at nothing) is False. An
+ escaping path is False (never touches the outside target).
+ """
+ try:
+ target = resolve_inside_repo(repo, candidate)
+ except PathEscapeError:
+ return False
+ return target.exists()
diff --git a/src/readme_harness/quality.py b/src/readme_harness/quality.py
new file mode 100644
index 0000000..c2e19fe
--- /dev/null
+++ b/src/readme_harness/quality.py
@@ -0,0 +1,57 @@
+from __future__ import annotations
+
+import re
+
+from .claims import blocks
+from .common import GateResult
+
+_PLACEHOLDER = re.compile(r"(?:<[A-Za-z][^>\n]{0,40}>|\{\{?\s*[A-Za-z][^}\n]{0,40}\}\}?|\b(?:TODO|TBD)\b)")
+_MARKER = re.compile(r"
+
+
+
+
+
+
+
+ Gradle Configuration Cache
+
+
+
+
+
+
+ Loading...
+
+
+
+
+
+
+