refactor: 문서 개선 중
This commit is contained in:
@@ -70,15 +70,44 @@ Agent(subagent_type="record-writer", prompt=<references/subagent-prompts.md 의
|
||||
그것을 되풀이하지 않아도 되는 것이 이 방식의 값이다 — 프롬프트는 **이번 런의 입력 경로와
|
||||
글감**만 준다.
|
||||
|
||||
**단계가 아닌 에이전트가 넷 더 있다.** 기록 한 편을 놓고 역할을 가른 것이라 아무 단계에도
|
||||
붙지 않는다. 부를지는 사람이 정하고, 원장의 단계 칸에는 안 들어간다.
|
||||
**단계 밖의 보조 에이전트도 역할을 고정한다.** 선택적으로 부르는 리뷰와 v3 런에서 절차상
|
||||
필요한 command/fact review를 섞지 않는다. `qualityReviews`에 들어가는 역할은 단계 칸과 별도로
|
||||
검증기가 확인한다.
|
||||
|
||||
| 에이전트 | 언제 | 안 하는 일 |
|
||||
|---|---|---|
|
||||
| `source-auditor` | S3 앞. 원본의 주장을 `관측`·`추론`·`미검증`으로 가른 표를 만든다 | 기록을 안 쓴다 |
|
||||
| `fact-reviewer` | 쓴 뒤. 결과 문장을 원문과 한 글자씩 역대조한다 | 파일을 안 고친다 |
|
||||
| `reader-reviewer` | 쓴 뒤. 제목·요약·목차만 보고 30초 안에 읽히는지 본다 | 본문을 안 연다 |
|
||||
| `setup-runner` | Setup 을 쓴 뒤. 손으로 끝까지 칠 수 있는지 읽는다 | 실제로 치지는 않는다 |
|
||||
| `command-pedagogy-planner` | S3 뒤 initial analysis에 finding이 있을 때 | Markdown을 안 고친다 |
|
||||
| `command-pedagogy-editor` | planner가 만든 plan을 command span에 반영할 때 | command block 밖의 산문을 안 고친다 |
|
||||
| `command-pedagogy-reviewer` | S6 뒤 final analysis에 shell/CLI block이 있을 때 | 파일을 안 고친다 |
|
||||
| `fact-reviewer` | command/prose/voice 수정이 모두 끝난 S6 뒤 | 파일을 안 고친다 |
|
||||
| `reader-reviewer` | 필요할 때 제목·요약·목차만 보고 30초 안에 읽히는지 본다 | 본문을 안 연다 |
|
||||
| `setup-runner` | Setup을 쓴 뒤 추가 운영성 검토가 필요할 때 | 실제로 치지는 않는다 |
|
||||
|
||||
## Command pedagogy lane — S3 직후 초벌, S6 뒤 최종 리뷰
|
||||
|
||||
S3이 기록을 만들면 먼저 결정론적 분석을 남긴다.
|
||||
|
||||
```bash
|
||||
python3 scripts/check-command-pedagogy.py <기록.md> \
|
||||
-o runs/<프로젝트>/<runId>/stage/S3/command-initial.json
|
||||
```
|
||||
|
||||
- **shell/CLI block이 없으면** command planner/editor/reviewer를 모두 `SKIPPED`로 적고 사유를 남긴다.
|
||||
- **finding이 없으면 planner/editor**는 `SKIPPED`다. 단, shell/CLI가 있으므로 최종 reviewer는 S6 뒤에 돈다.
|
||||
- finding이 있으면 `command-pedagogy-planner`가 frozen plan을 만들고 `command-pedagogy-editor`가
|
||||
`CommandPatchSet`만 만든다. editor가 기록 전체를 직접 고치지 않는다.
|
||||
- patch 적용은 `scripts/apply-command-pedagogy-patch.py`만 쓴다. 이 도구는 initial analysis의
|
||||
hash와 span을 대조해 **원래 command block 밖의 산문을 건드리지 못하게 한다.**
|
||||
- S5와 S6은 명령어를 보호 구간으로 취급한다. 둘이 끝난 뒤 같은 deterministic analyzer를 다시
|
||||
돌려 `finalAnalysis`를 남긴다. initial에 command block이 있었는데 final에서 전부 사라지거나
|
||||
`majorFindings > 0`이면 끝난 것이 아니다.
|
||||
- final에 shell/CLI가 하나라도 있으면 `command-pedagogy-reviewer`가 독립적으로 `PASS`해야 한다.
|
||||
`FAIL`과 `UNCERTAIN`은 막는다.
|
||||
- 마지막으로 `fact-reviewer`가 **모든 command/prose/voice 수정 이후** 기술 사실을 역대조해 `PASS`해야 한다.
|
||||
|
||||
이 영수증은 `run.json`의 `qualityReviews.commandPedagogy`와
|
||||
`qualityReviews.technicalEvidence`에 남긴다. command/fact review 자체는 schemaVersion 3 계약이다. schemaVersion 4부터는 analysis/plan/patch/review JSON의 repo-relative path+sha256과 최종 기록 `sourceSha256`까지 남긴다. v3 이전/이전 형식 원장에 새 영수증을 소급해 만들지 않는다. `CommandPlan`/`CommandPatchSet`은 `scripts/validate-command-pedagogy-artifact.py`로 검증한다.
|
||||
|
||||
## 순서가 고정된 곳
|
||||
|
||||
@@ -95,8 +124,9 @@ Agent(subagent_type="record-writer", prompt=<references/subagent-prompts.md 의
|
||||
S6 이 채울 자리(선택·비교·어긋남)가 보인다. 순서를 뒤집으면 S5 가 S6 이 넣은 목소리를
|
||||
「과한 대구」로 다시 깎는다.
|
||||
|
||||
**S6 → S7.** Studio 에는 문장 손질이 끝난 것만 넣는다. 저장한 뒤에 고치면 Studio 쪽 `version`
|
||||
이 올라가고 검증 산출물이 무효가 된다.
|
||||
**S6 → final command review → fact review → S7.** Studio에는 문장 손질뿐 아니라 command-pedagogy와
|
||||
technical-evidence 검토까지 끝난 것만 넣는다. 저장한 뒤에 고치면 Studio 쪽 `version`이 올라가고
|
||||
검증 산출물이 무효가 된다.
|
||||
|
||||
## S5·S6 뒤에는 S3 관문을 다시 돌린다
|
||||
|
||||
@@ -112,6 +142,12 @@ node .agents/skills/writing-tech-log-records/scripts/check_evidence.mjs <프로
|
||||
|
||||
원장에서는 이것이 S5·S6 의 관문이지 S3 의 재실행이 아니다.
|
||||
|
||||
`check_evidence.mjs --repo` 의 exit 의미는 구분한다. `0`은 대조 완료, `1`은 실제 불일치,
|
||||
`2`는 검사 대상 자체가 성립하지 않음, `3`은 원본 저장소가 현재 머신에 없어 repo 대조를
|
||||
수행하지 못한 상태다. 새 publication run의 관문에서는 `3`을 PASS로 기록하면 안 된다. 반면
|
||||
저장소 전체를 dogfooding하는 `verify-pipeline.py`는 기존 문서의 내용 불일치와 실행 환경의
|
||||
부재를 섞지 않기 위해 `3`을 `UNVERIFIABLE` WARN으로 따로 센다.
|
||||
|
||||
## 건너뛰어도 되는 단계
|
||||
|
||||
이미 있는 것을 다시 만들지 않는다. 건너뛴 단계도 **원장에 `SKIPPED` 와 사유를 적는다.**
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# Command Pedagogy Editor — Canonical Contract
|
||||
|
||||
이 계약은 provider와 무관한 editor의 SSOT다. `.claude/agents/command-pedagogy-editor.md`는 이 파일을 가리키기만 한다.
|
||||
|
||||
먼저 `.agents/skills/writing-practitioner-guides/SKILL.md`와 `references/command-pedagogy.md`를 읽는다. validated `CommandPlan`이 있을 때만 실행한다.
|
||||
|
||||
## 책임
|
||||
- 기록 파일을 직접 다시 쓰지 않는다.
|
||||
- frozen plan이 지목한 command span만 `CommandPatchSet`으로 제안한다.
|
||||
- command block 밖의 산문, technical claim/evidence, target host/session, file meaning, security boundary를 바꾸지 않는다.
|
||||
- validation과 destructive cleanup을 같은 chain에 두지 않는다.
|
||||
- diagnostic 문맥에서는 필요한 raw output을 먼저 관찰할 수 있게 한다.
|
||||
- automation/reference에서는 정당한 compact syntax를 유지할 수 있다.
|
||||
- 변경할 필요가 없으면 empty `patches`를 허용한다.
|
||||
|
||||
## 출력 계약
|
||||
`.agents/skills/running-tech-log-pipeline/schemas/command-patch-set.schema.json`을 만족하는 JSON만 산출한다. 적용은 `scripts/apply-command-pedagogy-patch.py`만 사용하며 stale source/block hash를 우회하지 않는다.
|
||||
@@ -0,0 +1,16 @@
|
||||
# Command Pedagogy Planner — Canonical Contract
|
||||
|
||||
이 계약은 provider와 무관한 planner의 SSOT다. `.claude/agents/command-pedagogy-planner.md`는 이 파일을 가리키기만 한다.
|
||||
|
||||
먼저 `.agents/skills/writing-practitioner-guides/SKILL.md`와 `references/command-pedagogy.md`를 읽는다. deterministic initial analysis에 finding이 있을 때만 실행한다.
|
||||
|
||||
## 책임
|
||||
- Markdown을 직접 고치지 않는다.
|
||||
- analysis가 지목한 command block마다 기술적 intent, 실행 host/cwd, prerequisite, 단계, 예상 결과, cleanup을 `CommandPlan`으로 명시한다.
|
||||
- tutorial/operator/diagnostic에서는 관찰 가능한 한 단계/한 책임을 우선한다.
|
||||
- automation/reference에서는 compact shell이 목적에 맞으면 유지할 수 있다. `sed`, `printf`, pipeline, command substitution 자체를 금지하지 않는다.
|
||||
- SSOT/evidence에 없는 alias, 파일, prerequisite, 성공 결과를 만들지 않는다.
|
||||
- target host/session, file meaning, security boundary, technical claim을 바꾸지 않는다.
|
||||
|
||||
## 출력 계약
|
||||
`.agents/skills/running-tech-log-pipeline/schemas/command-plan.schema.json`을 만족하는 JSON만 산출한다. `source_sha256`과 각 group의 `source_sha256`은 initial analysis의 frozen hash와 같아야 한다. 모든 finding 대상 block을 빠짐없이 command group으로 다룬다.
|
||||
@@ -0,0 +1,17 @@
|
||||
# Command Pedagogy Reviewer — Canonical Contract
|
||||
|
||||
이 계약은 provider와 무관한 독립 reviewer의 SSOT다. `.claude/agents/command-pedagogy-reviewer.md`는 이 파일을 가리키기만 한다.
|
||||
|
||||
먼저 `.agents/skills/writing-practitioner-guides/SKILL.md`와 `references/command-pedagogy.md`를 읽는다. command/prose/voice repair가 모두 끝난 최종 publication text, initial/final deterministic analysis, CommandPlan, SSOT/evidence를 함께 본다. 파일은 수정하지 않는다.
|
||||
|
||||
## PASS 조건
|
||||
- 실행 context와 prerequisite가 필요한 위치에서 분명하다.
|
||||
- setup/transfer/validation/observation/cleanup이 불필요한 opaque one-liner로 뭉치지 않는다.
|
||||
- destructive cleanup이 validation evidence를 같은 chain에서 지우지 않는다.
|
||||
- troubleshooting의 첫 경로에서 필요한 stderr/raw output을 숨기지 않는다.
|
||||
- 남아 있는 `sed`, `printf`, substitution, redirect, pipeline은 문서 mode에서 합리적이다.
|
||||
- command repair가 technical operation, target, security boundary, evidence를 바꾸지 않았다.
|
||||
- 결과나 prerequisite를 발명하지 않았다.
|
||||
|
||||
## 판정
|
||||
`PASS | FAIL | UNCERTAIN`. `FAIL`과 `UNCERTAIN`은 acceptance를 막는다. 결과 artifact에는 `scope=command-pedagogy`, `reviewer=command-pedagogy-reviewer`, `verdict`, `source_sha256`, `findings`, `notes`를 남겨 최종 publication hash에 결속한다.
|
||||
@@ -0,0 +1,29 @@
|
||||
schema_version: "1.0"
|
||||
default_mode: operator
|
||||
blanket_ban: false
|
||||
|
||||
modes:
|
||||
tutorial:
|
||||
prefer: [one-concern-per-step, explicit-execution-context, explain-before-run, expected-result, separate-verification, separate-cleanup]
|
||||
operator:
|
||||
prefer: [copyable, intent-revealing, observable, bounded-side-effects]
|
||||
diagnostic:
|
||||
allow: [pipelines, grep, jq, awk]
|
||||
require: [preserve-useful-errors, explain-filtering]
|
||||
automation:
|
||||
allow: [sed, awk, jq, printf, pipelines, command-substitution, compound-commands]
|
||||
require: [stated-input, stated-output, reason-for-automation, verification]
|
||||
reference:
|
||||
allow: [compact-command-forms]
|
||||
require: [intent-remains-visible]
|
||||
|
||||
major_findings:
|
||||
- validation_cleanup_same_chain
|
||||
- destructive_side_effects_without_observable_checkpoint
|
||||
- critical_diagnostic_output_hidden
|
||||
|
||||
principles:
|
||||
- deterministic_analyzer_reports_findings_only
|
||||
- command_repair_before_prose_repair
|
||||
- final_technical_evidence_review_after_all_repairs
|
||||
- command_free_sections_skip_command_model_calls
|
||||
@@ -121,6 +121,24 @@ node .agents/skills/rewriting-technical-prose-naturally/scripts/check_prose.mjs
|
||||
node .agents/skills/writing-tech-log-records/scripts/check_evidence.mjs <프로젝트> --repo
|
||||
```
|
||||
|
||||
`--repo`는 선택 옵션이 아니다. S3와 S3 관문을 다시 실행하는 S5·S6 모두 live source
|
||||
reconciliation을 시도해야 한다. 현재 기계에 `sourceRepository.path`가 없어서 명령이 exit 3을
|
||||
돌려주면 그 결과를 exit 0으로 바꾸거나 `--repo`를 빼지 않는다. schemaVersion 5 원장에는
|
||||
다음처럼 **대조 불가 자체를 영수증으로 남긴다.**
|
||||
|
||||
```text
|
||||
semanticId: evidence-repo
|
||||
status: UNVERIFIABLE
|
||||
exit: 3
|
||||
reason: source repository unavailable on current machine
|
||||
acceptedByProjectReview: true
|
||||
```
|
||||
|
||||
`verify-pipeline-run.py`는 v5부터 S3·S5·S6 각각에 `semanticId=evidence-repo` 관문이 정확히
|
||||
하나 있는지, 실제 명령에 `check_evidence.mjs <프로젝트> --repo`가 들어 있는지까지 확인한다.
|
||||
`UNVERIFIABLE`은 실패를 숨긴 PASS가 아니다. 실제 exit 3, 대조 불가 이유, 프로젝트 리뷰의
|
||||
명시적 수용이 모두 있을 때만 완료를 막지 않는 별도 상태다.
|
||||
|
||||
**노드가 `PROMOTE` 이고 `CONFIRMED` 인지 먼저 본다.** 아니면 쓰지 않는다.
|
||||
|
||||
**인용한 줄은 SSOT 에서 찾아 대조한다.** 앞선 기록에서 옮겨 적은 것은 확인한 것이 아니다 —
|
||||
@@ -129,6 +147,47 @@ node .agents/skills/writing-tech-log-records/scripts/check_evidence.mjs <프로
|
||||
그림이 필요해 보이면 **`final/assets/` 에 이미 있는지부터 본다.** 계약의 `ssot-assets` 가 이
|
||||
글감에 배정한 그림이 있으면 그 파일을 그대로 가리킨다. 없을 때만 S4 로 넘긴다.
|
||||
|
||||
### S3-C — command-pedagogy 보조 흐름
|
||||
|
||||
S3가 쓴 기록은 command의 **기술적 정답**과 **사람이 따라갈 수 있는 표현**을 분리해서 본다.
|
||||
먼저 deterministic `initialAnalysis`를 만든다.
|
||||
|
||||
```bash
|
||||
python3 scripts/check-command-pedagogy.py <기록.md> \
|
||||
-o runs/<프로젝트>/<runId>/stage/S3/command-initial.json
|
||||
```
|
||||
|
||||
`initialAnalysis.shellBlocks == 0`이면 planner/editor/reviewer는 모두 `SKIPPED`다. shell block은
|
||||
있지만 finding이 0이면 planner/editor만 `SKIPPED`하고 reviewer는 S6 뒤 최종본을 본다.
|
||||
|
||||
finding이 하나라도 있으면 역할을 나눈다.
|
||||
|
||||
1. `command-pedagogy-planner`가 분석이 지목한 block만 대상으로 `CommandPlan`을 만든다.
|
||||
2. `command-pedagogy-editor`는 기록을 직접 다시 쓰지 않고 `CommandPatchSet`만 만든다.
|
||||
3. 아래 적용기로 patch를 적용한다.
|
||||
|
||||
```bash
|
||||
python3 scripts/apply-command-pedagogy-patch.py \
|
||||
<기록.md> <command-initial.json> <command-patch-set.json> \
|
||||
-o <수정본.md>
|
||||
```
|
||||
|
||||
적용기는 initial source hash, block id, block hash를 대조한다. 따라서 editor가 **command block 밖의 산문**을
|
||||
직접 바꾸는 경로가 없다. stale hash나 unknown block이면 적용하지 않고 기록을 다시 분석한다.
|
||||
|
||||
S5·S6이 끝난 뒤 최종 기록에 같은 분석을 다시 실행해 `finalAnalysis`를 남긴다. initial에 shell block이
|
||||
있었는데 final이 0이면 command를 없애서 문제를 숨긴 것으로 보고 실패한다. `finalAnalysis.majorFindings`
|
||||
(`majorFindings`)가 1 이상이어도 실패한다. minor finding은 전역 금지 규칙이 아니므로 reviewer가 문맥을 본다.
|
||||
|
||||
최종 shell/CLI block이 있으면 `command-pedagogy-reviewer`가 독립적으로 `PASS`해야 한다. 그 다음
|
||||
`fact-reviewer`가 command/prose/voice 변경이 모두 끝난 결과를 SSOT/evidence와 역대조해 `PASS`해야 한다.
|
||||
두 reviewer는 파일을 고치지 않는다.
|
||||
|
||||
원장 위치는 `qualityReviews.commandPedagogy.{initialAnalysis,finalAnalysis,planner,editor,reviewer}`와
|
||||
`qualityReviews.technicalEvidence`다. command/fact review 기본 계약은 schemaVersion 3부터 적용한다.
|
||||
|
||||
schemaVersion 4부터는 command lane의 first-class artifact도 강제한다. `initialAnalysis`/`finalAnalysis`와 DONE 상태의 planner/editor/reviewer는 repository 내부 JSON artifact의 `path`+`sha256` 영수증을 남긴다. `CommandPlan`과 `CommandPatchSet`은 각각 `schemas/command-plan.schema.json`, `schemas/command-patch-set.schema.json` 계약을 따르고 `scripts/validate-command-pedagogy-artifact.py`로 frozen analysis와 대조한다. command reviewer와 `technicalEvidence`의 `sourceSha256`은 모든 repair가 끝난 최종 기록 파일의 SHA256과 같아야 한다. v3에는 이 새 영수증을 소급 요구하지 않는다.
|
||||
|
||||
---
|
||||
|
||||
## S4 — 기록 → 그림
|
||||
|
||||
@@ -156,6 +156,92 @@ error 0 까지 고쳐라.
|
||||
돌려줄 것: 위 JSON 형식. skillEcho 포함.
|
||||
```
|
||||
|
||||
### S3-C1 — initial command analysis
|
||||
|
||||
S3가 끝나면 항상 deterministic **initial command analysis**를 만든다.
|
||||
|
||||
```bash
|
||||
python3 scripts/check-command-pedagogy.py <기록.md> --mode <문서 mode> \
|
||||
-o runs/<프로젝트>/<runId>/stage/S3/command-initial.json
|
||||
```
|
||||
|
||||
shell/CLI block이 0이면 아래 세 command agent를 부르지 않고 원장의 planner/editor/reviewer를
|
||||
`SKIPPED`로 적는다. block은 있지만 finding이 0이면 planner/editor만 `SKIPPED`다.
|
||||
|
||||
### S3-C2 — CommandPlan (finding이 있을 때만)
|
||||
|
||||
```
|
||||
Agent(subagent_type="command-pedagogy-planner", prompt=<아래 command planner 프롬프트>)
|
||||
```
|
||||
|
||||
```text
|
||||
너는 command-pedagogy planner다.
|
||||
|
||||
먼저 .agents/skills/writing-practitioner-guides/SKILL.md 를 끝까지 읽고
|
||||
references/command-pedagogy.md 도 읽어라.
|
||||
|
||||
기록: <기록.md>
|
||||
initial command analysis: runs/<프로젝트>/<runId>/stage/S3/command-initial.json
|
||||
근거: <이 기록의 source가 가리키는 SSOT 절>
|
||||
|
||||
분석이 지목한 block만 계획해라. Markdown을 수정하지 마라.
|
||||
SSOT/evidence에 없는 alias, prerequisite, 성공 결과를 만들지 마라.
|
||||
compact syntax 자체를 금지하지 말고 문서 모드와 관찰 가능성으로 판단해라.
|
||||
|
||||
돌려줄 것: CommandPlan JSON + skillEcho.
|
||||
skillEcho는 writing-practitioner-guides/SKILL.md에서 원문 한 줄을 그대로 옮긴 것이다.
|
||||
```
|
||||
|
||||
CommandPlan을 `runs/<프로젝트>/<runId>/stage/S3/command-plan.json`에 저장한 뒤 frozen analysis와 검증한다.
|
||||
|
||||
```bash
|
||||
python3 scripts/validate-command-pedagogy-artifact.py plan \
|
||||
runs/<프로젝트>/<runId>/stage/S3/command-plan.json \
|
||||
--analysis runs/<프로젝트>/<runId>/stage/S3/command-initial.json
|
||||
```
|
||||
|
||||
### S3-C3 — bounded command editor (finding이 있을 때만)
|
||||
|
||||
```
|
||||
Agent(subagent_type="command-pedagogy-editor", prompt=<아래 command editor 프롬프트>)
|
||||
```
|
||||
|
||||
```text
|
||||
너는 command-pedagogy editor다.
|
||||
|
||||
먼저 .agents/skills/writing-practitioner-guides/SKILL.md 를 끝까지 읽고
|
||||
references/command-pedagogy.md 도 읽어라.
|
||||
|
||||
기록: <기록.md>
|
||||
initial command analysis: <command-initial.json>
|
||||
CommandPlan: <command-plan.json>
|
||||
근거: <이 기록의 source가 가리키는 SSOT 절>
|
||||
|
||||
기록 파일을 직접 수정하지 마라. frozen plan의 block_id에 대한 CommandPatchSet JSON만 만들어라.
|
||||
command block 밖의 산문, 기술 주장, target host/session, file meaning, security boundary를 바꾸지 마라.
|
||||
|
||||
돌려줄 것: CommandPatchSet JSON + skillEcho.
|
||||
```
|
||||
|
||||
CommandPatchSet을 `runs/<프로젝트>/<runId>/stage/S3/command-patch-set.json`에 저장하고 검증한다.
|
||||
|
||||
```bash
|
||||
python3 scripts/validate-command-pedagogy-artifact.py patch \
|
||||
runs/<프로젝트>/<runId>/stage/S3/command-patch-set.json \
|
||||
--analysis runs/<프로젝트>/<runId>/stage/S3/command-initial.json
|
||||
```
|
||||
|
||||
editor 결과는 에이전트가 직접 적용하지 않는다. host orchestrator가 bounded applier를 쓴다.
|
||||
|
||||
```bash
|
||||
python3 scripts/apply-command-pedagogy-patch.py \
|
||||
<기록.md> <command-initial.json> <command-patch-set.json> \
|
||||
-o /tmp/command-repaired.md
|
||||
mv /tmp/command-repaired.md <기록.md>
|
||||
```
|
||||
|
||||
그 다음 S3 관문을 다시 실행하고 S4로 간다.
|
||||
|
||||
---
|
||||
|
||||
## S4 — 기록 → 그림
|
||||
@@ -270,6 +356,102 @@ check_voice.mjs 는 목소리가 모자란지 재지 않는다. 지어낸 목소
|
||||
돌려줄 것: 위 JSON 형식. skillEcho 포함. 흔적이 없었으면 status DONE 에 notes 로 적어라.
|
||||
```
|
||||
|
||||
### R1 — final command analysis + independent command review
|
||||
|
||||
S6가 끝나면 **final command analysis**를 다시 만든다.
|
||||
|
||||
```bash
|
||||
python3 scripts/check-command-pedagogy.py <기록.md> --mode <initial과 같은 문서 mode> \
|
||||
-o runs/<프로젝트>/<runId>/review/command-final.json
|
||||
```
|
||||
|
||||
initial analysis에 shell block이 있었는데 final이 0이면 멈춘다. final `majorFindings`가 남아도
|
||||
멈춘다. final shell/CLI block이 하나라도 있으면 다음 reviewer를 부른다.
|
||||
|
||||
```
|
||||
Agent(subagent_type="command-pedagogy-reviewer", prompt=<아래 command reviewer 프롬프트>)
|
||||
```
|
||||
|
||||
```text
|
||||
너는 final command-pedagogy reviewer다. 파일을 고치지 마라.
|
||||
|
||||
먼저 .agents/skills/writing-practitioner-guides/SKILL.md 를 끝까지 읽고
|
||||
references/command-pedagogy.md 도 읽어라.
|
||||
|
||||
최종 기록: <기록.md>
|
||||
initial command analysis: <command-initial.json>
|
||||
final command analysis: <command-final.json>
|
||||
CommandPlan: <있으면 command-plan.json, 없으면 null>
|
||||
근거: <이 기록의 source가 가리키는 SSOT/evidence>
|
||||
|
||||
최종 command가 기술적으로 같은 일을 하면서 사람이 실행·관찰·진단할 수 있는지 독립적으로 판정해라.
|
||||
직접 수정하지 마라. PASS / FAIL / UNCERTAIN 중 하나만 낸다.
|
||||
FAIL과 UNCERTAIN은 acceptance를 막는다.
|
||||
|
||||
돌려줄 것: reviewer, verdict, findings, notes + skillEcho.
|
||||
```
|
||||
|
||||
### R2 — final technical-evidence review
|
||||
|
||||
command/prose/voice 수정이 모두 끝난 뒤 마지막으로 fact reviewer를 부른다. command가 없는 글도
|
||||
이 검토는 생략하지 않는다.
|
||||
|
||||
```
|
||||
Agent(subagent_type="fact-reviewer", prompt=<아래 fact reviewer 프롬프트>)
|
||||
```
|
||||
|
||||
```text
|
||||
너는 최종 technical-evidence reviewer다. 파일을 고치지 마라.
|
||||
|
||||
최종 기록: <기록.md>
|
||||
SSOT: docs/<프로젝트>/final/document.md
|
||||
추가 evidence: <tech-log-tree node가 가리키는 증거와 원본 가이드 경로>
|
||||
|
||||
모든 command repair, prose rewrite, voice edit가 끝난 이 최종본을 원문과 역대조해라.
|
||||
수치·단위·경로 결합·미검증→확정 전환·유무 오기·비밀 노출을 본다.
|
||||
|
||||
돌려줄 것은 fact-reviewer 계약의 VERDICT: PASS | FAIL 형식이다.
|
||||
PASS만 S7로 갈 수 있다.
|
||||
```
|
||||
|
||||
두 결과를 각각 `qualityReviews.commandPedagogy.reviewer`와
|
||||
`qualityReviews.technicalEvidence`에 적은 뒤 S7로 간다.
|
||||
|
||||
|
||||
### R3 — schemaVersion 4 artifact / hash receipt
|
||||
|
||||
v4 원장은 “호출했다”는 문자열만으로 command lane을 통과시키지 않는다. 아래 JSON artifact를
|
||||
repository 안의 run 디렉터리에 보존하고 각각의 **repo-relative path + sha256**을 `run.json`에 적는다.
|
||||
|
||||
- `command-initial.json` → `qualityReviews.commandPedagogy.initialAnalysis.artifact`
|
||||
- `command-plan.json` → planner가 DONE일 때 `planner.artifact`
|
||||
- `command-patch-set.json` → editor가 DONE일 때 `editor.artifact`
|
||||
- `command-final.json` → `finalAnalysis.artifact`
|
||||
- `command-review.json` → reviewer가 DONE일 때 `reviewer.artifact`
|
||||
|
||||
영수증 형식은 다음이다.
|
||||
|
||||
```json
|
||||
{"path":"runs/<프로젝트>/<runId>/review/command-final.json","sha256":"<64 hex>"}
|
||||
```
|
||||
|
||||
파일을 저장한 뒤 `sha256sum <artifact>`로 실제 digest를 구한다. planner/editor를 조건상 SKIPPED한
|
||||
경우 해당 `artifact`는 `null`이다. command reviewer를 실행했다면 reviewer 결과 JSON에는
|
||||
`source_sha256`을 넣고, `run.json`의 reviewer `sourceSha256`에도 **최종 기록 파일의 SHA256**을
|
||||
같이 적는다.
|
||||
|
||||
```bash
|
||||
sha256sum <기록.md>
|
||||
sha256sum runs/<프로젝트>/<runId>/stage/S3/command-initial.json
|
||||
sha256sum runs/<프로젝트>/<runId>/review/command-final.json
|
||||
```
|
||||
|
||||
`fact-reviewer`도 같은 최종 기록을 검토했다는 증거로
|
||||
`qualityReviews.technicalEvidence.sourceSha256`에 동일한 최종 기록 SHA256을 적는다. 그 뒤에 기록
|
||||
파일을 한 글자라도 바꾸면 reviewer/fact-review를 다시 실행해야 한다.
|
||||
|
||||
schemaVersion 3 원장은 이 artifact/hash 필드가 생기기 전 계약이므로 소급해서 채우지 않는다.
|
||||
|
||||
---
|
||||
|
||||
## S7 — Studio 저장
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "command-patch-set.schema.json",
|
||||
"title": "CommandPatchSet",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"schema_version",
|
||||
"source_sha256",
|
||||
"patches"
|
||||
],
|
||||
"properties": {
|
||||
"schema_version": {
|
||||
"const": "1.0"
|
||||
},
|
||||
"source_sha256": {
|
||||
"type": "string",
|
||||
"pattern": "^[0-9a-f]{64}$"
|
||||
},
|
||||
"patches": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"block_id",
|
||||
"expected_sha256",
|
||||
"replacement_markdown"
|
||||
],
|
||||
"properties": {
|
||||
"block_id": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"expected_sha256": {
|
||||
"type": "string",
|
||||
"pattern": "^[0-9a-f]{64}$"
|
||||
},
|
||||
"replacement_markdown": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
{
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "command-plan.schema.json",
|
||||
"title": "CommandPlan",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"schema_version",
|
||||
"section_id",
|
||||
"source_sha256",
|
||||
"mode",
|
||||
"command_groups"
|
||||
],
|
||||
"properties": {
|
||||
"schema_version": {
|
||||
"const": "1.0"
|
||||
},
|
||||
"section_id": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"source_sha256": {
|
||||
"type": "string",
|
||||
"pattern": "^[0-9a-f]{64}$"
|
||||
},
|
||||
"mode": {
|
||||
"enum": [
|
||||
"tutorial",
|
||||
"operator",
|
||||
"diagnostic",
|
||||
"automation",
|
||||
"reference"
|
||||
]
|
||||
},
|
||||
"command_groups": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"id",
|
||||
"block_id",
|
||||
"source_sha256",
|
||||
"goal",
|
||||
"execution_context",
|
||||
"prerequisites",
|
||||
"steps",
|
||||
"cleanup"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"block_id": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"source_sha256": {
|
||||
"type": "string",
|
||||
"pattern": "^[0-9a-f]{64}$"
|
||||
},
|
||||
"goal": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"execution_context": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"host",
|
||||
"cwd"
|
||||
],
|
||||
"properties": {
|
||||
"host": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"cwd": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
}
|
||||
},
|
||||
"prerequisites": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
},
|
||||
"steps": {
|
||||
"type": "array",
|
||||
"minItems": 1,
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"command",
|
||||
"reason",
|
||||
"expected_result"
|
||||
],
|
||||
"properties": {
|
||||
"command": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"reason": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"expected_result": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"cleanup": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"command",
|
||||
"reason"
|
||||
],
|
||||
"properties": {
|
||||
"command": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
},
|
||||
"reason": {
|
||||
"type": "string",
|
||||
"minLength": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"schemaVersion": 2,
|
||||
"schemaVersion": 5,
|
||||
"runId": "<YYYY-MM-DD-HHMM>",
|
||||
"project": "<프로젝트>",
|
||||
"record": "<docs/<프로젝트>/tech-log-studio/<주제>/<종류>/<기록>.md — 이 런이 만드는 기록>",
|
||||
@@ -104,5 +104,68 @@
|
||||
"gates": [],
|
||||
"notes": ""
|
||||
}
|
||||
]
|
||||
],
|
||||
"qualityReviews": {
|
||||
"commandPedagogy": {
|
||||
"initialAnalysis": {
|
||||
"cmd": "",
|
||||
"exit": null,
|
||||
"shellBlocks": null,
|
||||
"findings": null,
|
||||
"majorFindings": null,
|
||||
"artifact": null
|
||||
},
|
||||
"finalAnalysis": {
|
||||
"cmd": "",
|
||||
"exit": null,
|
||||
"shellBlocks": null,
|
||||
"findings": null,
|
||||
"majorFindings": null,
|
||||
"artifact": null
|
||||
},
|
||||
"planner": {
|
||||
"runBy": "command-pedagogy-planner",
|
||||
"skill": "writing-practitioner-guides",
|
||||
"status": "PENDING",
|
||||
"skipReason": "",
|
||||
"skillEcho": "",
|
||||
"skillRevision": null,
|
||||
"notes": "",
|
||||
"artifact": null
|
||||
},
|
||||
"editor": {
|
||||
"runBy": "command-pedagogy-editor",
|
||||
"skill": "writing-practitioner-guides",
|
||||
"status": "PENDING",
|
||||
"skipReason": "",
|
||||
"skillEcho": "",
|
||||
"skillRevision": null,
|
||||
"notes": "",
|
||||
"artifact": null
|
||||
},
|
||||
"reviewer": {
|
||||
"runBy": "command-pedagogy-reviewer",
|
||||
"skill": "writing-practitioner-guides",
|
||||
"status": "PENDING",
|
||||
"skipReason": "",
|
||||
"skillEcho": "",
|
||||
"skillRevision": null,
|
||||
"verdict": null,
|
||||
"notes": "",
|
||||
"artifact": null,
|
||||
"sourceSha256": null
|
||||
}
|
||||
},
|
||||
"technicalEvidence": {
|
||||
"runBy": "fact-reviewer",
|
||||
"status": "PENDING",
|
||||
"skipReason": "",
|
||||
"verdict": null,
|
||||
"notes": "",
|
||||
"sourceSha256": null,
|
||||
"liveSourceReconciliation": null,
|
||||
"liveSourceReason": "",
|
||||
"acceptedByProjectReview": false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user