# 12 · ECC 상류 대비 mccp 개선 여지 (2026-08-13)

> **대상**: mccp (fork base ECC v1.8.0, 2026-03-04) vs [affaan-m/ecc](https://github.com/affaan-m/ecc) **v2.2.0** (HEAD `eb49702`, 2026-08-12)
> **관점**: 라운드 수렴 문제(`11-review-round-remediation.md`)와 상류 이슈 #124·#125·#127·#128 을 개선할 수 있는가
> **성격**: 분석. 확정 아님. §C 는 **개발 방향성 변경 판단용**이며 사용자 결정 사항이다.

---

## 0. 규모 대조

| 축 | ECC 2.2.0 | mccp 1.23.7 |
|---|---|---|
| skills | 284 | 47 (16.5% 포크) |
| commands | 94 | 21 |
| workflows | `orch-review.workflow.js` (실행 코드 296행) | 없음 |
| receipt / gate chain | **없음** (`gate_id` 0건) | 있음 — mccp 순수 추가분 |
| santa-loop | 175행 (구버전) | 260행 (**mccp 가 앞섬**) |

**핵심 판정**: ECC 2.x 는 **넓이**로 갔고(언어·도메인·다국어·커뮤니티), mccp 는 **깊이**로 갔다(게이트·receipt·해시 앵커). 전면 리베이스는 mccp 고유 가치를 파괴한다. 아래 §A 는 **선별 이식** 목록이다.

---

## A. 상류가 앞선 것 — 이식 후보 (효익순)

### A1. `workflows/orch-review.workflow.js` — 리뷰를 산문이 아니라 실행 코드로

`santa-loop-materialize` PRD 가 *"199행 산문이고 백킹 코드가 0"* 이라 적은 그 자리에 상류는 **296행 실행 workflow** 를 갖고 있다. 설계가 #124·#125 를 구조로 답한다.

| 상류 기제 | 코드 | mccp 이슈 대응 |
|---|---|---|
| **차원 fan-out** — quality + language + 조건부 security 를 병렬 리뷰 | `dimensions[]` 배열, `parallel()` | 라운드당 리뷰어 2명(범용)을 **차원 N명**으로. 층위를 라운드로 발견하던 것을 한 라운드에 펼친다 |
| **적대적 검증 2단계** — CRITICAL/HIGH 마다 반증 시도 | `verifyPrompt` + `VERDICT_SCHEMA` | 오탐 기각을 사람이 매 라운드 손으로 하던 것을 기계 단계로. `10-index-git-m7` 기각 8/48 · 다른 라운드 오탐 4/6 |
| **불확실은 blocking 유지** | `REFUTE_MIN_CONFIDENCE = 0.8`. `isReal=false` 라도 confidence < 0.8 이면 blocking | "확신 없는 반증" 이 blocker 를 강등시키지 못한다 |
| **degrade 가 시끄럽다** | `incomplete` · `failedDimensions[]` → `verdict: CHANGES_REQUESTED` | **#125 항목 3 을 구조로 해결.** 리뷰어가 죽으면 APPROVE 가 안 나온다 |
| **증거 스니펫 기준 dedup** | `${file}::${normalize(evidence)}` — title·line 아님 | 리뷰어 행번호가 28~53줄 어긋나던 실측 조건에서도 dedup 이 성립한다 |
| **stats 블록** | `{dimensions, failed, raw, unique, confirmed, unverified, uncertain, refuted}` | **`review-loop-trust` 가 "없어진 분모" 라고 한 `rejected` 계수가 여기 있다.** receipt 149건 `resolution.rejected` 총합 0 이던 자리 |
| **입력 fail-closed** | 빈 diff · 잘못된 `changedFiles` 는 throw | *"리뷰하지 못한 payload 를 조용히 APPROVE 하지 않는다"* |

> **주의**: 이 workflow 는 diff 리뷰용이다. mccp 의 plan 단계 리뷰(문서 산출물)에 그대로 못 쓴다. 가져올 것은 **파일이 아니라 6가지 설계 결정**이다.

### A2. `skills/loop-design-check` — 판정 층 규율 (mccp 미포크)

mccp 는 루프 **기제** 스킬을 포크했는데(`verification-loop`·`eval-harness`·`continuous-learning-v2`) **판정 층** 스킬을 안 가져왔다. 이게 라운드 문제의 상위 프레임이다. 핵심 5가지:

1. **목표는 기계 판정 가능해야 한다** — 아니면 comparator 가 못 끝낸다.
2. **주장(assertion)보다 대조(reconciliation)를 선호하라** — golden sample / upstream total 같은 **외부 사실**에 앵커. *"모든 테스트 통과" 는 게임할 수 있고(assert 완화·mock 위조·예외 삼킴) "기준 대비 diff < 0.01" 은 못 한다.*
3. **완료 조건과 경계 조건을 같이 정의하라** — 경계 없는 완료 조건은 치팅 면허(Goodhart). *"테스트 전부 통과" 만 걸면 에이전트가 테스트를 지운다.*
4. **모든 해명은 앞당겨라(front-load)** — 실행 중 물어볼 거라 기대하지 마라. 안 묻고 틀린 답을 끝까지 실행한다.
5. **판정은 사람에게 남긴다** — 루프는 작업자지 인수 담당이 아니다.

그리고 **리뷰 체크리스트 5 실패 모드** — 루프 자체를 이걸로 검사한다. `santa-loop` 을 이 5행에 넣으면 최소 2개(#2 판사가 피고 자신 / #4 실행 중 해명 기대)에 걸린다.

### A3. plan 템플릿 — **mccp 가 상류보다 후퇴했다** (#127 증거 보강)

ECC `commands/prp-plan.md` 템플릿에 있고 mccp `commands/plan.md` 에 **0건**인 것 (실측 grep):

| 상류 섹션 | mccp | 겨냥하는 층위 |
|---|---|---|
| `## NOT Building` — 명시적 범위 밖 | **0건** | 경계 조건 = Goodhart 항체. #128 불변식의 계획 단위 판 |
| `EXPECT:` — 모든 validation 명령마다 기대 결과 명기 | **0건** | **"명령 ≠ 게이트" 의 직접 항체.** mccp 는 `{project-specific validation commands}` 자유 블록 |
| `GOTCHA:` — Task 필드, 알려진 함정 | **0건** | 층위 1 사실 오류 |
| `## Testing Strategy` + Edge Cases 체크리스트 | **0건** | 층위 6 |
| `## Mandatory Reading` — P0/P1/P2 + 행 범위 | **0건** | 그라운딩 |
| Patterns to Mirror = **실제 코드 스니펫** + `// SOURCE: file:lines` | 3행 표 + 짧은 서술 | 패턴 재발명 |
| Task 필드 6종 (ACTION/IMPLEMENT/MIRROR/IMPORTS/GOTCHA/VALIDATE) | 3종 (Action/Mirror/Validate) | — |

**mccp 의 `plan.md` 는 2067행인데 그중 산출물 계약은 65행이고, 나머지가 전부 게이트 기계다.** 상류는 502행 중 약 180행이 계약이다. 게이트를 쌓는 동안 **계약이 줄었다** — #127 의 논지가 상류 대조로 확증된다.

### A4. `schemas/state-store.schema.json` (`ecc.state-store.v1`) — 계측 substrate

```
sessions · skillRuns · skillVersions · decisions · installState · governanceEvents · workItems
```

`review-loop-trust` 우산 PRD 의 핵심 증거가 *"receipt 149건: findings 총합 3 · rejected 총합 0 · duration 보유 0"* 이다. 마크다운 STATE.md + 파일당 JSON receipt 로는 질의가 안 된다. 상류는 **질의 가능한 상태 저장소 + CLI** 를 이미 갖는다(1.9.0, #510). `decisions` · `governanceEvents` 가 mccp 의 receipt·원장 축에 대응한다.

### A5. `epic-*` 명령 + `scripts/github-coordination.js` — 세션 밖 조정 substrate

`epic-decompose` / `epic-claim` / `epic-sync` / `epic-unblock` / `epic-validate` / `epic-publish`. 분해 결과를 **GitHub 이슈 본문의 coordination block** 에 저장하고 감사 코멘트를 남긴다. 진행 상태가 세션 밖에 산다.

`multi-session-work-loop` PRD 의 *"진행 상태가 사람이 손으로 관리하는 텍스트라 세션이 늘수록 실제 상태와 어긋난다"* 에 대한 상류의 답이다. mccp 는 `.claude/state/STATE.md`(세션 로컬 마크다운) 하나뿐이다.

### A6. `skills/orch-pipeline` — 크기 분류기 (right-sizing)

> **Ceremony scales to blast radius.**

4티어(trivial / small / standard / large) × 3신호(파일 수 · 새 의존/계약 · 설계 모호성), **최고 티어를 채택하고 한 줄로 선언해 사용자가 뒤집을 수 있게** 한다. 티어별로 도는 phase 가 다르다(trivial 은 4→5→6, large 는 1→2→(3)→4→5→6).

mccp `/mccp:work` 의 trivial 분기는 **2단(trivial/full)** 이다. 4티어 + phase 선택으로 올리면 게이트 체인 비용이 규모에 비례하게 된다.

---

## B. 상류가 뒤진 것 — 가져오면 안 됨

| 항목 | 사실 | 판정 |
|---|---|---|
| `commands/santa-loop.md` | ECC 175행. severity contract · 판정 원장 · patch-chasing terminator · `targets` 필드 **전부 없다**. mccp 1.23.7 이 260행으로 앞섰다 | **되돌리지 말 것.** 상류에 역제안할 자산 |
| receipt / gate chain | ECC 전체에 `gate_id` **0건**, receipt 개념 없음 | mccp 고유 가치. 상류에 없다는 이유로 버리면 안 된다 |
| MCP 커넥터 기본값 | 상류는 기본 커넥터를 6→1(`chrome-devtools`)로 축소, 나머지는 스킬이 CLI/REST 를 감싸는 방식으로 대체 | 참고만. 이 저장소는 playwright 2종을 실제로 쓴다 |

---

## C. 방향성 도전 — **사용자 판단 필요**

상류 규율과 대조했을 때 현재 진행 방향과 **어긋나는** 지점이다. 각각 채택 여부는 사용자 결정.

### C1. 층위를 라운드로 발견하지 말고 **차원으로 펼쳐라** — 가장 큰 지렛대

`11-review-round-remediation.md` 는 8개 결함 층위를 **자가 체크리스트**(리뷰 전 1패스)로 앞당기자고 적었다. 상류 `orch-review` 의 답은 다르다 — **그 8개를 리뷰 차원으로 만들고 병렬 fan-out** 한다.

- 현재: 범용 리뷰어 2명 × N라운드 → 라운드당 층위 1개
- 상류형: 차원 리뷰어 8명 × 1라운드 → 층위 8개 동시

체크리스트는 저자가 자기 것을 보는 것이라 `loop-design-check` 실패 모드 #2(**판사가 피고 자신**)에 걸린다. 차원 fan-out 은 그걸 안 밟는다. **A2 체크리스트를 자가 패스로 쓰지 말고 차원 리뷰어의 렌즈 목록으로 쓰는 편이 낫다.**

> 판단 포인트: mccp 의 santa-loop 을 "2인 합의 × 다라운드" 에서 "N차원 fan-out × 적대적 검증 × 소수 라운드" 로 바꿀 것인가. 이는 `santa-adjudication`·`santa-evidence-diversity` PRD 의 설계 전제를 바꾼다.

### C2. Acceptance 를 **주장이 아니라 대조**로 정의하라

이 저장소는 라운드를 거쳐 매번 같은 곳에 도착했다 — golden 동결 · digest 전체 대조 · 접지 대조 · `stratum_sha256`. **매번 8~11라운드 걸려서 도착했다.** `loop-design-check` 은 그걸 목표 정의 시점의 요구로 못박는다:

> **Prefer reconciliation over assertion.** 자기 단언보다 외부 사실(golden sample / upstream total / 정본 대조)에 먼저 앵커하라.

`CLAUDE.md` §1 의 plan 계약에 한 줄 추가할 값어치가 있다 — *"Acceptance 항목은 가능한 한 자기 단언이 아니라 외부 기준 대조로 쓴다."* 층위 2(주장≠검사)와 7(검사 자신의 주장)이 **정의상** 줄어든다.

### C3. **루프는 인수 담당이 아니다** — santa-loop 의 push 가 red line 이다

상류 red line 원문:

> 인수 / "done" 셀은 **사람이 뒤집는다.** 루프는 작업자지 인수 담당이 아니다.
> 실패를 감당할 수 없는 것(잘못된 PR 머지 / 잘못된 배포)은 권한을 자동으로 넘기지 마라.

mccp `santa-loop.md` Step 6 은 NICE 판정 시 `git push -u origin HEAD` 를 **루프가 직접 한다.** 두 리뷰어가 다 PASS 면 사람 없이 원격에 올라간다.

> 판단 포인트: NICE → push 자동화를 유지할 것인가, NICE → "push 준비 완료" 보고로 내리고 사람이 마지막 스위치를 잡을 것인가. 이 저장소는 이미 실질적으로 후자로 운용해 왔다(캡 도달 시 push 안 함 · 사용자 지시로 라운드 연장). **문서와 실제 운용이 어긋나 있다.**

### C4. 의식(ceremony)을 blast radius 에 맞춰라

`00-protocol-m4` 는 **수치 5종 확정** 마일스톤이고 11라운드를 돌았다. `12-index-runtime-m1-r2` 는 **schedules.yaml 1개 생성**이고 16라운드를 돌았다. 상류 분류기로 재면 둘 다 `standard`~`large` 지만, 라운드 수는 large 를 훨씬 넘는다.

> 판단 포인트: 전 마일스톤에 동일 게이트 체인을 거는 현재 방식 대신, 크기 티어별 phase 선택을 도입할 것인가. 도입하면 `/mccp:work` 의 2단 분기가 4단이 된다.

### C5. **plan 단계 리뷰는 자동 검증이 약하다** — 그래서 라운드가 사람 판단으로 흐른다

`loop-design-check` Step 0 4조건 게이트: ① 주 1회 이상 반복 ② **검증 자동화 가능** ③ 토큰 예산 감당 ④ 에이전트가 실제로 돌려보고 결과를 본다.

- **구현물 리뷰**는 4조건을 통과한다 — `verify.sh`·selftest·golden 이 있다.
- **계획서 리뷰**는 ②가 약하다. 산출물이 문서라 기계 판정 지점이 "게이트 코드가 실제로 도는가" 뿐이고, 그마저 계획서 안의 셸이라 실행 검증이 사람 손이다.

> 상류 문장: *"루프를 받을 자격이 없는 저장소는 오류가 한 겹 증폭될 뿐이다."*
> 판단 포인트: plan 단계 santa-loop 을 유지할 것인가, 아니면 **계획서의 Validation 블록을 실제 스크립트 파일로 먼저 빼고**(=`11-*.md` A5) 그 스크립트에 대해서만 루프를 돌릴 것인가. 후자면 ②가 성립하고 라운드가 기계 판정으로 끝난다.

---

## D. 권장 순서

| # | 항목 | 근거 절 | 비용 | 이 저장소 즉시성 |
|---|---|---|---|---|
| 1 | plan 계약에 `NOT Building` · `EXPECT:` · `GOTCHA` 복원 | A3 | 낮음 | **즉시** — `CLAUDE.md` §1 에 3줄 |
| 2 | Acceptance 를 대조 기반으로 | C2 | 낮음 | **즉시** — 같은 파일 1줄 |
| 3 | 8층 체크리스트를 자가 패스 → 차원 리뷰어 렌즈로 전환 | C1 | 중간 | 다음 마일스톤 |
| 4 | santa NICE → push 를 보고로 강등 | C3 | 낮음 | 문서-운용 정합만 맞추면 됨 |
| 5 | Validation 블록 스크립트 외부화 후 루프 대상 재정의 | C5 | 높음 | 다음 대형 계획 |
| 6 | `orch-review` 6설계 결정을 santa 에 이식 | A1 | 높음 | 상류 PR 소관 |
| 7 | state-store · epic 조정 substrate | A4·A5 | 매우 높음 | 상류 로드맵 |

1·2·4 는 이 저장소에서 오늘 반영 가능하다. 3·5 는 다음 마일스톤 착수 시. 6·7 은 mccp 본체 PRD 축이며 이미 진행 중인 `santa-*` 4종 PRD 와 설계 전제가 충돌할 수 있으므로 **먼저 C1 판단이 필요하다.**

---

## D-2. 상류 이슈 발화 (2026-08-13)

| 이슈 | 내용 | 이 문서의 절 |
|---|---|---|
| [#129](https://github.com/idenn207/mccp/issues/129) | ECC 2.2.0 포크 델타 — `orch-review` 설계 결정 7종(3종은 기존 PRD 미포함) · `loop-design-check` 미포크 · state-store 스키마 · `epic-*` · 크기 분류기 · 상류가 뒤진 3건 | A1·A2·A4·A5·A6·B |
| [#130](https://github.com/idenn207/mccp/issues/130) | santa-loop Step 6 자동 push 가 인수 판정을 루프에 넘긴다. A/B/C 3안 | C3 |
| [#127 코멘트](https://github.com/idenn207/mccp/issues/127#issuecomment-5277885302) | plan 템플릿은 드리프트가 아니라 **상류 대비 회귀** — `NOT Building`·`EXPECT:`·`GOTCHA` 0건, 계약 180행→65행 | A3 |

---

## E. 상류에 역제안할 것

mccp 가 앞선 자산이다. ECC 에 없다.

- santa-loop severity contract · 판정 원장 · patch-chasing terminator (mccp 1.23.7)
- receipt chain + `plan_hash` 앵커 + `gate_id` 체계 (ECC `gate_id` 0건)
- 이 저장소가 축적한 **결함 층위 8종 분류** — `orch-review` 의 차원 목록으로 그대로 쓰인다
