# 변환 하네스 (Conversion Harness) > **이 체크리스트의 모든 항목을 순서대로 통과해야 한다. 건너뛰기 금지.** > 각 항목에서 "확인"이 안 되면 다음으로 넘어가지 않는다. > **2층 구조: 1층(행동 통제) → 2층(구현)**. 1층을 통과하지 않으면 2층 진입 금지. --- # ═══ 1층: 행동 통제 하네스 ═══ ## A. 사용자 요청 해석 - [ ] 사용자가 실제로 말한 문제를 **한 문장으로** 다시 적었는가? - [ ] 내가 하려는 수정이 **그 문제에 직접 대응**하는가? - [ ] 사용자가 말하지 않은 구조 변경을 하려면 **사전 합의**가 필요한가? - [ ] "이것도 같이 바꾸면 좋겠다"는 생각이 들면 → **멈추고 물어본다** ## B. 블록 분류 (patch / rewrite / hold) 작업 시작 전 반드시 분류하고 근거를 3줄로 적는다. ``` 이 블록은 무엇인가? ├── patch — 구조는 살아 있고 특정 부분만 수정하면 됨 │ 근거: ___ ├── rewrite — 구조 자체가 틀어져서 처음부터 다시 해야 함 │ 근거: ___ └── hold — 지금 건드리지 않고 보류 근거: ___ ``` - [ ] 분류 결정함 → `blocks/{id}/classification.md`에 기록 - [ ] 근거 3줄 적음 - [ ] **patch가 아닌 블록에 임의 구조 전환 금지** - [ ] **rewrite 블록은 사용자 확인 후에만 착수** ## C. 변경 범위 제한 - [ ] **이번 수정의 단일 목표**를 한 문장으로 적었는가? - [ ] 이번 수정에서 바꾸는 축은 **1개**인가? - 예: spacing만 / bullet model만 / gradient CSS 변환만 - [ ] 다른 축은 건드리지 않았는가? - [ ] 현재 정상 동작하는 요소를 **변경 금지 목록**으로 적었는가? ``` 변경 대상: ___ 변경하지 않는 것: ___ ``` ## D. 변경 전 기록 - [ ] 수정 전 현재 값/구조 기록 (되돌릴 수 있도록) - [ ] 변경 전 렌더링 스크린샷 baseline 저장 ## E. 중단 조건 아래 상황 발생 시 **즉시 멈추고 사용자에게 보고**: - [ ] 인코딩 깨짐 발견 - [ ] MCP 좌표와 렌더 결과가 크게 다름 (30px+ 이상 차이) - [ ] 패치하려던 블록이 구조 붕괴 상태 - [ ] 한 군데 고치니 다른 곳이 깨짐 (cascade failure) - [ ] 사용자 요청과 다른 방향으로 가고 있음을 인지 → patch 중단 → rewrite required로 분류 전환 → `blocks/{id}/STATUS.md` 남기고 다음 블록으로 ## F. 완료 판정 patch 또는 rewrite가 끝났다고 판단하기 전에: - [ ] 사용자가 지적한 문제가 **실제로 사라졌는가** (렌더링 확인) - [ ] 새로 생긴 **부작용이 없는가** - [ ] baseline 대비 **더 나빠진 요소가 없는가** - [ ] 아래 4개 산출물을 남겼는가: - before screenshot - after screenshot - 변경 요약 3줄 - classification 결과 (patch/rewrite/hold) 위 전부 통과해야 "완료". 하나라도 안 되면 미완료. --- # ═══ 2층: 구현 하네스 ═══ > **1층 A~F를 모두 통과한 후에만 아래 진행** ## 0. 시작 전 — 규칙 파일 읽기 + 행동 원칙 확인 - [ ] RULES.md 읽음 (R1~R19 전부) - [ ] PROCESS-CONTROL.md 읽음 (규칙 1~8) - [ ] PROCESS.md 읽음 (STEP 0~10) - [ ] HARNESS.md 읽음 (이 파일) - [ ] blocks_index.md 읽음 (기존 패턴 확인) ### 행동 원칙 (PROCESS-CONTROL에서, 매 작업 전 상기) - [ ] **소스는 Figma 데이터다** — PNG를 보고 판단하지 않음 (규칙1) - [ ] **이미지 해석 금지** — 멀티모달로 gradient 방향 추측 안 함 (규칙2) - [ ] **작동하는 것은 건드리지 않는다** — A만 문제면 A만 수정 (규칙3) - [ ] **한 번에 하나만 바꾼다** — gradient 각도와 border-radius 동시 변경 금지 (규칙4) - [ ] **사용자가 말한 것만 한다** — 자의적 해석 금지 (규칙5) - [ ] **찍어맞추기 금지** — 값을 바꾸기 전에 WHY를 먼저 설명 (규칙6) - [ ] **쉬운 전면 재작성 금지** — 80점에서 2개 고칠 때 구조를 갈아엎지 않음 (규칙7) - [ ] **MCP 데이터 전수 반영** — "핵심만", "단순화" 금지 (규칙8) --- ## 1. MCP 데이터 수집 - [ ] get_metadata 호출 → 모든 노드 ID, 위치, 크기 확보 - [ ] get_design_context 호출 → gradient, font, style, rotation 확보 - [ ] 에셋 URL 목록 추출 --- ## 2. 에셋 분류 — R9 CSS vs 이미지 판정 (에셋마다 반드시 수행) 각 에셋에 대해: ``` 이 에셋이 뭔가? ├── 단순 사각형 + gradient → CSS linear-gradient + border-radius [R9] ├── 단순 원 + gradient → CSS border-radius:50% + linear-gradient [R9] ├── 단순 직선/점선 → CSS border [R9] ├── 단색 사각형 → CSS background-color [R9] ├── plus-darker blend → multiply로 교체 [R10] └── 복잡 path / 사진 / 아이콘 / 곡선 → 이미지 유지 ``` - [ ] 모든 에셋 분류 완료 - [ ] CSS 대체 가능한 에셋은 다운로드하지 않음 - [ ] 이미지 유지 에셋만 다운로드 --- ## 3. gradient 변환 — R9 CSS 대체 에셋 CSS로 대체하기로 한 에셋마다: - [ ] SVG 파일을 열어 linearGradient 데이터 추출 - [ ] gradient_math.py로 CSS linear-gradient 변환 (인라인 복사 금지) - [ ] viewBox padding이 있으면 R12 remap 적용 - [ ] 변환 결과 기록 --- ## 4. 구조 결정 — R17 레이아웃 타입 ``` 이 블록의 레이아웃은? ├── 순차 행 (비교표, 이슈 목록, 불릿 리스트) │ → flex column (행 간) + flex row (행 내부) [R17] │ → 텍스트 늘면 행이 밀림 │ ├── 표 (행×열 구조) │ → CSS grid [R17] │ → border가 곧 그리드 라인 │ → 셀 높이 auto │ ├── 2D 다이어그램 (원, 노드, 겹침) │ → absolute + 명시 height + zoom [R19] │ → 겹침이 있으므로 flex 불가 │ └── 좌우 분할 (좌:이미지 / 우:목록) → display:flex (좌:flex-none / 우:flex column) ``` - [ ] 레이아웃 타입 결정 - [ ] zoom 적용 (transform:scale 금지) [R19] --- ## 5. HTML 작성 — 요소별 체크 ### 5-A. DOM 순서 - [ ] MCP metadata 순서 = HTML DOM 순서 (나중 요소가 위에 렌더) - [ ] z-index 별도 지정 필요 없음 (DOM 순서로 해결) ### 5-B. 텍스트 요소 - [ ] 본문 텍스트에 position:absolute 사용 안 함 [R17] - [ ] overflow:hidden으로 텍스트 숨기기 안 함 [R17] - [ ] 고정 height로 텍스트 제한 안 함 [R17] - [ ] word-break: keep-all 적용 [R14] - [ ] descender 보정 필요한가? [R1] - line-height / font-size < 1.448 (Noto Sans KR) → padding-bottom 계산 - [ ] gradient 텍스트인가? → background-clip: text [R4] - [ ] 다중 fills인가? → 첫 번째 불투명 fill만 사용 [R5] - [ ] 중복 노드인가? (동일 좌표 + 동일 내용) → 1개만 렌더 [R6] - [ ] 세로 텍스트인가? (width < fontSize × 0.8) → `
` 줄바꿈, writing-mode 사용 금지 [R3] - [ ] vertical center 정렬이 필요한가? → flex justify-center [R15] - [ ] 불필요한 `
` 삽입 안 함 (자연 wrap에 맡김) ### 5-C. 불릿/마커 리스트 [R13] - [ ] `