| name | bdev-untangle |
| description | 바이브코딩으로 만들어진 거대한 단일 파일(수천 줄짜리 HTML·하나의 app.js·거대 React 컴포넌트·단일 app.py 등)을 읽고, **동작은 한 줄도 바꾸지 않은 채** 원래 개발자라면 썼을 관용적 아키텍처로 *분리*하는 스킬. 비개발자가 짠 코드를 유지보수·확장 가능한 구조로 만드는 게 목표 — 나중에 기능을 추가해도 오류가 나지 않도록 모듈 경계를 깨끗하게 가른다. 재작성이 아니라 분해(decompose)다. 트리거 — "이 파일 너무 길어 분리해줘", "단일 html 수천 줄 나눠줘", "코드 구조 정리", "리팩터해서 파일 분리", "원래 개발자처럼 아키텍처 짜줘", "split this monolith", "decompose", "refactor into files", "bdev-untangle". 주의 — 동작 보존이 절대 원칙. 검증 수단(테스트 또는 실행 가능한 앱)이 없으면 진행 전에 경고한다. "개선"은 하지 않는다(구조 분리만). |
bdev-untangle — 거대 단일 파일을 동작 보존하며 분해
철칙 (먼저 읽기 — 이게 이 스킬의 전부)
- 분해지 재작성이 아니다. 코드를 옮기고 연결할 뿐, 다시 쓰지 않는다. 동작은 한 줄도 바뀌면 안 된다. (humanize의 "내용 불변"과 같은 DNA — 여기선 behavior 불변.)
- "온 김에 개선" 금지. 이름 바꾸기·로직 "수정"·엣지케이스 정리·추상화 추가 = 전부 금지. 멀쩡히 돌던 앱을 조용히 깨뜨리는 1순위 원인. 똑똑한 모델일수록 더 손대려 하니 스스로를 묶어라.
- 확장 안전(extension-safe)이 목표. 단순히 파일만 쪼개는 게 아니라, 나중에 기능을 추가해도 안 깨지게 — 모듈 책임 단일·상태 단일 출처·숨은 결합 제거·명확한 공개 인터페이스.
- 검증 없으면 멈춘다. 테스트 또는 실행 가능한 앱(=동작 비교 수단)이 없으면, 진행 전에 사용자에게 "안전망이 없다"고 경고하고 동의를 받는다.
- 계획 먼저, 점진 적용. 큰 변경을 한 번에 쏟지 않는다. 목표 구조를 승인받고, 한 모듈씩 빼며 매 단계 앱이 계속 돌게 한다.
Phase 1 — 스코프 & 안전 준비
- 대상 파일 식별 + 스택 감지(단일 HTML / 바닐라 JS / React 단일 컴포넌트 / Express·Flask 단일 파일 / Next page-dump 등).
- 안전망 확인:
git status로 깨끗한 트리 권고(커밋/스태시). 변경을 git restore 한 방에 되돌릴 수 있어야 한다.
- 검증 수단 확인: 테스트가 있는가? 없으면 앱을 실행해 before 상태를 캡처할 수 있는가? 둘 다 없으면 경고 후 동의.
- 한 줄 출력:
bdev-untangle — {파일} / {스택} / 검증: {tests|smoke|none(경고)}
Phase 2 — 맵핑 (먼저 읽고 지도화)
큰 파일을 읽고 무엇이 무엇인지 지도화한다. 수천 줄이라 한 번에 안 읽히면 섹션별로 나눠 맵핑.
- 관심사 분리 후보: 마크업 / 스타일 / UI 로직 / 상태 / 데이터·API / 설정·상수 / 유틸.
- 위험 신호 기록(동작 보존에 영향): 전역 변수·전역 스코프 의존,
<script> 로드 순서 의존, 이벤트 리스너 등록 시점, 호이스팅·this 바인딩, CSS 특이도(specificity) 의존, 즉시실행 부작용(IIFE/top-level side effect).
- 중복 로직 위치(나중 확장 안전성에 영향).
Phase 3 — 목표 구조 제안 (plan-first, 승인 필수)
references/decomposition-recipes.md의 해당 스택 관용 구조를 따라 목표 파일 트리를 표로 제시한다. 기존 스택을 벗어나지 않는다 — 바닐라 HTML을 React로 바꾸지 않는다(그건 재작성=동작 위험).
표에 담을 것: 새 파일 / 무엇이 들어가는지 / 어디서 옮겨오는지 / 확장 지점(새 기능이 붙을 seam). 승인받고 진행.
Phase 4 — 점진 추출 (옮기되 다시 쓰지 않는다)
한 모듈씩 추출하며 매 단계 앱이 돌게 한다.
- 코드를 옮긴다 — 복붙 후 import/export로 연결. 로직 변형 금지.
- 로드 순서·전역 부작용 보존: 모듈로 빼면 스코프가 바뀌므로, 전역 의존은 명시적 import/export 또는 단일 진입점에서 원래 실행 순서대로 재구성.
- 마크업↔스타일↔스크립트 연결(클래스명·id·셀렉터·이벤트 바인딩)이 끊기지 않게.
- 매 추출 후 빠른 동작 확인(앱이 여전히 켜지는지).
Phase 5 — 검증 (수호자 패스, 동작 불변 증명)
references/verification.md를 따른다.
- 테스트 있으면: 실행 → 전부 통과해야 함.
- 테스트 없으면 스모크 diff: before/after 같은 출력인지 — 같은 DOM·같은 console·같은 네트워크 호출·같은 화면. UI면 앱 띄워서 주요 플로우 클릭.
- 깨짐 신호 점검: 콘솔 에러, undefined 참조, 끊긴 이벤트, 사라진 스타일, 로드 순서 깨짐.
- 다르면 그 추출을 롤백하고 원인 교정.
Phase 6 — 확장 안전성 리포트
마지막에 **"이제 확장해도 안 깨지는 이유"**를 요약한다.
- 각 모듈의 단일 책임 한 줄 설명.
- 새 기능이 붙는 지점(seam) 명시 — "버튼 추가는 여기, API는 여기, 상태는 여기".
- 남은 결합·전역 상태 정직하게 플래그(완전히 못 푼 부분은 숨기지 말 것).
references/verification.md의 확장 안전 체크리스트(상태 단일 출처·순환 의존 없음·모듈별 공개 인터페이스·중복 로직 제거) 통과 여부.
안전장치
① 계획 먼저·승인 후 적용 ② 코드는 옮길 뿐 재작성 X·"개선" X ③ 매 모듈 후 검증, 깨지면 롤백 ④ 검증 수단 없으면 경고·동의 ⑤ 배포·커밋은 사용자(스킬은 분리·검증까지).
비-목표
- 재작성·리디자인·기능 추가·성능 최적화 — 하지 않는다(받은 건 "분리"). 개선 제안은 별도로 메모만.
- 스택 전환(HTML→React 등) — 그건 다른 작업. 요청 시 명확히 "재작성"임을 알리고 분리하지 않는다.
- 테스트 작성 — 검증을 돕되, 테스트 스위트 구축은 별도 작업.