문서 목차
이 페이지에서목차

/cc-spec:verify — Jev 에게 판정받고 잠그기

Seed spec 을 기계 검사(M-01~M-10)한 뒤 Jev(판정 전용 모델)에 한 번 보내 모호성 점수(5차원)와 3관점 패널 판정을 보정 확률로 받고 `docs/spec-evaluation-{slug}.md` 를 남깁니다 — PASS 면 `--lock` 으로 DRAFT→LOCKED. API 키가 없으면 UNVERIFIED 로 멈추고 절대 통과로...

항목내용
실행 명령/cc-spec:verify
분류스펙 명확화
난이도●●● 높음

한마디로#

작성한 핵심 명세(Seed spec)가 개발을 시작해도 될 만큼 또렷한지를, 그 명세를 쓴 AI 가 아니라 별도의 "판정 전용 모델(Jev)" 에게 묻고, 합격이면 도장(잠금)을 찍는 단계입니다. 시험을 본 학생이 자기 답안을 채점하지 않고 채점관에게 넘기는 것과 같아요. Jev 는 글을 쓰지 않고 확률·선택·점수만 돌려주는 모델이라, "대충 괜찮아 보인다"는 말로 넘어갈 수 없습니다.

누가·언제 쓰나요#

  • /cc-spec:seed 로 초안을 만든 뒤, 이대로 확정해도 되는지 판정받고 싶을 때
  • 명세를 고친 뒤 다시 판정받고 싶을 때 (판정은 파일 내용 지문에 묶여 있어, 고치면 다시 받아야 합니다)
  • 판정을 통과한 명세를 더 못 바꾸게 잠가두고(LOCKED) 다음 단계로 넘어가고 싶을 때

👉 먼저 필요한 것: 환경변수 TYPESAFE_API_KEY. 없으면 이 명령은 "판정 불가(UNVERIFIED)"로 멈춥니다 — 통과가 아니며 잠글 수 없습니다.

무엇을 해주나요#

  • 1단계 — 기계 검사(무료, 즉시): 꼭 들어가야 할 10개 항목(M-01~M-10)이 채워졌는지 스크립트가 셉니다. 하나라도 빠지면 여기서 멈추고 보완 안내를 냅니다.
  • 2단계 — Jev 판정(한 번의 요청): 인수 기준·제약·엔티티 한 줄마다 좁은 질문을 붙여 한꺼번에 보냅니다(보통 20~40문항).
    • 모호성 5차원 — "이 줄에 모호한 말이 있나", "무엇이 계기이고 무엇이 관찰되나", "이 제약과 이 기준은 모순되나"를 줄마다 묻고, 걸린 줄을 코드가 세어 0~4 단계로 매깁니다 → 가중 평균이 0.2 이하이고 걸린 Must 줄·모순·빠진 엔티티·실패 사례 누락이 없으면 통과
    • 3관점 패널 — 분석가·PM·아키텍트 좌석을 역할극이 아니라 좁은 판정(관찰 가능한가·범위 안인가·타입을 정의할 수 있나)으로 코드가 계산 → 막는 좌석이 0개면 통과. 애매한 답은 찬성으로 세지 않습니다.
  • 리포트 — docs/spec-evaluation-{이름}.md 에 판정·확률·보완 안내를 남기고, 명세 파일의 메타데이터에 점수와 판정 도장(모델·날짜·지문)을 기록합니다.
  • 잠금 — 합격이고 --lock 을 붙였거나 확인하면 DRAFT → LOCKED.

판정 결과는 합격(PASS) / 조건부(CONDITIONAL) / 불합격(FAIL) / 판정 불가(UNVERIFIED) 넷 중 하나입니다.

어떻게 쓰나요#

/cc-spec:verify                      # 가장 최근 docs/seed-spec-*.md 를 판정
/cc-spec:verify --file {path}        # 특정 파일
/cc-spec:verify --lock               # 합격 시 바로 잠금
/cc-spec:verify --dry-run            # Jev 에 보낼 요청만 보여 주고 호출하지 않음 (판정 없음)

안에서 무슨 일이 벌어지나요#

  1. 대상·지문 채취 — 파일을 읽어 버전(vX.Y.Z)과 내용 지문(hash)을 적어 둡니다.
  2. 기계 검사 — 10항목을 셉니다. 못 읽는 표가 있으면 "통과"가 아니라 "판정 불가"로 막습니다.
  3. Jev 호출 — 명세를 JSON 으로 직렬화해(표는 배열로) 한 번 보냅니다. 인수 기준·제약·엔티티 한 줄마다 좁은 질문을 붙이므로 보통 20~40문항입니다.
  4. 판정 집계 — 걸린 줄을 코드가 세어 모호성 점수와 패널 세 좌석을 계산합니다. Must 줄이 하나라도 걸리면 점수가 낮아도 "고치고 다시"입니다. 답이 하나라도 빠지면 판정 불가.
  5. 리포트·메타데이터 — Jev 는 이유를 쓰지 않지만 어느 줄이 걸렸는지는 나옵니다. 그 줄과 채점 기준을 근거로 에이전트가 보완 안내를 씁니다. 판정 자체는 바꾸지 않습니다.
  6. 잠금 — 합격 + (--lock 또는 확인) 이면 상태를 LOCKED 로 바꾸고 변경 이력에 남깁니다.

⚠️ 한국어 보정은 결론을 아는 fixture 5건으로 확인했습니다(config/thresholds.yaml jev.calibration). 답한 모델 버전이 보정한 버전과 다르면 리포트에 경고가 붙고, 확률이 0.25~0.75 로 애매했던 줄(uncertain_rows)은 사람이 한 번 더 읽습니다.


⚙️ 상세 옵션·실행 명세 (개발자 / AI 에이전트용)

Usage#

/cc-spec:verify                      # latest docs/seed-spec-*.md
/cc-spec:verify --file {path}
/cc-spec:verify --lock               # lock on PASS without a second confirmation
/cc-spec:verify --dry-run            # print the Jev request; no call; no verdict

Parameters#

ParameterDescriptionDefault
--fileSeed spec pathlatest docs/seed-spec-*.md
--lockLock on PASSfalse (ask)
--dry-runBuild and print the request onlyfalse

Prerequisites#

  • TYPESAFE_API_KEY exported — or CLOUDFLARE_API_TOKEN + CLOUDFLARE_ACCOUNT_ID for the Workers AI route (see skills/jev-gate/SKILL.md → 준비; run jev_judge.py ping once first). Neither → UNVERIFIED, exit 3.
  • Python 3.10+ (jev_judge.py is stdlib-only).

Execution Flow#

Normative declaration. The step subsections 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 is the SoT for item criteria, skills/jev-gate/questions/*.json for the question texts and assertions, config/thresholds.yaml for the numbers.

V0     ACT   대상 스펙 결정 (--file | 최신)                              reads:docs/seed-spec-*.md
V0.1   ACT   specVersion + specHash 스탬프 채취 (jev_judge parse)         reads:docs/seed-spec-*.md
V1     GATE  Stage 1 기계 검사 (jev_judge check, M-01..M-10)            verdict:mechanical==="pass"  undet:fail  fail:Vfix
V2     ACT   Jev 요청 1회 — 줄 단위 ambiguity + panel 좌석 (jev_judge judge)  reads:skills/jev-gate/questions/ambiguity.json,skills/jev-gate/questions/panel.json
V2.g   GATE  Jev 게이트 (judge verdict === PASS — 걸린 줄·모순·누락 없음)  verdict:jev==="pass"  undet:fail  fail:Vfix
V3     ACT   리포트 발행 + 메타데이터(점수·Gate 스탬프) 기록              writes:docs/spec-evaluation-{slug}.md,docs/seed-spec-{slug}.md  own:lead
V4     GATE  잠금 요청 (--lock || 사용자 확인)                            verdict:lockRequested===true  undet:fail  fail:VEND
V5     ACT   DRAFT → LOCKED (Locked 날짜 + S6 "locked" 행)                writes:docs/seed-spec-{slug}.md  own:lead
VEND   ACT   보고만 하고 종료 (잠금 없음)
Vfix   LOOP  지적 반영 ↺ 재판정 (CONDITIONAL / FAIL)                     contract:L-spec.verify-fix-rejudge

V0 --> V0.1 --> V1 --> V2 --> V2.g --> V3 --> V4 --> V5
V4 --> VEND
Vfix --> V0.1
V1   ==> Vfix  on:mechanical!=="pass"   bound:2  invalidates:V1
V2.g ==> Vfix  on:jev!=="pass"          bound:2  invalidates:V1,V2,V2.g

읽는 법: 두 스테이지는 직렬이고 팬아웃이 없다 — V2 는 HTTP 요청 하나이지 에이전트 스폰이 아니므로 tier: 가 없다. 모든 되돌림은 Vfix 로 착지하고 Vfix --> V0.1 로 나가므로, 수정 라운드는 언제나 새 스탬프를 채취하고 Stage 1 부터 다시 시작한다. undet:fail 은 UNVERIFIED(키 부재 · API 오류 · 답변 누락 · 파싱 불가)를 뜻하며, 이는 Vfix 가 아니라 환경을 고친 뒤 재실행할 일이다 — 스펙을 고쳐도 해결되지 않는다.

Step 1 — Target + stamp#

JJ="${CLAUDE_PLUGIN_ROOT}/skills/jev-gate/scripts/jev_judge.py"
python3 "$JJ" parse docs/seed-spec-{slug}.md      # → version, status, spec_hash
  • Status must be DRAFT or LOCKED. On LOCKED, verify re-judges but never re-locks silently; say so.

Step 2 — Stage 1: mechanical#

python3 "$JJ" check docs/seed-spec-{slug}.md      # exit 0 PASS / 2 FAIL
  • exit 2 → render the checks table (✅/❌/⚠️), write remediation per failed detail, stop at Vfix.
  • ⚠️ UNVERIFIED (unparseable section) blocks like FAIL (eval G1).

Step 3 — Stage 2: one Jev request#

python3 "$JJ" judge --set ambiguity,panel --spec docs/seed-spec-{slug}.md > /tmp/jev-verify.json
# exit 0 PASS · 2 FAIL or CONDITIONAL · 3 UNVERIFIED
  • --dry-run prints request and stops. A dry run has no verdict field — never report it as one.
  • The JSON carries set_results.ambiguity (ambiguity_score, grade, dimensions, findings, flagged_must_rows, uncertain_rows), set_results.panel (blocking, panel[seat].counted_as, panel[seat].basis), results (raw per-question), spec_hash, usage, warnings, caveats.
  • A state over 32,000 chars or more than 200 constraint × criterion pairs is not sent (UNVERIFIED) — split the spec by domain.

Step 4 — Verdict#

Worst wins: UNVERIFIED > FAIL > CONDITIONAL > PASS (references/EVALUATION_PROTOCOL.md → Integrated Verdict). The agent may not alter a Jev verdict. It may disagree in the report's commentary and it may fix the spec.

Step 5 — Report + metadata#

  • Write docs/spec-evaluation-{slug}.md in the protocol's report format. Every table row carries the stamp.
  • Remediation prose comes from the agent: for each flagged row (findings, flagged_must_rows) and each non-APPROVE seat (basis), cite the row id, the Seed section and the rubric level text (references/AMBIGUITY_RUBRIC.md) that explains the gap.
  • Update the Seed metadata: - Ambiguity Score: {score} · - Gate: {verdict} ({model_reported} · {YYYY-MM-DD} · {spec_hash_short}) (this edit changes the file hash — the stamp in Gate: refers to the hash that was judged, by design).
  • If warnings says the answering model differs from the calibrated one, the report's Summary starts with that caveat, and borderline rows (uncertain_rows) are read by a person before locking.

Step 6 — Lock#

Conditions, all required: Stage 1 PASS · Jev PASS (not CONDITIONAL) · --lock or explicit user confirmation.

  • Status: DRAFT → LOCKED, - Locked: {YYYY-MM-DD}, append S6 row | {version} | {date} | locked (Gate PASS {spec_hash_short}) | verification | {approver} |.

Loop Contract#

L-spec.verify-fix-rejudge

inv:      라운드 진입 시 새 specHash 를 채취한다(Vfix --> V0.1). 이전 라운드의 모든 지적(실패한 M 항목 ·
          level ≥ 1 차원 · non-APPROVE 좌석)이 disposition 을 갖는다: fixed(스펙 위치 인용) | accepted(사유) |
          escalated(이슈 id)
prog:     open = disposition 이 없는 지적 수, 라운드마다 강한 감소. 같은 지적이 disposition 없이 두 번
          제기되면 진행 없음 — 남은 라운드를 같은 수정에 쓰지 않고 /cc-dev:unstuck 으로 올린다
term:     mechanical==="pass" && jev==="pass"
budget:   outer 2 라운드 (config/thresholds.yaml verify.max_fix_rounds; 각 ==> 의 bound:2). 3회째는 문구가
          아니라 문제 정의를 다시 잡을 신호다 — /cc-spec:seed 로 돌아간다
exhaust:  FAIL 확정 + 미해소 지적·마지막 disposition·스탬프를 리포트 라운드 표에 남기고 사람에게
          에스컬레이트. "경고 후 통과" 금지. UNVERIFIED 는 라운드를 소모하지 않는다(환경 문제)
resume:   docs/spec-evaluation-{slug}.md 의 라운드 표(라운드 · 스탬프 · Stage 1 · 2a · 2b · disposition)가
          위치 기록이다. 대화 카운터는 /clear 를 넘지 못하므로 예산이 아니다
log:      라운드당 한 줄 "round 2/2: open 3→1, fixed AC-03, stamp v1.0.1/9f3ac1, ambiguity 0.27→0.18"

Output#

FilePath
Evaluation reportdocs/spec-evaluation-{slug}.md
Seed spec (metadata; Status on lock)docs/seed-spec-{slug}.md

Next Steps#

  • PASS + locked → /cc-product:plan (Planning stage) · /cc-spec:status --against … for drift checks
  • CONDITIONAL → fix the flagged dimensions / seat, re-run (≤ 2 rounds)
  • FAIL → fix the relevant stage and re-run; after round 2, go back to /cc-spec:seed or a human
  • UNVERIFIED → set TYPESAFE_API_KEY / fix the parse error, re-run. Do not lock.
  • /cc-spec:seed — author the Seed spec
  • /cc-spec:status — read-only Jev drift report against the LOCKED seed
  • /cc-spec:evolve — evolve a LOCKED seed

References#

  • references/EVALUATION_PROTOCOL.md — item criteria + verdict rules (SoT)
  • skills/jev-gate/SKILL.md — jev_judge.py, question sets, fail-closed rules, calibration check
  • skills/jev-gate/questions/ambiguity.json, panel.json — the questions actually sent
  • config/thresholds.yaml — numbers
  • plugins/cc-dev/rules/orchestration-graph.md — flow notation (§1), loop contract (§2), gate tri-state (§3)

검색어를 입력하면 문서를 찾습니다.

↑ ↓ 이동 · Enter 열기Esc 닫기