LogoSkills

/cc-spec:evaluate — 명세 최종 합격 심사

3단계 통합 평가 — 기계적·의미적·합의 검증을 통한 Specification Gate 판정

/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. 1단계 — 기계 검사: 10개 항목 체크리스트(M-01~M-10)를 기계적으로 점검합니다. 하나라도 실패하면 즉시 불합격, 10개 모두 통과해야 다음으로 넘어갑니다.
  2. 2단계 — 의미 검사: 세 가지를 확인합니다. ① 모호성 점수가 충분히 낮은지, ② 반론 검토에서 중대한 지적이 모두 해소됐는지, ③ 단순화 검토에서 모든 제안에 수락/거절 결정이 내려졌고 복잡도가 기준 이하인지.
  3. 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 only

Parameters#

ParameterDescriptionDefault
--fileTarget file pathLatest docs/seed-spec-*.md
--stageRun 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 미판정 "   — 단일 스테이지 PASSGate Passed 가 아니다
E2   ~~ >   SKIP  on:--stage==2              record:리포트에  " Stage 3 미판정 "   — 단일 스테이지 PASSGate 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:

FieldValueWhere it comes from
specVersionSemVer vX.Y.Z of the Seed specSeed spec metadata (the same field M-10 checks)
specHashcontent hash of the target file, e.g. git hash-object docs/seed-spec-{slug}.mdrecomputed 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:

  1. 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.
  2. 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:

  1. Analyst perspective: Requirements completeness, testability, AC quality
  2. PM perspective: Business goal alignment, prioritization, ROI
  3. 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 one Workflow parallel() (see Substrate); pass no custom agentType — use the default workflow agent with a role-framed prompt and a label (Analyst/PM/Architect). There is no cc-pm:*, cc-bmad:*, or cc-product:* agent type (those plugins ship skills/commands only — cc-product has no agents/ at all), so mapping a panelist to e.g. agentType: 'cc-pm:product-vision' fails with agent type not found. product-vision is 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: of E3.j's mode:barrier, and plugins/cc-dev/rules/orchestration-graph.md §4.2 already lists "cc-spec/commands/evaluate.md Stage 3 합의 정족수" among the confirmed-legitimate barriers — this is that barrier's own site.
  • width:3 is fixed, not data-driven. It comes from config/thresholds.yaml evaluation.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 is undetermined, and undetermined is not a verdict (§3).
  • tier: per judge is explicit (tier:standard on E3). §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; PASS is 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 outputMeaningCounted as
APPROVE-with-notesobjection(s) raised, panelist states none of them block implementationAPPROVE (non-blocking)
APPROVE (no objection)only with an explicit "looked for an objection, found none because X"APPROVE (non-blocking)
REQUEST_CHANGESthe panelist claims this blocks implementation — reserved for exactly thatblocking
REJECTfundamental problem, reasons statedblocking

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):

ColumnValue
Verdictone enum value — APPROVE / REQUEST_CHANGES / REJECT
ObjectionsOBJ-{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
Stampthe specVersion + specHash this panelist actually read

Consensus Verdict (E3.g) — evaluated over the complete set of three verdicts:

ConditionVerdict
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) === 0CONDITIONAL (≤ 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 stampSpecification Gate Passed
  • Any stage FAIL or 판정 불가 → Fix and re-evaluate through Efix (≤ 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  >   0Stage 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:

RoundObjection idRaised byBlocking?DispositionEvidence / issue idStamp
1OBJ-1-Architect-1ArchitectyesresolvedSeed spec S2, constraint 3v1.1.0 / 3ab91c
2OBJ-1-Architect-2Architectyesescalated#412v1.2.0 / 9f3ac1

Result Report Generation#

  • Generate docs/spec-evaluation-{slug}.md
  • Every stage verdict carries its specVersion + specHash stamp; Stage 3 additionally carries the per-panelist Objections / Blocking? columns and the round table above

Output#

FilePath
Evaluation Result Reportdocs/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.9 sends the round back through Stages 1–2 first
  • FAIL / 판정 불가 → Fix the relevant stage and re-evaluate; after the 2nd round, escalate (/cc-spec:evolve or a human) instead of re-running
  • /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 ```flow block 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)