/cc-spec:evaluate — 명세 최종 합격 심사#
| 항목 | 내용 |
|---|---|
| 실행 명령 | /cc-spec:evaluate |
| 분류 | 스펙 명확화 |
| 난이도 | ●●● 높음 |
한마디로#
작성한 기획 명세(Seed spec)가 다음 단계로 넘어가도 될 만큼 충분히 명확한지 세 번에 걸쳐 꼼꼼히 심사하는 최종 관문입니다. 운전면허 시험에 비유하면, 서류 확인(기계 검사) → 필기 시험(의미 검사) → 면접관 합의(전문가 합의)를 모두 통과해야 합격을 내주는 것과 같아요.
누가·언제 쓰나요#
- 기획 명세(Seed spec)를 다 작성하고 잠금(LOCKED)까지 끝낸 뒤, "이제 진짜 개발로 넘어가도 되나?"를 판정받고 싶을 때
- 앞선 사전 점검(모호성 점수, 반론 검토, 단순화 검토)을 마치고 종합 합격 여부를 확인하고 싶을 때
👉 이 명령을 돌리기 전에 아래 사전 준비가 끝나 있어야 합니다.
- Seed spec이 잠금(LOCKED) 상태
- 모호성 점수 평가 완료 (
/cc-spec:score) - 반론 검토 완료 (
/cc-spec:challenge) - 단순화 검토 완료 (
/cc-spec:simplify)
무엇을 해주나요#
세 단계 심사 결과를 종합해 합격 / 조건부 합격 / 불합격 판정을 내리고, 그 내용을 정리한 리포트 파일 한 개(docs/spec-evaluation-{이름}.md)를 만들어 줍니다.
- 합격(PASS): 다음 단계인 기획(Planning)으로 넘어갑니다.
- 조건부 합격(CONDITIONAL): 지적된 부분만 고친 뒤 다시 심사받습니다. 재심사는 최대 2번까지이고, 그 안에 지적이 정리되지 않으면 불합격으로 확정합니다.
- 불합격(FAIL): 문제가 된 단계를 고쳐 다시 심사합니다.
- 판정 불가: 세 심사위원 중 한 명이라도 의견을 내지 못하면 "합격 아님"이 아니라 불합격으로 처리합니다. 도착한 의견만으로 셈하지 않습니다.
어떻게 쓰나요#
/cc-spec:evaluate # 가장 최근 Seed spec을 심사
/cc-spec:evaluate --file {경로} # 특정 파일을 지정해서 심사
/cc-spec:evaluate --stage {1|2|3} # 특정 단계만 따로 심사
--file을 생략하면 가장 최근의 docs/seed-spec-*.md 파일을 자동으로 잡습니다.
--stage를 생략하면 1 → 2 → 3 단계를 순서대로 모두 돌립니다. (조건부 합격 후 마지막 단계만 다시 볼 때는 --stage 3처럼 쓰면 됩니다.)
⚠️ --stage 3만 다시 돌릴 때는 명세를 고친 뒤라면 1·2단계 결과가 옛 명세를 본 것이므로 그대로 쓰지 않습니다. 1·2단계는 기계적인 점검이라 값이 싸므로
자동으로 1단계부터 다시 돌리고, 그럴 수 없으면 심사를 거부합니다. 각 단계 결과 옆에는 그때 본 명세의 버전과 내용 지문(hash)을 함께 적어 둡니다.
안에서 무슨 일이 벌어지나요#
세 단계를 차례로 통과해야 최종 합격입니다. 한 단계라도 떨어지면 거기서 멈추고 고칠 부분을 알려 줍니다.
- 1단계 — 기계 검사: 10개 항목 체크리스트(M-01~M-10)를 기계적으로 점검합니다. 하나라도 실패하면 즉시 불합격, 10개 모두 통과해야 다음으로 넘어갑니다.
- 2단계 — 의미 검사: 세 가지를 확인합니다. ① 모호성 점수가 충분히 낮은지, ② 반론 검토에서 중대한 지적이 모두 해소됐는지, ③ 단순화 검토에서 모든 제안에 수락/거절 결정이 내려졌고 복잡도가 기준 이하인지.
- 3단계 — 전문가 합의: 세 명의 가상 전문가(분석가·PM·아키텍트)가 각자의 관점에서 명세를 검토하고 찬성/수정요청/반대 의견을 냅니다. 세 명 모두 지적은 반드시 하나씩 꺼내야 하지만, "지적했다"와 "이건 막아야 한다"는 다릅니다 — 구현을 막을 정도가 아니면 지적을 달아 둔 찬성이고, 이것도 찬성으로 셉니다. 막아야 한다는 의견이 0개면 합격, 1개면 조건부 합격, 그 이상이거나 반대가 하나라도 있으면 불합격입니다. 단 세 명의 의견이 전부 도착해야 판정합니다 — 두 명만 답했다면 "2명 찬성"이 아니라 판정 불가(불합격)이고, 빈자리를 찬성으로 메우지 않습니다.
마지막으로 심사 결과를 docs/spec-evaluation-{이름}.md 리포트로 정리해 줍니다.
⚙️ 상세 옵션·실행 명세 (개발자 / AI 에이전트용)
Usage#
/cc-spec:evaluate # Evaluate the latest Seed spec
/cc-spec:evaluate --file {path} # Evaluate a specific file
/cc-spec:evaluate --stage {1|2|3} # Run a specific stage onlyParameters#
| Parameter | Description | Default |
|---|---|---|
--file | Target file path | Latest docs/seed-spec-*.md |
--stage | Run specific stage only (1, 2, 3) | All (1→2→3) |
Prerequisites#
- Seed spec in LOCKED status
- Ambiguity score evaluation completed (
/cc-spec:score) - Contrarian review completed (
/cc-spec:challenge) — Required for Stage 2 - Simplifier review completed (
/cc-spec:simplify) — Required for Stage 2
Execution Flow#
Normative declaration of this command's flow. The stage subsections, verdict bullets and Next Steps
below are derived views (plugins/cc-dev/rules/orchestration-graph.md §6) — where they disagree,
this block wins. references/EVALUATION_PROTOCOL.md stays the SoT for the item criteria
(M-01..M-10 wording, 2a/2b/2c pass conditions) and config/thresholds.yaml for the numbers;
this block declares only the wiring — gates, stamps, fan-out and the back-edge.
E0 ACT 대상 스펙 결정 (--file | 최신) reads:docs/seed-spec-*.md
E0.1 ACT specVersion + specHash 스탬프 채취 reads:docs/seed-spec-*.md
E1 GATE Stage 1 기계 검사 (M-01..M-10) verdict:mechanical=== " pass " undet:fail fail:Efix
E2 GATE Stage 2 의미 검사 (2a+2b+2c) verdict:semantic=== " pass " undet:fail fail:Efix
E2.9 GATE Stage 1·2 스탬프 == 현재 스탬프 verdict:stage1.stamp===stamp & & stage2.stamp===stamp undet:fail fail:Efix
E3 LOOP Stage 3 판정 수집 (Analyst·PM·Architect) contract:L-spec.evaluate-stage3-judge-panel width:3 tier:standard
E3.j JOIN 정족수 집계 mode:barrier because:판정 하나는 나머지 둘과 대조해야 정족수가 된다 — §4.2 의 확인된 barrier 목록에 이 자리가 등재돼 있다
E3.g GATE 정족수 판정 verdict:verdicts===3 & & blocking===0 undet:fail fail:Efix
E4 ACT 결과 리포트 발행 writes:docs/spec-evaluation-{slug}.md own:lead
Efix LOOP 지적 반영 ↺ 재평가 (CONDITIONAL/FAIL) contract:L-spec.evaluate-outer-fix-reevaluate
E0 -- > E0.1 -- > E1 -- > E2 -- > E2.9 -- > E3 -- > E3.j -- > E3.g -- > E4
Efix -- > E1
E0.1 ~~ > E2.9 on:--stage==3 record:리포트에 인용한 Stage 1·2 스탬프 + " 이번 실행에서 재판정하지 않음 "
E1 ~~ > SKIP on:--stage==1 record:리포트에 " Stage 2·3 미판정 " — 단일 스테이지 PASS 는 Gate Passed 가 아니다
E2 ~~ > SKIP on:--stage==2 record:리포트에 " Stage 3 미판정 " — 단일 스테이지 PASS 는 Gate Passed 가 아니다
E1 == > Efix on:mechanical!== " pass " bound:2 invalidates:E1
E2 == > Efix on:semantic!== " pass " bound:2 invalidates:E1,E2
E2.9 == > Efix on:stampMismatch bound:2 invalidates:E1,E2
E3.g == > Efix on:blocking > 0||verdicts!==3 bound:2 invalidates:E1,E2,E2.9,E3,E3.j읽는 법(이하 모든 §는 plugins/cc-dev/rules/orchestration-graph.md 의 절): 세 스테이지는
직렬이고(§4.1 의 "순차는 정당한 답"), 병렬은 E3 안의 3 판정 하나뿐이며
width:3 이 그 상한이다. 모든 되돌림은 Efix 한 곳에 착지하고 Efix --> E1 로 나가므로, 수정 라운드는
언제나 Stage 1 부터 다시 시작한다 — E2.9 는 그 규칙을 --stage 3 단독 실행에도 강제하는 자리다.
Stage 1: Mechanical Verification#
10-item checklist from EVALUATION_PROTOCOL.md:
- Sequential inspection of M-01 through M-10
- Any FAIL → Overall FAIL + remediation guidance
- 10/10 PASS → Proceed to Stage 2
Stage 2: Semantic Verification#
3 sub-verifications:
2a. Ambiguity Score
- Check score in Seed spec metadata
- <= 0.2 PASS, > 0.3 FAIL
2b. Contrarian Review Results
- Check Contrarian review file in
docs/ - Confirm 0 unresolved Critical challenges
- Confirm responses exist for all Major challenges
2c. Simplifier Review Results
- Check Simplifier review file in
docs/ - Confirm accept/reject decisions exist for all proposals
- Confirm complexity score <= 30
2a + 2b + 2c all satisfied → Proceed to Stage 3
Stage Verdict Stamps — the --stage 3 staleness invariant (E0.1 · E2.9)#
Invariant: Stage 3 may only be judged when Stages 1 and 2 were judged against the exact spec version now under review. Record the stamp next to every stage verdict, not just once per report:
| Field | Value | Where it comes from |
|---|---|---|
specVersion | SemVer vX.Y.Z of the Seed spec | Seed spec metadata (the same field M-10 checks) |
specHash | content hash of the target file, e.g. git hash-object docs/seed-spec-{slug}.md | recomputed at E0.1 on every run, including --stage runs |
E2.9 compares stage1.stamp and stage2.stamp against the stamp taken at E0.1. On mismatch there
are exactly two dispositions — never a third:
- Re-run Stages 1 and 2 (default). They are cheap mechanical checks: a checklist pass plus three file reads. Re-running is idempotent and produces fresh stamps.
- Refuse — report
판정 불가and stop, when the target file cannot be re-read or hashed.
Reusing a Stage 1/2 verdict whose stamp differs from the current one is prohibited: it is the
null-as-pass form (plugins/cc-dev/rules/orchestration-graph.md §3.2) applied to a stale pass —
the spec that passed the mechanical checks is not the spec the panel is looking at. A missing stamp
(older reports predate this field) counts as a mismatch, i.e. undetermined → fail, not as a match.
Stage 3: Consensus Verification#
3-agent panel simulation:
- Analyst perspective: Requirements completeness, testability, AC quality
- PM perspective: Business goal alignment, prioritization, ROI
- Architect perspective: Feasibility, technical constraints, scalability
Each renders APPROVE / REQUEST_CHANGES / REJECT verdict.
⛔ Panelists are prompt-only personas, not registered agent types. The panel runs as three
agent()calls inside oneWorkflowparallel()(see Substrate); pass no customagentType— use the default workflow agent with a role-framed prompt and alabel(Analyst/PM/Architect). There is nocc-pm:*,cc-bmad:*, orcc-product:*agent type (those plugins ship skills/commands only —cc-producthas noagents/at all), so mapping a panelist to e.g.agentType: 'cc-pm:product-vision'fails withagent type not found.product-visionis a skill, never an agent.
Substrate — Workflow parallel(), width 3, barrier join
parallel() is the right substrate here specifically, and this is not a new fan-out — it is the
cap and the tier: on the three judgments this command already runs:
- Barrier is genuinely required. A single verdict means nothing on its own; the quorum compares
each verdict against the other two. That cross-item justification is the
because:ofE3.j'smode:barrier, andplugins/cc-dev/rules/orchestration-graph.md§4.2 already lists "cc-spec/commands/evaluate.mdStage 3 합의 정족수" among the confirmed-legitimate barriers — this is that barrier's own site. width:3is fixed, not data-driven. It comes fromconfig/thresholds.yamlevaluation.panel_size: 3. Nothing here scales with input size, so §4's Workflow row is used for its determinism and its barrier, not for width.- Schema-forced enum verdicts. Each
agent()returns the verdict as one enum value (APPROVE | REQUEST_CHANGES | REJECT) plus an objection list — never free prose that the quorum has to parse. An output that does not fit the schema isundetermined, andundeterminedis not a verdict (§3). tier:per judge is explicit (tier:standardonE3). §5: unset means silent inherit, and at degree 3 an unset tier is a 3× multiplier, not a default.- Nothing merges or locks here. The Workflow substrate has no human approval step (§4), so this
command stops at a report;
PASSis an input to the Planning gate, never an auto-advance. - Fallback is sequential, with no feature difference (§5 Fallback Principle). If
parallel()is unavailable, run the three personas one after another — but still aggregate once, after all three verdicts exist. Judging the quorum incrementally is prohibited.
The three stages themselves stay strictly sequential: Stage 3 never starts before Stage 2 passes,
and --stage 3 is not an exception (that is what E2.9 enforces).
Objection ≠ blocking verdict
references/EVALUATION_PROTOCOL.md Stage 3 requires every panelist to surface a concrete objection
(bare APPROVE is forbidden). That obligation is about raising an issue; the quorum counts
blocking verdicts. Keeping the two separate is what makes PASS reachable for a compliant panel:
| Panelist output | Meaning | Counted as |
|---|---|---|
| APPROVE-with-notes | objection(s) raised, panelist states none of them block implementation | APPROVE (non-blocking) |
| APPROVE (no objection) | only with an explicit "looked for an objection, found none because X" | APPROVE (non-blocking) |
| REQUEST_CHANGES | the panelist claims this blocks implementation — reserved for exactly that | blocking |
| REJECT | fundamental problem, reasons stated | blocking |
blocking = count(REQUEST_CHANGES) + count(REJECT). A panelist who raises three objections and marks
all three as non-blocking issues an APPROVE-with-notes verdict, not REQUEST_CHANGES — so a panel
that fully obeys the anti-rubber-stamp rule can still reach 3/3 APPROVE and PASS.
Verdict record (per panelist row). Fill these columns in the report's Stage 3 table (base template:
references/EVALUATION_PROTOCOL.md → Result Report Format):
| Column | Value |
|---|---|
Verdict | one enum value — APPROVE / REQUEST_CHANGES / REJECT |
Objections | OBJ-{round}-{role}-{n} ids, e.g. OBJ-1-Architect-2. Never empty: if none, the cell holds "looked for an objection, found none because {reason}" |
Blocking? | yes/no per objection id. Any yes ⇒ that panelist's Verdict must be REQUEST_CHANGES or REJECT |
Stamp | the specVersion + specHash this panelist actually read |
Consensus Verdict (E3.g) — evaluated over the complete set of three verdicts:
| Condition | Verdict |
|---|---|
verdicts !== 3 (a panelist never reported, or its output failed the enum schema) | FAIL — 판정 불가 |
verdicts === 3 && blocking === 0 (3/3 APPROVE, notes included) | PASS |
verdicts === 3 && blocking === 1 && count(REJECT) === 0 | CONDITIONAL (≤ 2 rounds — L-spec.evaluate-outer-fix-reevaluate) |
otherwise (blocking >= 2, or any REJECT) | FAIL |
⛔ Missing panelists are undetermined, and undetermined is fail (§3). Never renormalise the
denominator: two APPROVEs out of two arrivals is not "2/3 APPROVE → CONDITIONAL" and not
"3/3 APPROVE → PASS" — it is verdicts === 2 → FAIL. An empty seat is never filled with APPROVE, and
min_consensus: 3 in config/thresholds.yaml is a count of arrived verdicts, not of survivors. This
is the empty-set pass / nothing-to-check pass pair in §3.2 read at the quorum.
Final Verdict#
- Stage 1 + 2 + 3 all PASS against one and the same stamp → Specification Gate Passed
- Any stage FAIL or
판정 불가→ Fix and re-evaluate throughEfix(≤ 2 rounds) - A single-stage run (
--stage 1|2|3) never yields Specification Gate Passed — it reports that stage only, and the report records which stages were not judged
Loop Contracts#
Field shapes and the 7-field obligation come from plugins/cc-dev/rules/orchestration-graph.md §2;
the values below live here, at the loops' own site.
L-spec.evaluate-stage3-judge-panel
inv: 한 라운드에 판정은 정확히 3개(`config/thresholds.yaml` evaluation.panel_size)이고, 각
판정은 enum 한 값 + objection id 목록 + 스탬프를 갖는다 — iteration 진입·종료 양쪽에서 확인
prog: missing = 3 - (스키마에 맞는 판정 수), 매 iteration 강한 감소
no-prog: 같은 페르소나를 같은 프롬프트로 재호출 금지. 프롬프트를 고칠 수 없으면 그 판정을
미도착으로 확정하고 루프를 끝낸다 — 빈자리를 APPROVE 로 메우지 않는다
term: missing === 0
budget: 3 판정 × 재호출 1회 = 최대 6 agent() 호출. width:3 은 상한이며 입력 크기로 늘지 않는다
exhaust: missing > 0 → Stage 3 = 판정 불가(undetermined) → **FAIL**. 도착한 판정만으로 정족수를
계산하는 것( " 2/3 APPROVE → CONDITIONAL " )을 금지한다. 디스패치된 워커 안이면 대화형
AskUserQuestion 은 유효한 exhaust 가 아니다(§2)
resume: 리포트 Stage 3 표 — enum 값과 스탬프가 채워진 역할 행은 재호출하지 않는다(재호출은 멱등:
같은 역할·같은 스탬프의 판정은 덮어쓴다)
log: iteration 당 한 줄 " panel #2: missing 3→1 (Architect 미도착) " + 스키마 위반으로 **탈락시킨**
출력과 그 이유L-spec.evaluate-outer-fix-reevaluate
The CONDITIONAL/FAIL back-edge (E1|E2|E2.9|E3.g ==> Efix). This is the only loop that re-enters the
whole flow, and it is capped.
inv: 라운드 진입 시 Stage 1·2 스탬프 == 현재 specHash. 다르면 그 라운드는 E1 부터 시작한다
(Efix -- > E1). 이전 라운드의 objection id 전부가 disposition 을 갖는다:
resolved(근거 인용) | escalated(이슈 id) | withdrawn(패널 철회 + 이유)
prog: unresolved = disposition 이 없는 objection id 수, 라운드마다 강한 감소.
**같은 objection id 는 resolved/escalated 되지 않은 채 두 번 제기될 수 없다** — 두 번째
제기는 진행 없음으로 읽는다
no-prog: 같은 id 가 그대로 남았으면 남은 라운드를 같은 수정에 쓰지 않고 Rung 2 로 올린다
term: verdicts === 3 & & blocking === 0 (E3.g PASS)
budget: outer 2 라운드 (각 `== > ` 의 bound:2). inner 루프는 L-spec.evaluate-stage3-judge-panel.
2 의 근거: 라운드마다 사람이 Seed spec 원문을 고치므로 3회째는 문구가 아니라 문제 정의를
다시 잡을 신호다 — `config/thresholds.yaml` seed_spec.max_evolution_per_cycle: 3 의 안쪽
exhaust: FAIL 확정 + 미해소 objection id·마지막 disposition·스탬프를 리포트에 남기고
`/cc-spec:evolve` 또는 사람으로 에스컬레이트. " 경고 후 통과 " 금지
resume: `docs/spec-evaluation-{slug}.md` 의 라운드 표(라운드 번호 · objection id · disposition ·
스탬프)가 위치 기록이다. 대화 카운터는 /clear 를 넘지 못하므로 예산이 아니다
log: 라운드당 한 줄 " round 2/2: unresolved 3→1, escalated OBJ-1-Architect-2, stamp v1.2.0/9f3ac1 "Round table (required in the report). Each round records the prior round's objections and what
happened to them — a round that cannot show the previous round's dispositions has no prog: and is
treated as exhausted:
| Round | Objection id | Raised by | Blocking? | Disposition | Evidence / issue id | Stamp |
|---|---|---|---|---|---|---|
| 1 | OBJ-1-Architect-1 | Architect | yes | resolved | Seed spec S2, constraint 3 | v1.1.0 / 3ab91c |
| 2 | OBJ-1-Architect-2 | Architect | yes | escalated | #412 | v1.2.0 / 9f3ac1 |
Result Report Generation#
- Generate
docs/spec-evaluation-{slug}.md - Every stage verdict carries its
specVersion+specHashstamp; Stage 3 additionally carries the per-panelistObjections/Blocking?columns and the round table above
Output#
| File | Path |
|---|---|
| Evaluation Result Report | docs/spec-evaluation-{slug}.md |
Next Steps#
- PASS → Proceed to Planning stage in
cc-product - CONDITIONAL → Fix the flagged items, record each objection id's disposition, then re-run
/cc-spec:evaluate --stage 3. ≤ 2 rounds; if the spec file changed,E2.9sends the round back through Stages 1–2 first - FAIL / 판정 불가 → Fix the relevant stage and re-evaluate; after the 2nd round, escalate
(
/cc-spec:evolveor a human) instead of re-running
Related Commands#
/cc-spec:score— Ambiguity score (Stage 2a prerequisite)/cc-spec:challenge— Contrarian review (Stage 2b prerequisite)/cc-spec:simplify— Simplifier review (Stage 2c prerequisite)/cc-spec:verify— Structural verification (similar to Stage 1)
References#
references/EVALUATION_PROTOCOL.md— Detailed 3-stage protocol (item criteria SoT; the flow wiring is the```flowblock above)config/thresholds.yaml— Threshold settings (evaluation.panel_size,min_consensus,seed_spec.max_evolution_per_cycle)plugins/cc-dev/rules/orchestration-graph.md— flow notation (§1), loop contract (§2), gate tri-state (§3), substrate matrix + confirmed barriers (§4, §4.2), fan-out obligations (§5)