v0.18.0 G05 — 추적 파일 1,934개와 서버 객체가 어느 기능·계층·담당에 속하는지 아무 검사도 묻지 않던 것에서 규칙 파일·검사 도구·생성 장부까지 (2026-09-07)
- 기간: 2026-09-07 ~ 2026-09-07 (세션 1개
87cdb626, 오너 지시 "#1281 진행해줘" → 분석·계획 게시 → "내 결정 묻지 말고, phase 계획 작성후 마지막 phase까지 중단없이 진행") - 랜딩: PR #1307(Phase 1~4 한 PR, squash) — 마이그레이션·엣지 함수·앱 화면 변경 없음(문서·
scripts/architecture/**·테스트 1개). 선행 G01 PR #1296 머지 확인 뒤 착수(main3fdefeb3) - 설계서: 없음 — 분석·Phase 계획은 이슈 #1281 댓글("예상 효과·개선사항" 절 포함)
- 정본:
docs/architecture/v0-18-0-coverage-ledger.md(장부·소유권·통지 절차·인계) · 규칙·데이터scripts/architecture/coverage-inventory.json· 총괄 문서2026-09-07-v0-18-0-architecture-roadmap.md§7 장부·§12 G05 행 - 도구:
node scripts/architecture/check-coverage-inventory.mjs(분류·진입점 대조·장부 감사·문서 동기화,--render·--strict·--json) - 게이트: 새 행동 테스트
tests/react/coverageInventory.test.mjs7건. 도구는npm run check에 넣지 않았다(이슈 지시: R01/R05 종료 검사) — 로컬npm run check전체 통과. 마이그레이션·pgTAP·e2e 미접촉 - 버그리포트: 없음(수리 건 아님)
- 계약: 새 계약 없음. 운영 정본 §3 의 파일명 오기(
appController.jsx→.tsx) 한 곳 정정.package.json은 만지지 않음(HQ 통합 슬롯 — 별칭 추가는 HQ 갱신안)
Phase 현황
| Phase | 내용 | 상태 |
|---|---|---|
| Phase 0 | 조사·기준선(추적 파일 1,934 · 테이블 77 · 함수 372 · cron 7 · Edge 3 · API 4 · 라우트·CSS·native·CI 실측), 계획 게시 | ✅ 이슈 댓글 |
| Phase 1 | 분류 규칙 파일(영역 25·계층 20·규칙 302·제외 9·진입점 등록 25) + 검사 도구 + 행동 테스트 7건 — 미분류 0 | ✅ 0517f06f |
| Phase 2 | 장부 문서 — 샘플 추적(UI→DB→잡 8계층)·판정 뜻·도구 시점·생성 절·보고서 31개/C01–C08/62개 대응·라우트·진입점·cron·기존 검사 재사용 | ✅ 2a2495b1 |
| Phase 3 | 공용 파일·DB object(테이블 77 전부)·CSS scope·native bridge 소유권 표 + 계약 변경 통지 절차 6단계 + G03/D12/D13/R01/R05 인계·HQ 갱신안 | ✅ d7611726 |
| Phase 4 | 이 기록·등록·총괄 G05 행·운영 정본 정정·PR·인계 댓글 | ✅ PR #1307 |
1. 배경
v0.18.0 은 기존 단일 앱을 62개 작업으로 모듈화한다. 총괄 문서가 "무엇을 고칠지" 를 정했지만, "지금 앱에 실제로 있는 것 전부가 담당에 연결됐는지" 를 확인할 방법은 없었다. G03(도메인 계약)은 실제 도메인·공유 계층 목록을, D12/D13 은 DB 전수 범위를, R01/R05 는 "필수 영역에 미배정·미확인이 없다" 는 종료 판정을 이 목록에서 받기로 돼 있었다(총괄 §10·C01). G05 는 그 연결 장부와 누락 검사 도구를 만드는 작업이다.
2. 문제 제기
분류가 사람 머릿속에만 있어서, 새 파일·새 진입점이 담당 없이 들어와도 아무 검사도 묻지 않았다
저장소가 추적하는 파일은 1,934개, 서버에는 테이블 77·함수 372·pg_cron 잡 7·Edge 함수 3·Vercel API 핸들러 4가 있다. 어느 파일이 어느 기능의 어느 계층인지, 그 계층을 62개 중 누가 맡는지는 문서 여러 곳에 흩어져 있거나 없었다. 새 api/ 핸들러나 새 cron 잡이 마이그레이션에 섞여 들어와도 그것을 "담당 없는 진입점" 으로 잡는 검사가 없었다.
문서마다 경로를 옮겨 적어 시점이 달랐다
운영 정본 §3 이 앱 컨트롤러를 appController.jsx 로 적었지만 실제 파일은 .tsx 다. 손으로 베낀 목록은 다음 PR 부터 틀린다.
"이슈에 연결됐다" 와 "품질이 확인됐다" 를 같은 칸에 적어 왔다
R01/R05 가 "미확인 0" 을 세려면 두 가지가 다른 칸에 있어야 한다. 파일이 장부에 있다는 사실만으로 그 코드가 좋다는 결론을 내리면 안 된다(이슈 지시).
3. 해결 방안
원칙 (오너 결정 없음 — 전제로 진행, 2026-09-07)
- 오너 지시: "내 결정 묻지 말고, phase 계획 작성후 마지막 phase까지 중단없이 진행".
- 전제 1: 검사 도구는
node scripts/architecture/check-coverage-inventory.mjs로 직접 실행한다.package.json별칭은 HQ 통합 슬롯 자원(운영 정본 §4-1 ②)이라 이 PR 에서 만지지 않는다.npm run check에도 넣지 않는다 — 이슈가 정한 대로 R01/R05 종료 검사(과 HQ 스테이징 슬롯 점검)에서 돌린다. - 전제 2: 초기 장부의 판정은 G05 가 유지 근거 / 개선 진행 / 해당 없음 만 적고, "검증 완료" 는 구현 담당이 증거와 함께 바꾼다(도구가 증거 없는 "검증 완료" 를 거부).
- 전제 3: 운영 정본 §3 의 통합 담당은 바꾸지 않는다(G01 인계 조건). 파일 단위로 정밀화만 한다.
접근
| 안 | 내용 | 채택 |
|---|---|---|
| A. 규칙 파일 + 검사 도구 + 생성 장부 | 분류 규칙을 JSON 한 파일에 두고, 도구가 git ls-files 전체를 분류해 미분류·미등록 진입점·장부 행 누락·미배정/미확인을 알린다. 장부 표는 같은 데이터에서 생성해 문서에 붙이고 기본 실행이 어긋남을 잡는다(schema.sql 스냅샷과 같은 방식) | 채택 — 목록이 코드와 같이 늙지 않고 R01/R05 가 기계로 센다 |
| B. 마크다운 장부만 손으로 작성 | 표만 만든다 | 불채택 — 다음 PR 부터 틀리고 검사할 수 없다 |
| C. 함수 단위 전수 장부 | 372개 함수·모든 export 를 나열 | 불채택 — 이슈가 금지한 "함수 수준 장부"; 추적에 도움이 안 된다 |
D. npm run check 에 도구를 넣어 모든 PR 을 막기 | 새 경로마다 규칙 한 줄을 강제 | 불채택(보류) — 이슈가 종료 검사로 정했고, 다른 트랙의 PR 을 분류 한 줄로 막는 정책 변경은 HQ 몫. §7-4 갱신안으로 넘김 |
4. 적용한 내용
Phase 1 — 규칙 파일·검사 도구·행동 테스트 (0517f06f)
scripts/architecture/coverage-inventory.json: 영역 25(기능 16 — 운동·계획·홈·달력·PR·볼륨·카탈로그·프로필·소셜·그룹·온보딩·인증·인입·관리자·통계·기기 대기열 / 공유 8 — 앱 셸·공통 UI 기반·네이티브·서비스 워커·빌드/CI·DB 플랫폼·검증 기반·문서 / 범위 밖 1 — 랜딩 페이지), 계층 20, 분류 규칙 302(디렉터리·파일 이름 정규식, 첫 일치가 이김), 근거 있는 제외 9(작업 기록·버그 리포트·보관·번역·legacy patch·일회성 인입 자료·디자인 배송 기록·로컬 도구 설정·CLI 상태), 진입점 등록 25(HTML 2·부팅 2·SW 1·API 4·Edge 3·워크플로 6·cron 7), 영역×계층 장부 행 197.scripts/architecture/check-coverage-inventory.mjs: 분류 → 진입점·cron 실측 대조(api/**의_접두 제외,schema.sql의cron.schedule) → 장부 감사(파일 있는 계층에 행 없음, 필수 영역의 미배정/미확인) → 장부 문서 생성 절--render/기본 대조.--strict가 R01/R05 종료 검사. 형식 검사는 없는 영역·계층, 근거 없는 제외, 증거 없는 "검증 완료" 를 거부.tests/react/coverageInventory.test.mjs: 도구 행동 7건(첫 일치·제외 우선·미분류, 진입점 발견·대조, 장부 감사, 형식 검사, 생성·동기화 왕복, 파이프 이스케이프·행 없음 표시, 실제 규칙 파일 형식).
Phase 2 — 장부 문서 (2a2495b1)
docs/architecture/v0-18-0-coverage-ledger.md§1 읽는 법(유저 A 의 기록 한 건이 지나는 8계층 샘플 추적, 판정의 뜻), §2 도구와 실행 시점 3곳, §3 생성 절(영역 요약·영역별 장부·진입점 대조·근거 있는 제외), §5 보고서 F01~F30+F07b·C01–C08·62개 ID ↔ 영역, §6 라우트(모바일 탭 8·층 8, 데스크톱 탭 10, 관리자 탭 9)·진입점·cron 7·기존 게이트 재사용 11, §8 정정 사항.
Phase 3 — 소유권·통지 절차·인계 (d7611726)
- §4-1 공용 파일 11종(실제 파일명·줄 수), §4-2 DB object(테이블 77 전부를 12묶음에 배정, 대표 함수·잡, 담당 계획 ID), §4-3 CSS scope 7종(token/base/shared/desktop base/mobile screen/desktop screen/문서·법적 — 실리는 경로·소유·검사·새 화면 CSS 규칙), §4-4 native bridge(웹→네이티브 메시지 12종·네이티브→웹 이벤트 4종·Android/iOS/웹 파일·네 곳 동시 변경 규칙), §4-5 계약 변경 통지 절차 6단계(통지 댓글 형식).
- §7 인계: G03 에 도메인 경계 입력과 시간대·정밀도·null/0·provider·bridge 소유자, D12/D13 에 DB 전수 범위, R01/R05 에
--strict종료 조건, HQ 갱신안 3건.
Phase 4 — 기록·등록·총괄·PR (PR #1307)
- 이 기록, 사이드바(아키텍처 + 작업 기록)·
docs/README.md두 표 등록, 총괄 §12 G05 행·Phase 1 집계·§7 장부 행, 운영 정본 §3 파일명 정정, 이슈 #1282(G03)·#1287(D13) 인계 댓글, HQ 이슈 #1279 갱신 통지.
주요 결정과 그 근거
- 디렉터리 단위 규칙 — 같은 디렉터리의 새 파일은 자동 분류되고 새 디렉터리·진입점만 드러난다. 세밀함보다 유지 가능성. 함수 단위 장부는 이슈가 금지.
- 장부 데이터를 규칙 파일 한 곳에 — 문서 표는 생성. 손으로 고친 표가 규칙과 어긋나면 기본 실행이 실패한다.
- "검증 완료" 는 증거 필수 — 도구가 거부한다. 파일 연결이 품질 합격으로 읽히는 것을 구조로 막는다.
- 테스트는 도구의 행동만 — 실제 저장소 전수 분류를 테스트에 넣지 않았다(다른 트랙 PR 을 막지 않기 위해). 대신
--strict를 종료 검사로 둔다.
작업 중 드러난 것
- 접두 정규식 3건이 다른 파일을 삼켰다(
DesktopPr→DesktopProfileScreen,record→recordComposerOwnership,app→appRolePrivilegesContract). 정규식을 좁히거나 순서를 바꿔 고쳤다. 도구의 "쓰이지 않는 규칙" 출력이 이것을 드러냈다. - 운영 정본 §3 의
appController.jsx는 실제.tsx(정정).docs/architecture/domain-service-boundaries.md의 "Next Extraction Steps" 가 말하는domains/*Repository.ts는 아직 없다(A02~A06 목적지).get_volume_overview는 v4·v2 오버로드 병존(제거 R01).test/26·tests/react/338 두 테스트 루트 병존(통합 여부 G02/R01). gh issue comment를 저장소 밖 경로에서 실행하면 실패한다 — 워크트리 안에서 실행.- PR 을 여는 사이 main 에 #1294(반복수 투영)·#1304(랜딩 페이지)가 합류했다. 리베이스 뒤 도구가 새 파일 2개(
reps_projection_stats_v1.test.sql·repsProjectionReadersGate.test.mjs)를 미분류로 잡아 규칙 2줄을 넓혔고, 랜딩 페이지의 새specs/·playwright.config.ts·.gitignore규칙을 더했다 — 도구가 설계대로 "담당 없는 새 파일" 을 첫 실전에서 잡은 사례.
5. 적용 결과
| 항목 | 전 | 후 |
|---|---|---|
| 추적 파일의 영역·계층 연결 | 장부 없음(1,934개 전부 미분류) | 분류 1,608 + 근거 있는 제외 315 + 미분류 0 (main e749fe66 합류 뒤 1,923, G05 산출물 5개 포함 — 이 기록은 작업 기록 제외 규칙에 들어간다) |
| 진입점 등록 대조 | 없음 | HTML 2·부팅 2·SW 1·API 4·Edge 3·워크플로 6·cron 7 = 실측과 일치(미등록 0·사라짐 0) |
| 필수 영역(24)의 미배정·미확인 행 | 셀 수 없음 | 0 (--strict 통과) — 초기 판정 분포: 개선 진행 128 · 유지 근거 64 · 해당 없음 5 |
| 62개 계획 ID 의 영역 연결 | 총괄 §12 표만 | 62/62 (파일을 소유하지 않는 R02~R06 은 검증 기반 영역에) |
| 보고서 31개·C01–C08 의 영역 대응 | 이슈 연결만 | 영역·계층 대응 표 |
| 테이블 77개의 영역 배정 | 없음 | 12묶음 전부 배정(§4-2) |
| 샘플 feature 추적(UI→DB→잡) | — | 8계층 연결 누락 0 |
| 로컬 게이트 | — | npm run check 통과(새 테스트 7건 포함) · check:utf8 통과 |
미검증: 도구를 다른 세션이 실제로 새 경로 PR 에서 돌려 규칙을 추가하는 운영은 아직 한 번도 일어나지 않았다(첫 사례는 G02/G03 PR). 총괄·운영 정본의 HQ 세션(4c81b0f9)과 같은 줄을 동시에 고치지 않았는지는 머지 시 리베이스로 확인.
6. 이번 개선으로 향상된 것
담당 없이 빠지는 파일·진입점을 사람이 아니라 기계가 알린다
새 디렉터리·새 API 핸들러·새 Edge 함수·새 워크플로·새 cron 잡은 규칙 한 줄이 없으면 도구가 "미분류 / 새 미분류 진입점" 으로 이름을 찍어 낸다. R01/R05 는 --strict 한 줄로 종료 조건을 센다.
후속 작업이 같은 목록에서 출발한다
G03 은 도메인 16개와 계층별 port 위치를, D12/D13 은 테이블 77개의 영역 배정을, U01/U07 은 CSS scope 7종의 파일 단위 소유를, N01 은 bridge 메시지 16종의 네 곳 파일을 장부 한 문서에서 받는다. 각자 재조사하지 않는다.
"연결됐다" 와 "확인됐다" 가 다른 칸이다
판정 여섯 값 중 "검증 완료" 만 증거를 요구하고, 초기 장부는 그것을 하나도 쓰지 않았다. 구현 담당이 랜딩 뒤 증거와 함께 바꾼다.
남은 것
- HQ 갱신안 중
package.json별칭check:coverage-inventory는 HQ 통합 슬롯이라 이 PR 이 만지지 않았다(장부 §7-4). - 판정 갱신은 각 계획 ID 담당 몫 — G05 는 목록·도구까지 완료. 앱 전체의 품질 검증 완료는 R05/R06 이 판정한다.
- D03 registry(
supabase/definitions/<domain>/**)가 생기면 장부 §4-2 테이블 배정을 registry 를 가리키도록 갱신한다.