Files
company-haness/.claude/commands/review-output.md
T

78 lines
6.1 KiB
Markdown

---
description: OPS-ORCH가 QA/감사 role의 exact review를 조율한다.
---
당신은 concrete executor `OPS-ORCH`다. 검토 산출물 producer/reviewer는 계약에 등록된 `QA`,
`EXEC-VPENG`, `SEC-ENGINEER` 같은 concrete role이어야 하며 family ID는 actor가 아니다.
**workflow-stage = `verification`→`acceptance`.**
입력: 검토 대상 `<workflow-id>`(인자, `--workflow <wf>`).
## 상태엔진 게이트(진입) — build→verification 선행조건 강제
- **guard(진입 게이트):** `python3 .claude/hooks/state_engine.py guard --workflow <wf> --to verification`.
- 이 게이트는 `build→verification`(cascade) 또는 `run→verification`(wave/light)의 선행조건 = **completion-record-present**를 강제한다. **exit 2면 검토를 시작하지 않는다** — completion-record가 없으면 `/build`(또는 `/run-wave`)를 먼저 완료하라는 신호(미충족 사유 포함 BlockedReport). exit 0이면 진행.
- exit 0이면 `state_engine.py enter-stage --workflow <wf> --to verification --actor OPS-ORCH`
`verification.running`을 연다.
## 불변 스냅샷 + append-only 이벤트 모델 (#14)
리포트(`.report.yaml`)는 **불변 SNAPSHOT**이다 — 검토 결과로 그 파일의 상태를 고치지 않는다.
대신 검토 결정(Accepted/Changes-Requested/Blocked)을 **append-only 이벤트**로 남긴다
(`acceptance_log.py``<workspace>/state/acceptance-events.jsonl`). 그래야 어느 스냅샷이
최신 시도인지·무엇이 수락됐는지·무엇을 대체(supersede)했는지 감사 가능하게 추적된다.
## 절차
1. 검토 대상 리포트를 특정한다: 해당 workflow/role의 **최신 시도 스냅샷**
(`completion-records/<workflow>/<role>-*.report.yaml` 중 최신 `attempt-id`).
이미 내려진 최신 수락 상태는 아래로 조회한다:
```bash
python3 .claude/hooks/acceptance_log.py latest-accepted --workflow <WF> --role <ROLE>
```
2. 그 리포트의 `report-header`·`evidence`를 확인한다.
3. **evidence 검증**(validate_report와 동일 기준): source-uri 실존, grade 정합(E4/E5는 실행/실존 아티팩트), confidence:High는 E3+ 근거 필수. 새 workflow의 Passed check는 일반 Bash receipt가 아니라 아래처럼 실제 exit code를 소유하는 runner로 실행한다:
```bash
python3 .claude/hooks/verify_run.py \
--workflow <WF> --agent QA --session <SESSION-ID> \
--category test --subject <CHECK-SUBJECT> \
--source-revision-sha256 <64-HEX-SOURCE-REVISION> -- \
<test-runner> <test-args...>
```
shell 문자열이 아니라 argv를 직접 넘긴다. 출력된 `receipt-id`를 quality check에 결속한다.
4. `state-transition-rules.yaml`의 `Submitted-for-Review → Accepted` 조건 확인: acceptance-decision-present, quality_gate_status=Passed, handoff-to 또는 closure-reason.
5. 결정한다:
- **Accepted**: 조건 충족.
- **Changes-Requested**: required-changes를 구체적으로 명시.
- **Blocked**: blocked-report + resume-condition 작성 → OPS-ORCH가 queue 등록.
6. **정확한 revision을 권한 있는 reviewer가 검토한다**(리포트를 수정하지 말 것):
```bash
python3 .claude/hooks/state_engine.py review-artifact \
--workflow <WF> --report <COMPLETION-REPORT-PATH> \
--decision <DECISION> --reviewer QA
```
엔진은 등록 artifact의 id+sha256, producer, reviewer capability와 self-review=false를 검증한다.
- 이 결정이 이전 시도를 대체하면(재작업 후 수락 등) 그 이전 스냅샷의 report-id를
`--supersedes <PRIOR-REPORT-ID>`로 함께 넘긴다(계보 연결 → 태그 검색에서 낡은 것 자동 제외).
- Changes-Requested/Blocked면 그 스냅샷이 rejected로 기록되어, 이후 수정본은
`new_report.py --supersedes <이 report-id>`로 새 스냅샷을 만든다.
## 상태엔진 전이(종료) — 결정에 따라 stage 전진/차단
7. QA가 `artifact-kind: quality-gate-review` 보고서를 낸다. payload에는 `quality-gate.status`,
`blocker-open`, 검토한 completion의 `reviewed-artifact-id`/`reviewed-artifact-sha256`를 넣는다. 각 `checks[].category`는 결속한 typed receipt의 `verification_category`와 같아야 하고, Passed는 `assertion_status=passed`, `exit_code=0`이어야 한다. standard/heavy Passed receipt는 completion과 동일한 source revision hash가 필수다. 그 뒤:
`state_engine.py record-quality-gate --workflow <wf> --review <review-path> --actor QA`.
8. 검토 결정에 따라 stage를 완료/진입한다:
- **Accepted**이고 quality event가 Passed/false면 `complete-stage --workflow <wf>
--actor OPS-ORCH --evidence <review-path>`로 verification을 완료한 후
`enter-stage --workflow <wf> --to acceptance --actor OPS-ORCH`를 실행한다.
(`verification→acceptance` gate를 두 호출 모두 재확인한다.)
- **Changes-Requested**: stage를 전진시키지 않는다(리포트는 rejected 이벤트로 기록, 수정본은 새 스냅샷).
- **Blocked**: `artifact-kind: blocked-report`에 blocker + resume-condition을 작성한 뒤
`state_engine.py block --workflow <wf> --report <path> --actor OPS-ORCH`.
## 산출
`acceptance-decision`. report-header(BLUF)로 시작: bottom-line=결정, decision-needed(needed/approver), confidence(evidence 파생), risks, evidence.
그리고 위 6단계로 **append된 acceptance-event-id** + 7단계로 수행한 **state 전이**를 산출에 명시한다(결정=이벤트, 리포트 mutation 아님).
- **다음**(Accepted): cascade/wave는 `/release-check`(Release Acceptance + 인간 게이트)로 진행한다. light plan은 `acceptance`가 종단이므로 release-check/released 전이를 실행하지 않는다.
## 규칙
- completion-record 없이 Accepted 처리 금지. self-reported quality_gate만으로 통과 금지(근거 확인 필수).
- 리포트 스냅샷은 **불변** — 상태 변화는 `acceptance_log.py` 이벤트로만. 리포트 파일을 덮어쓰지 않는다(guard_tools가 차단).
- 최신 수락 상태는 이벤트 원장(`latest-accepted`)이 정본 — 스냅샷 개별 파일이 아니다.