---
task_id: insuro-design-system
type: context
scope: system
created: 2026-05-03
updated: 2026-05-03
status: in-progress
---

# 맥락 노트: InsuRo Design System 평가 레이어

**system**: IDS Phase 1 재작업 평가 시스템
**related**: task-2421

---

## 결정 근거

### 결정 1 — BQ+PQ 인간 3자 평가 폐기, 단일 자동 평가 채택
- **결정 이유**: 회장 명시 "더 가볍게 + 더 정확하게 + 더 퀄리티 높게". 인간 3자 평가는 (a) 사이클 누적으로 ≥3시간, (b) 평가자 주관 편차, (c) silent pass 발생 가능 (task-2389/2401). 코드 수치 평가는 결정론적·재현 가능·즉시 실행.
- **대안과 기각**: BQ+PQ 유지(인간 평가) → 회장 "더 가볍게" 위배. AI(LLM) 자동 평가 → 비결정론·환각·silent pass 위험.

### 결정 2 — dq-rules.json 단일 소스 직접 import (수정 X, 참조만)
- **결정 이유**: 회장 모듈화 정신 (`feedback_modularity_mindset.md`) — DRY, 단일 소스. quality_evaluator.py가 dq-rules.json을 런타임 import → 규칙 변경 시 평가 함수 자동 반영.
- **대안과 기각**: 평가 함수 내 하드코딩 → dq-rules.json과 분기 가능, 규칙 진실 분산 위험.

### 결정 3 — retry_loop.py = max 5 retry, 매 회 다른 시드/패턴 hint
- **결정 이유**: 회장 "더 퀄리티 높게" + silent corruption 영구 차단. 1회 FAIL 시 단순 reject가 아니라 retry_hints 반환 → satori 재호출 시 (다른 random seed, 패턴별 강제 분화 hint, 색 강제 hint) 적용. 5회 FAIL 시 명시 ERROR + 회장 알림 (silent pass 절대 금지).
- **대안과 기각**: 무한 retry → 비용·시간 폭발. 1회 retry → 5 패턴 분화 보장 부족.

### 결정 4 — silent corruption 검출 = 픽셀 분포 분석 + 패턴별 특징 함수
- **결정 이유**: task-2389/2401 회귀 분석 — "단조 그라데이션+박스+텍스트 1종 패턴". 검출 방법:
  1. **픽셀 분포 분석**: 이미지 RGB 히스토그램 → 색상 분산(variance) 측정. 단조 그라데이션은 색상 분포가 좁음 (variance < threshold). photo_card는 분포 넓음.
  2. **패턴별 특징 함수**: photo_card = 사진 영역 비율 ≥ 30% (Sobel edge density), illustration = 색상 다양성 score ≥ N (unique colors > N), gpt_style = 비정형 형태 검출, gradient = 그라디언트 부드러움 score, user_photo = 자연 사진 패턴.
- **대안과 기각**: AI 비전 모델 평가 → 비결정론. 단순 pixel hash 비교 → 정상 변형 못 잡음.

### 결정 5 — Lab 색공간 ΔE < 30 (design-md 브랜드 색 매칭)
- **결정 이유**: RGB 거리는 인지적 색차 반영 X. CIELAB ΔE는 인지 균등 색공간. ΔE 30 = "분명히 다름" 임계 (CIE 기준 30~50 = 명확한 차이). supabase 청록(#3ECF8E) ↔ 회색(#808080) ΔE > 50으로 명확 검출 가능.
- **대안과 기각**: RGB 유클리드 거리 → 시각적 색차 부정확. 색상 hue 각도만 → 채도/명도 차이 못 잡음.

### 결정 6 — OCR confidence 70% 임계
- **결정 이유**: pytesseract `--lang=kor` 한글 OCR 신뢰도. 70% 미만은 폰트 fallback 의심. task-2389 한글 깨짐(□□□) 회귀 차단.
- **대안과 기각**: 80%+ → 정상 폰트도 false positive 가능. 60%- → silent pass 위험.

## 참조 자료

- 회장 명시: 작업 task-2421 본문 (Phase 1 재작업 + 평가 시스템)
- 단일 소스: `memory/specs/dq-rules.json` (font_sizes/font_weights/font_pairing/color/dq_scoring)
- 영감 (그대로 적용 X): `memory/specs/image-workflow-v2.5-final.md` (BQ/PQ 평가 사이클)
- 노하우: `memory/specs/design-qc-knowhow.md` (DQ 10항목 성공/실패 패턴)
- 5 hybrid 패턴: `skills/hybrid-image/patterns/{h1_photo_card,h2_illustration_card,h3_gpt_style_card,h4_gradient_card,h5_user_photo_card}.py`
- 132 브랜드: `resources/design-md/INDEX.md`
- 회장 메모리: `feedback_modularity_mindset.md`, `feedback_no_dead_code_skills.md`, `feedback_cardnews_dq_mandatory.md`, `feedback_verification_scenarios.md`

## 주의사항

- **`dq-rules.json` 절대 수정 금지** — 단일 소스 보호. 평가 함수는 import만.
- **`resources/design-md/**` 절대 수정 금지** — 132 브랜드 라이브러리 무수정.
- **`skills/hybrid-image/**` 절대 수정 금지** — 5 패턴 정의 무수정. 평가 함수는 패턴 출력 PNG만 분석.
- **silent pass 영구 차단** — 5회 retry 후에도 FAIL 시 명시 ERROR 발생. `pass_with_warning` 같은 우회 절대 금지.
- **외부 API 호출 0** — pytesseract(로컬), Pillow(로컬), colormath(로컬)만. 회장 메모리 LLM 모델 우선.
- **회장 승인 게이트 (Phase 0 → Phase 1 진입)** — 코드 작성 후 회장 검토 필요. 자동 진행 보류.
- **회장 승인 게이트 (Phase 3)** — 25장 중 임의 5장 + supabase H4 + financial_h4 회장 직접 시각 confirm.
- **회귀 0** — 다른 IDS Phase 영역 무수정 (forbidden_paths 28개 항목).

## 로키 G2 적대적 평가 결과 + 대응 (Phase 1.5)

**1차 로키 적대적 평가 (2026-05-03)**: FAIL — 9개 우회 시도 중 3건 성공 (CRITICAL 1, HIGH 1, MEDIUM 1, LOW 1)

| # | 심각도 | 약점 (smoking gun) | 대응 (Phase 1.5 보완) | 검증 결과 |
|---|---|---|---|---|
| 1 | CRITICAL | TV-static 노이즈 + OCR 텍스트 PNG가 5/5 검증 100점 통과. visual_diversity가 std/unique colors만 보고 spatial coherence 미검증 | `check_visual_diversity`에 `spatial_diff` (인접 픽셀 차이 평균) 추가. `SPATIAL_COHERENCE_DIFF_MAX = 25.0` 초과 시 FAIL | 실측: smoking_gun spatial_diff=40.00 > 25.0 → passed=False (차단 확인) |
| 2 | HIGH | check_font_size OCR 예외 시 silent pass (passed=True, score=15) — check_ocr_confidence와 정책 비일관 | OCR 예외 경로를 BLOCKED 통일 (passed=True+blocked=True+score=0+reason="BLOCKED: OCR 실행 오류") | check_ocr_confidence와 정책 일관, evaluate_image가 blocked_reasons 별도 카운트 |
| 3 | MEDIUM | brand_color_match 면적 비율 미검증 — 1% 영역만으로도 PASS | `BRAND_AREA_RATIO_MIN = 0.10` 추가, `matching_area_ratio` 계산 + 검증 (delta_e_ok AND area_ok 모두 PASS 요구) | 99% 회색 + 1% 청록 PNG → matching_area_ratio < 0.10 → FAIL (차단 확인) |
| 4 | LOW | OCR 한글 비율 미검증 — 영문/숫자만으로도 PASS | `OCR_KOREAN_RATIO_MIN = 0.5` 추가, 한글 유니코드 비율 계산 + 검증 | 영문 only PNG → korean_ratio=0% → FAIL |

**Phase 1.5 단위 테스트** (카구야 추가): 4 시나리오 (G-15 ~ G-18) — 18 전체 PASS 14 / SKIP 4 / FAIL 0

## Codex 사전 검증 결과 + 대응

**1차 Codex 검증 (2026-05-03 18:33)**: FAIL — critical 1, high 3, medium 2

| # | 심각도 | 지적 | 대응 |
|---|---|---|---|
| 1 | critical | OCR ≥ 70% 핵심 게이트인데 tesseract 미설치 환경 → 두 극단(전부 FAIL or silent pass) 위험 | `check_font_size`/`check_ocr_confidence`에서 미설치 시 `passed=True` + **`blocked=True` + `score=0` + `reason="BLOCKED: pytesseract 미설치"`** 명시. `evaluate_image`는 `blocked_reasons`를 별도 카운트하여 fail_reasons에 명시 추가 → silent pass 영구 차단. |
| 2 | high | retry-until-pass의 seed/hint 소비 함수가 _satori.py / render_one.py에 없음 → 같은 이미지 5회 반복 위험 | `_render_with_seed`를 명시 NotImplementedError placeholder로 유지 + retry_loop.py 모듈 docstring에 Phase 2 통합 의존성(소비해야 할 6개 입력 축) 명시. Phase 2 머지 전 활성화 불가 명문화. |
| 3 | high | 평가 기준은 design-md, 생성은 render_one.py의 하드코딩 BRAND_PALETTES → 자기모순 | Phase 2에서 render_one.py가 design_md_loader.py 사용하도록 통합 명시 (본 task 범위 밖, 계획서 Phase 2 의존성으로 기록). |
| 4 | high | 패턴 분화 임계값 N 미정의 → false positive/negative | `PATTERN_THRESHOLDS` 모듈 상수로 5 패턴별 임계 명시 (`h1_photo_card.edge_density_min=0.05`, `h2.unique_colors_min=5000`, `h3.edge_density_min/max=0.03/0.08` 등). |
| 5 | medium | dq-rules.json 스키마 계약 미문서화 | `_DQ_RULES_REQUIRED_KEYS` 명시 + `_validate_dq_rules_schema()` 추가. 스키마 위반 시 즉시 RuntimeError 발생 (silent fallback 금지). |
| 6 | medium | affected_files 누락 — verify_korean.py 역할 중복 위험 | quality_evaluator.py = 시각/패턴/색상 + OCR 통합 평가, verify_korean.py = 한글 OCR 단독 검증 (기존 satori 빌드 단계 잔존). 역할 분리 명시: quality_evaluator는 최종 통합 게이트, verify_korean은 satori 렌더링 직후 빠른 한글 검증. Phase 2에서 verify_korean을 quality_evaluator.check_ocr_confidence로 통합 흡수 검토. |

## 3 Step Why 자문

- **1st Why — 왜 이 평가 시스템이 필요?**
  - A: task-2389(한글 깨짐)와 task-2401(단조 그라데이션) 두 차례 silent corruption 발생. pytest "OCR 100% PASS" = 시각 다양성 0 검출 못함. 코드 수치 검증으로 영구 차단.
- **2nd Why — 왜 BQ+PQ 인간 평가 안 쓰고 단일 자동?** (Codex 사전 리뷰 질문 포함)
  - B: 인간 평가는 사이클 누적 + 주관 편차 + silent pass 위험. 회장 명시 "더 가볍게 + 더 정확하게". 코드 평가는 결정론적·재현 가능·픽셀 단위 정확.
  - **대안 검토**: (1) BQ+PQ 유지 → 회장 "더 가볍게" 위배. (2) LLM 비전 평가 → 비결정론·환각. (3) 코드 수치 평가 → 회장 3 원칙 모두 충족 ✓
- **3rd Why — 왜 retry-until-pass가 다른 대안보다 나은가?**
  - C: 단순 reject(1회 FAIL → 작업 중단)는 회장 "더 퀄리티 높게" 위배. retry-until-pass(max 5)는 (a) FAIL 시 자동 재생성, (b) retry_hints로 패턴별 분화 강제, (c) 5회 FAIL 시 명시 ERROR로 silent pass 차단. 비용 폭발 방지(상한 5).
- **A-B-C 일관성 검증**: A(silent corruption 영구 차단) ↔ B(결정론적 코드 평가) ↔ C(retry 자동화로 5 패턴 분화 강제) — 모두 silent pass 방지·5 패턴 분화·회장 3원칙으로 일관 ✓
