# task-2994 — InsuRo UI 전수 점검 (진단 전용 · 코드 변경 0줄)

- 팀: dev5-team (마르둑) · 레벨: Lv.2 (진단) · 작성 2026-08-21
- 대상: `/home/jay/projects/InsuRo` (읽기 전용) · 프로덕션 `https://insuro.biz`
- 점검 라우트: **58개** (사이드바 노출 47 + sidebarOnly 1 + 미표시 10)
- 코드 변경: **0줄** (git status 무변경, PR 없음)

---

## S (상황)
엔진 완성도만 보고되어 왔고 화면은 점검된 적이 없다. 회장님이 직접 메뉴를 눌러보다 5건을 발견했다.

## C (복잡성)
전수 점검 결과, 개별 화면 결함보다 **상위의 구조적 원인**이 먼저 나왔다.
**네비게이션 정의가 두 벌 존재하고, 그중 한 벌이 죽어 있다.**

| | `src/config/routes.ts` | `src/components/navigation/navigationConfig.ts` |
|---|---|---|
| 렌더러 | `src/components/AppSidebar.tsx` | `DashboardLayout` → `TopNavBar`/`ContextSubMenu`/`MobileBottomNav` |
| 실사용 | **죽음** | **라이브** |
| 섹션 | 9개 (`분석&도구`·`유용한도구`·`보험 시장분석 AI` 분리) | 4탭 (`고객관리`/`분석 & 도구`/`AI 마케팅`/`안내 & 설정`) |

`AppSidebar` 는 `src/components/AppSidebar.tsx:63` 에서 정의될 뿐 **src 전체에서 단 한 번도 import 되지 않는다** (`grep -rn "AppSidebar" src/` → 자기 정의 1건). 따라서 `routes.ts` 의 `section`·`menuSections`·`sidebarOnlyItems` 는 **화면에 전혀 반영되지 않는 죽은 메타데이터**다. 라우팅에만 쓰인다(`src/App.tsx:10`).

**→ 회장님 발견 #1·#4 의 "분류"는 이 죽은 메타데이터를 근거로 판단된 것이다. 실제 프로덕션에서는 문제의 성격이 다르다(아래 §3).**

## Q (질문)
무엇부터 고쳐야 하는가?

## A (답변)
**단일 소스 확정(navigationConfig 일원화)이 1순위다.** 개별 화면 문구를 고쳐도 정의가 두 벌인 한 드리프트는 재발한다. 상세는 §4.

---

## 0. 판정 방식과 그 한계 (먼저 밝힘)

| 방식 | 적용 범위 | 근거 |
|---|---|---|
| **실브라우저(프로덕션)** | 58 라우트 전체의 **접근성/리다이렉트 거동** | Playwright 실행. 아래 §0.1 |
| **프로덕션 번들 실측** | **라이브 메뉴 구성 확정** | `https://insuro.biz/assets/DashboardLayout-HZzbI6Sn.js` 다운로드 후 파싱 |
| **소스 정적 분석** | 화면 내부 문구·로직·API 대조 | `src/pages/*.tsx`, `src/config/routes.ts` |

**한계 — 화면 내부는 실브라우저로 보지 못했다.** 테스트 계정 자격증명이 저장돼 있지 않고(`grep TEST_USER/E2E_EMAIL` → 0건), 회장님 세션은 사용할 수 없다. 로그인이 필요한 55개 화면은 **로그인월까지만 실제로 열어봤고**, 내부 판정은 소스 기준이다. 화면별로 §1 표의 `판정방식` 열에 명시했다.

### 0.1 실브라우저 실측 결과 (프로덕션, 비로그인)

| 경로 | 최종 URL | 관찰 |
|---|---|---|
| `/privacy` | `/privacy` | **정상 렌더** (공개). 스크린샷 검증 완료 |
| `/namecard/does-not-exist` | 동일 | **정상 렌더** — "프로필을 찾을 수 없습니다" |
| 나머지 55개(`/`·`/intro`·`/admin/*`·`/zzz-nonexistent` 포함) | **`/login`** | 전부 클라이언트 리다이렉트 |

- 스크린샷: `/home/jay/workspace/teams/dev5/.playwright-mcp/task-2994-privacy-public.png` (공개 페이지 정상), `task-2994-loginwall.png` (**로그인월 — 기능 화면 아님**)
- `*`(NotFound) 는 비로그인 시 404 대신 `/login` 으로 흡수되어 **도달 불가**.
- 점검 중 탭 크래시가 1회 발생했으나 **20회+ 연속 내비게이션에 의한 탭 메모리 고갈**이었다. 신규 탭에서 동일 경로 재현 시 정상 → **앱 결함 아님**으로 판정(오탐 배제).

---

## 1. 전 라우트 점검표

판정: PASS / **FAIL** / 주의 · 근거는 §2 문제번호로 연결.

### 1-1. 고객관리 (5+1)
| 경로 | 제목(routes / 라이브nav / 페이지h1) | 기준1 섹션 | 기준2 용어 | 기준3 실사용 | 기준4 설명 | 판정방식 |
|---|---|---|---|---|---|---|
| /crm/dashboard | 대시보드 / 대시보드 / 고객관리 대시보드 | PASS | 주의 A-11 | **FAIL** A-3 | **FAIL** A-3 | 소스 |
| /crm/customers | 고객 목록 / 고객 목록 / 고객 목록 | PASS | **FAIL** A-12 | 주의 | 주의 A-19 | 소스 |
| /crm/pipeline | 파이프라인 / 파이프라인 / 파이프라인 | PASS | PASS | PASS | 주의 | 소스 |
| /crm/policy-analysis | 고객 증권분석 (3자 동일) | 확정#5 | PASS | 확정#5 | 확정#5 | 소스 |
| /crm/messenger | 메신저 / 메신저 / (h1 없음) | PASS | 주의 A-14 | **FAIL** A-4 | **FAIL** A-4 | 소스 |
| 디지털 명함 → /mypage#namecard | (sidebarOnly) | **FAIL** A-9 | — | 주의 | 주의 | 소스 |

### 1-2. 분석 & 도구 — 라이브 13항목 (+메뉴에 없는 2)
| 경로 | 제목 | 기준1 섹션 | 기준2 용어 | 기준3 실사용 | 기준4 설명 | 판정방식 |
|---|---|---|---|---|---|---|
| /market/newsletter | 매월 소식지분석 AI / 소식지분석 / 소식지 AI 분석 | 주의 | **FAIL** A-13 | PASS | PASS | 소스 |
| /market/premium-compare | 보험료/환급률 분석 AI | 주의 | 주의 | **FAIL** A-5 | **FAIL** A-20 | 소스 |
| /tools/insuwiki | 인슈위키(InsuWiki) | **FAIL** A-8 | 주의 | **FAIL** A-6 | **FAIL** A-21 | 소스 |
| /tools/mediscan | 메디스캔 | 주의 | 주의 | 주의 | **FAIL** A-7 | 소스 |
| /tools/pdf-editor | PDF 편집기 / (제목 없음) | PASS | 주의 A-15 | **FAIL** A-2 | 주의 A-22 | 소스 |
| /tools/image-editor | 이미지 편집기 / (제목 없음) | 주의 | **FAIL** A-15 | PASS | 주의 | 소스 |
| **/tools/policy-terms-upload** | 약관 업로드 | **FAIL 확정#4** | 주의 | PASS | **FAIL 확정#5** | 번들+소스 |
| /tools/insurance-portal | 보험사 전산정보 / / 보험사 전산 포털 | PASS | **FAIL** A-13 | 주의 | **FAIL** A-23 | 소스 |
| /tools/calculators | 각종 계산기 | 주의 A-10 | **FAIL** A-16 | PASS | 주의 A-24 | 소스 |
| /tools/external-sites | 외부 참고 사이트 | PASS | PASS | PASS | PASS | 소스 |
| /keyword-analysis?tab=info-keyword | 정보성 키워드 분석 | **FAIL** A-10 | 주의 A-17 | 주의 | **FAIL** A-25 | 소스 |
| /composite-design | 복합설계 계산기 / / 복합설계 AI 계산기 | 주의 A-10 | **FAIL** A-17 | 주의 | **FAIL** A-26 | 소스 |
| /composite-design/setup | Helper 확장 설치 | 주의 A-10 | 주의 A-17 | PASS | 주의 A-26 | 소스 |
| **/tools/silson-calculator** | 실손계산기 | **FAIL A-1** | PASS | **도달불가** | — | **번들 실측** |
| **/new-design-comparison** | 신규설계 비교 | **FAIL A-1 / 확정#1** | **FAIL 확정#2** | **FAIL 확정#3** | 주의 | **번들 실측** |

### 1-3. AI 마케팅 (라이브 5 / routes 6)
| 경로 | 제목 | 기준1 | 기준2 | 기준3 | 기준4 | 판정방식 |
|---|---|---|---|---|---|---|
| /keyword-analysis | AI 키워드 분석 | 주의 A-10 | PASS | **FAIL** A-5 | 주의 | 소스 |
| /generate | AI 콘텐츠 작성 | PASS | 주의 | **FAIL** A-18 | **FAIL** A-27 | 소스 |
| /contents | 콘텐츠 관리 | **FAIL** A-10 | 주의 | PASS | 주의 | 소스 |
| /ai-onestop (premiumOnly) | AI 원스탑 포스팅 | 주의 | **FAIL** A-16 | **FAIL** A-4 | **FAIL** A-28 | 소스 |
| /ai-automation (premiumOnly) | AI 포스팅 자동화 | 주의 | **FAIL** A-16 | **FAIL** A-2 | **FAIL** A-28 | 소스 |
| **/content-calendar** | 콘텐츠 캘린더 | **FAIL A-1** | PASS | **도달불가** | 주의 | 소스 |

### 1-4. 안내 & 설정 (8)
| 경로 | 제목 | 기준1 | 기준2 | 기준3 | 기준4 | 판정방식 |
|---|---|---|---|---|---|---|
| /intro | 인슈로 소개 | PASS | 주의 | PASS | **FAIL** A-29 | 소스 |
| /guide | 이용방법 및 가이드 / 이용방법/가이드 / 인슈로 서비스 이용가이드 | PASS | **FAIL** A-13 | PASS | 주의 A-30 | 소스 |
| /api-key | API 키 발급 가이드 / API키 / SNS 연동 가이드 | **FAIL** A-10 | **FAIL** A-13 | **FAIL** A-6 | 주의 | 소스 |
| /fcpa | 금융소비자보호법 / 금소법 / 금융소비자보호법 가이드 | PASS | 주의 A-13 | PASS | PASS | 소스 |
| /notices | 공지/커뮤니티 | PASS | PASS | PASS | PASS | 소스 |
| /mypage | 마이페이지 / / (h1 없음) | PASS | 주의 A-14 | **FAIL** A-9 | **FAIL** A-31 | 소스 |
| /settings | 개인 설정 / / 내 설정 | PASS | **FAIL** A-13 | **FAIL** A-9 | 주의 | 소스 |
| /pricing | 플랜 & 구독 | PASS | **FAIL** A-16 | **FAIL A-2** | **FAIL** A-32 | 소스 |

### 1-5. 관리자 (13)
`adminOnly` 라우트 가드는 **존재하지 않는다**(A-33). 아래 기준1은 전부 그 전제 위의 판정이다.

| 경로 | 제목 / 화면h1 | 기준1 | 기준2 | 기준3 | 기준4 | 판정방식 |
|---|---|---|---|---|---|---|
| /admin/notices | 공지사항 관리 | 주의 A-33 | PASS | PASS | PASS | 소스 |
| /admin/fcpa | 금소법 관리 (관리자) | 주의 A-33 | 주의 A-35 | 주의 | **FAIL** A-37 | 소스 |
| /admin/organizations | 조직 관리 / 조직 & 구독 관리 | 주의 A-33 | **FAIL** A-34 | PASS | PASS | 소스 |
| /admin/subscriptions | 구독 플랜 관리 | 주의 A-33 | PASS | **FAIL** A-2 | PASS | 소스 |
| /admin/ai-config | AI 엔진 설정 | **보안** A-40 | PASS | 주의 | PASS | 소스+마이그레이션 |
| /admin/image-feedback | 이미지 피드백 / 이미지 재생성 피드백 | 주의 A-33 | 주의 A-34 | PASS | PASS | 소스 |
| /admin/roadmap | 개발 로드맵 / 향후 개발 로드맵 | 주의 A-33 | 주의 A-34 | PASS | PASS | 소스 |
| /admin/crm | CRM 관리 | **FAIL** A-5 | PASS | **FAIL** A-6 | **FAIL** A-38 | 소스 |
| /admin/newsletters | 소식지 관리 | 주의 A-33 | PASS | PASS | PASS | 소스 |
| /admin/premium-data | 보험료 데이터 / 보험료 데이터 관리 | 주의 A-33 | 주의 A-34 | PASS | PASS | 소스 |
| /admin/guide | 이용 가이드 관리 | 주의 A-33 | PASS | 주의 A-2 | PASS | 소스 |
| /admin/analytics | KPI 대시보드 / 핵심 KPI 대시보드 | **FAIL A-1** | 주의 A-34 | 주의 | PASS | 소스 |
| /admin/infokeyword | 인포키워드 관리 | 주의 A-33 | PASS | PASS | PASS | 소스 |

### 1-6. 사이드바 미표시 (10)
| 경로 | 제목 | 기준1 | 기준2 | 기준3 | 기준4 | 판정방식 |
|---|---|---|---|---|---|---|
| /login | 로그인 | PASS 공개 | 주의 | PASS | PASS | **실브라우저** |
| /privacy | 개인정보처리방침 | PASS 공개 | PASS | PASS | PASS | **실브라우저** |
| /reset-password | 비밀번호 재설정 | PASS 공개 | PASS | PASS | PASS | **실브라우저**+소스 |
| /chat/:token | 고객 채팅 | PASS 공개(설계상) | 주의 | PASS | PASS | 소스 |
| /namecard/:agentId | 디지털 명함 | **보안** A-39 | 주의 | PASS | 주의 | **실브라우저**+소스 |
| /crm/customers/:id | 고객 상세 | PASS 인증필요 | 주의 | PASS | PASS | 소스 |
| /crm/messenger/:conversationId | 메신저 | PASS 인증필요 | PASS | PASS | PASS | 소스 |
| **/analytics** | 분석 (화면은 "콘텐츠 관리") | **FAIL A-1** | **FAIL** A-36 | PASS | **FAIL** A-36 | 소스 |
| **/onboarding** | 온보딩 | **FAIL A-1** | 주의 | PASS | 미확인 | 소스 |
| `*` | 페이지 없음 / `404 Oops! Page not found` | 주의 | **FAIL** A-41 | PASS | — | **실브라우저**+소스 |

---

## 2. 문제 목록 (심각도순)

심각도: **① 설계사가 쓸 수 없음 > ② 분류 오류 > ③ 용어 불일치 > ④ 설명 부정확**

### ① 설계사가 쓸 수 없음

**A-1. 라우트는 있는데 메뉴에 없는 화면 5개 — URL 직접 입력 외 진입 경로 0**
프로덕션 번들 실측(권위 근거). `assets/DashboardLayout-HZzbI6Sn.js` 의 `analytics-tools.items` 는 **13개이고 아래 두 항목이 없다**:
```
{title:"약관 업로드",url:"/tools/policy-terms-upload"}   ← 있음
... 마지막 항목: {title:"Helper 확장 설치",url:"/composite-design/setup"}
```
`grep -o "신규설계 비교" DashboardLayout*.js | wc -l` → **0** · `실손계산기` → **0** (같은 파일에서 `약관 업로드` → 1).
- **`/new-design-comparison`(신규설계 비교)** — `src/config/routes.ts:331` 에 `section:"분석&도구"` 로 등록돼 있으나 라이브 메뉴 부재
- **`/tools/silson-calculator`(실손계산기)** — `routes.ts:324` 동일
- **`/content-calendar`(콘텐츠 캘린더)** — `routes.ts:242`, 링크 0건. `Contents.tsx:45-47` 의 캘린더 탭과 내용 중복(둘 다 `ContentCalendarTab` 렌더)
- **`/admin/analytics`(KPI 대시보드)** — `routes.ts:505`. 라이브 관리자 메뉴는 `navigationConfig.ts:130-143` 하드코딩 12개이고 여기 없음
- **`/onboarding`** — `routes.ts:552`, 앱 내 이동 코드 0건

> **회장님 발견 #1 의 실제 상태는 "분류가 틀렸다"가 아니라 "메뉴에 아예 없다"이다.** 메모리에 남은 "스크롤하면 보일 것"이라는 추정은 **번들 실측 결과 사실이 아니다**. 화면 밖이 아니라 목록에 미등록.
- 조치: `navigationConfig.ts` `analytics-tools.items` 에 2건 추가(신규설계 비교는 §4대로 **고객관리**로). 관리자 메뉴는 `routes.filter(r=>r.adminOnly)` 파생으로 단일화. 규모 **작음**

**A-2. 눌러도 아무 일도 일어나지 않는 버튼 4곳**
- **`/pricing` 결제 CTA에 `onClick` 자체가 없다** — `src/pages/Pricing.tsx:235-245` `<Button className={cn(...)} variant={isProPlan?"default":"outline"}>{plan.name} 시작하기</Button>`. 핸들러 prop 0개(직접 확인). `AiOnestop.tsx:293-300`·`UpgradeModal.tsx:97` 의 업그레이드 동선이 전부 이 죽은 버튼으로 수렴한다 → **유료 전환 경로 전체가 막혀 있다**
- `/admin/guide` 내부 경로 수기입력 — `AdminGuide.tsx:406` `placeholder="예: /generate"`, 오타 검증 없음
- `/admin/subscriptions` 기능 기본값 JSON 수기 — `AdminSubscriptions.tsx:1176` + `:302-307` **JSON.parse 실패를 조용히 문자열로 저장**. `False` 입력 시 truthy `"False"` 가 DB에 들어가 기능 게이트가 **반대로 열린다**
- `/tools/pdf-editor` 합치기·나누기·저장·주석 실패가 **console 로만** 처리 — `PdfEditor.tsx:427,461,480,584,595,612,622`. 사용자에겐 "눌렀는데 무반응"
- 조치: Pricing 은 결제 미연동이 사실이면(`Pricing.tsx:65` 자인) "결제 준비 중 — 문의하기"로 문구 변경. 규모 **작음**~중간

**A-3. `/crm/dashboard` "총 보험료"는 유료 사용자에게 항상 0**
`CrmDashboard.tsx:59` 가 `customers.total_premium` 을 합산하는데, 이 컬럼에 **쓰는 코드가 전무**(마이그레이션 `20260308182257:26` CREATE TABLE 의 `DEFAULT 0` 뿐, insert/update/트리거 0건). 고객 등록 다이얼로그(`CrmCustomers.tsx:385-460`)에 보험료 입력란 없음.
반면 무료 데모는 `src/data/crm-demo-data.ts:157` `totalPremium:450000` 으로 **정상 동작처럼 보인다 → 돈 낸 사용자만 0을 본다.** 규모 중간

**A-4. 기능 버튼이 이름과 다른 일을 한다**
- `/crm/messenger` `상담 종료` 버튼(`CrmMessenger.tsx:418`, 확인창 `:262` "상담을 종료하고")이 실제로는 `summarize` API 호출만 한다(`:273-283`). `conversations` 상태를 바꾸는 코드 없고 타입(`:20-27`)에 상태 필드조차 없다 → 종료해도 대화가 계속 열려 있음
- 같은 화면 안내문 `:332` "고객 상세에서 대화를 시작하세요" — `CrmCustomerDetail.tsx` 에 `conversations` 참조 0건. 대화 생성 함수 `handleStartChat`(`:163-192`)은 **어디서도 호출되지 않는 죽은 코드**
- `/crm/customers` `연락처 가져오기`(`:468-470`)는 안내문 다이얼로그만 띄우고 실행 동작 0(`:701-742`)
- `/ai-onestop` — 4채널 중 3채널이 `준비 중` 하드코딩(`AiOnestop.tsx:14-19`, 주석에 "현재 API 없으므로 하드코딩" 자인)인데 CTA 는 `:291` "모든 채널 연동" 규모 **작음**(문구)

**A-5. 플랜 게이트가 화면과 메뉴에서 서로 다른 기준을 쓴다 — 프로 결제자가 자기 기능에서 막힌다**
`src/hooks/use-user-plan.ts:123,125` 실측: `isPro = Pro||Max||Hidden`, **`isPremium = isMax`**(하위호환 alias).
- 메뉴: `ContextSubMenu.tsx:82` `if (item.premiumOnly && !isPremium)` → **Max 요구**
- 화면: `AiOnestop.tsx:45,100` `const {isPro}` → `isPro ? (전체 기능)` → **Pro 허용**
→ **Pro 결제자는 쓸 수 있는 기능을 사이드바에서 클릭조차 못 하고 업그레이드 팝업만 본다**(URL 직접 입력으로만 접근).
- 파생: `UpgradeModal` 이 약속하는 "프리미엄 플랜"은 `use-user-plan.ts:33-34` 매핑상 **Pro** 인데, 그 모달이 잠근 기능은 **Max** 를 요구한다 → 안내대로 사면 여전히 잠긴다
- `/admin/crm` 은 관리자 화면인데 `PlanGuard requiredPlan="pro"`(`AdminCrmConfig.tsx:65`)로 감싸 **시스템 관리자가 자기 관리 화면에서 blur+결제 유도**를 본다(13개 중 이 화면만)
- 조치: `premiumOnly:boolean` → `minPlan` 으로 교체하고 `planFeatureMap.ts` 의 `hasMinPlan` 으로 일원화. `isPremium` alias 폐기. 규모 **중간**

**A-6. 화면만 보고는 목적을 달성할 수 없는 화면 4개**
- `/api-key` — 설계사에게 **Meta 개발자 앱 생성 → 토큰 교환 → 수기 붙여넣기**를 요구(`ApiGuide.tsx:110-118,126,140`). 입력란은 다른 화면(`Settings.tsx:682-692`). **60일마다 반복**(`:151`)해야 하고 만료 알림은 `:130` "제공할 예정"으로 미구현
- `/tools/insuwiki` — API 호출 0건. 콘텐츠 전량 블러+잠금(`InsuWikiIntro.tsx:390-402`), 주 CTA 가 `:212` "입사 문의하기". **도구가 아니라 리쿠르팅 랜딩**
- `/admin/crm` — 쓰기 연산 0건, 3개 탭 전부 하드코딩 JSX(`AdminCrmConfig.tsx:113-193`). "CRM 관리"인데 관리 기능이 없다
- `/tools/mediscan`·`/tools/insuwiki` 문의 CTA 2개가 **`mailto:insuro@example.com`·`#placeholder`**(`src/config/cta-config.ts:20-21`, `MediScan.tsx:707,714`) — 비히든 사용자의 유일한 다음 행동이 example.com 메일

**A-7. `/tools/mediscan` 기능 설명이 실제 동작과 다르다**
`MediScan.tsx:77-79` "보험 **약관**을 업로드하면" → 실제 업로드 대상은 **의료 서류**(`:395` "의료 서류 업로드", `:29-35` 세부진료/처방조제/건강검진). `:87-89` "현재 보장과 비교해 갭을 시각화" → **증권 입력 수단이 화면에 없다**(업로드는 PDF 의료서류 1종). 규모 **작음**

**A-8. `/tools/insuwiki` 는 히든 전용인데 메뉴에 잠금 표시가 없다**
`InsuWikiIntro.tsx:90`·`MediScan.tsx:387` 이 `isHidden` 분기인데 `navigationConfig.ts:53,54` 두 항목에 `premiumOnly` 플래그 없음(같은 배열 `:61` 은 있음). 일반 설계사는 잠금 표시 없이 눌러 광고 페이지만 본다. 규모 **작음**

**A-9. 디지털 명함의 핵심 필드를 앱 어디에서도 입력할 수 없다**
`DigitalNamecard.tsx:40` 이 `introduction/specialties/career_years/certifications/profile_photo_url` 를 읽고 `:183`·`MyPage.tsx:184` 는 "프로필에서 입력하면"이라 안내한다. 그러나 `Settings.tsx:225-234` 저장 payload 에 **이 필드가 전부 없고**, 편집 UI 도 존재하지 않는다(전체 grep 결과 읽기 전용).
→ 명함은 영구히 "이름+회사명"만 표시. `MyPage.tsx:215` `명함 설정` 버튼은 `/settings` 로 보내지만 4개 섹션에 명함 항목이 없다. 규모 **중간**

### ② 분류 오류

**A-10. 죽은 섹션 정의가 진실처럼 남아 있다 (근본 원인)**
`routes.ts:127-137` `menuSections` 9개 ↔ `navigationConfig.ts:30-95` 4탭. 렌더러 `AppSidebar.tsx:63` 미참조.
- 회장님이 지적한 `분석&도구` vs `유용한도구` 이중 존재는 **죽은 쪽에만 있다** — 라이브는 이미 하나로 병합됨. `보험 시장분석 AI` 독립 섹션도 이미 흡수됨
- 라이브 기준 실제 분류 오류: **`/api-key`**(안내가 아니라 Meta 셋업 매뉴얼 → `개인 설정 > API 키` 로 흡수), **`/tools/insuwiki`**(도구 아님 → 안내), **`Helper 확장 설치`**(설치 문서가 최상위 메뉴로 승격, 복합설계 화면 내 링크 이미 존재 `CompositeDesign.tsx:1026`), **`/composite-design`**(상담이력·고객매칭 CRM 기능 혼재 — `:1063`, `CustomerMatchDialog.tsx:66`)
- 조치: `routes.ts` 의 `section`/`menuSections`/`sidebarOnlyItems` + `AppSidebar.tsx` 삭제로 **단일 소스 확정**. 규모 **중간**

**A-25/A-10-b. `정보성 키워드 분석` 을 누르면 메뉴가 통째로 갈아끼워진다**
`navigationConfig.ts:61` 은 `분석 & 도구` 소속인데 목적지는 `/keyword-analysis?tab=info-keyword` 이고 `:72` 는 `AI 마케팅` 소속이다. `getActiveTabFromPath`(`:110-118`)는 **pathname 만** 비교하므로 쿼리 포함 URL 은 매칭 실패 → 항상 `ai-marketing` 반환.
→ 분석&도구에서 클릭 시 **좌측 메뉴 전체가 AI 마케팅으로 전환되고 방금 누른 항목은 활성 표시조차 안 된다.**
추가: `/info-keyword` 는 `App.tsx:58` 의 `<Navigate>` 가 `routes.ts:267` 보다 먼저 선언되어 **`InfoKeyword.tsx` default export 페이지는 도달 불가한 죽은 코드**(실사용은 `KeywordAnalysis.tsx:4` 의 named export). 규모 **작음**

**A-11/A-36. "대시보드/분석" 3중 이름 충돌 + 죽은 별칭**
`routes.ts:527-531` `{path:"/analytics", title:"분석", component: Contents}` — 화면은 `Contents.tsx:32` **"콘텐츠 관리"** 를 렌더한다. 제목과 내용 불일치. 링크 0건이라 실피해는 낮으나 북마크·외부링크로 진입 가능.
덤: `src/pages/Analytics.tsx`(h2 "성과 분석")는 **어떤 라우트에도 연결되지 않은 고아 파일**.
`/crm/dashboard`("대시보드") · `/admin/analytics`("KPI 대시보드") · `/analytics`("분석") 세 라벨이 서로 다른 층위를 가리키는데 구분 단서가 없다. 규모 **작음**

**A-9-b. 디지털 명함 링크가 탭을 이탈시키고 앵커 스크롤도 안 된다**
`navigationConfig.ts:42` 는 고객관리 탭인데 `:106` 이 `/mypage` 를 `info-settings` 로 판정 → 클릭 시 **안내&설정 탭으로 강제 전환**. 앵커 대상은 존재하나(`MyPage.tsx:176` `<Card id="namecard">`) SPA 내부 이동에서 해시 스크롤 핸들러가 전역에 없고, 로딩 스켈레톤(`:123-134`)이 먼저 그려져 네이티브 스크롤도 실패. 규모 **작음**

### ③ 용어 불일치

**A-13. 사이드바 제목 ≠ 페이지 제목 (라이브 기준 8건)**
| 경로 | 메뉴 라벨 | 페이지 제목 |
|---|---|---|
| /api-key | API키 | **SNS 연동 가이드** |
| /settings | 개인 설정 | **내 설정** |
| /guide | 이용방법/가이드 | 인슈로 서비스 이용가이드 |
| /market/newsletter | 소식지분석 | 소식지 AI 분석 |
| /tools/insurance-portal | 보험사 전산정보 | 보험사 전산 포털 |
| /crm/dashboard | 대시보드 | 고객관리 대시보드 |
| /fcpa | 금소법 | 금융소비자보호법 가이드 |
| /market/premium-compare | 보험료/환급률 분석 | 보험료/환급률 분석 AI |
근거: `navigationConfig.ts:37,51,52,58,86,87,88,91` ↔ `ApiGuide.tsx:32`·`Settings.tsx:303`·`HelpGuide.tsx:168`·`MarketNewsletter.tsx:152`·`InsurancePortal.tsx:161`·`CrmDashboard.tsx:204`·`FcpaGuide.tsx:123`·`PremiumComparison.tsx:240`. 규모 **작음**

**A-16. 유료 등급 명칭이 최소 5가지로 갈린다 — 결제 판단을 직접 방해**
`PREMIUM`(`ContextSubMenu.tsx:96`) · "프리미엄 플랜"(`UpgradeModal.tsx:70,73`) · "맥스 플랜 이상"(`KeywordAnalysis.tsx:62`) · "프로 플랜 전용"(`AiOnestop.tsx:216,289`) · "Pro 이상"/"Premium 이상"(`Calculators.tsx:323,437`, 하드코딩). A-5 의 `isPremium=isMax` 와 결합해 **안내와 실제 게이트가 어긋난다.** 규모 **중간**

**A-12. 내부 코드명이 설계사 화면에 그대로 노출**
`CrmCustomers.tsx:607` 버튼 라벨 **`ohmy history`**(고객 카드마다 표시) — 정작 다이얼로그 제목은 `:660` "…의 상담이력". `:312` 토스트도 "…history가 다른 고객으로 이동되었습니다".
`PolicyTermsUpload.tsx:350,354,358,363,380,412` 가 `product_id`·`terms_sha256`·`drive_file_id` 를 결과 화면에 노출(확정#4의 방증).
`ImageEditor.tsx:1045` 사이드바 라벨 **`WM삭제`** ↔ 패널 제목 `워터마크 삭제`(`AIPanel.tsx:50`). 규모 **작음**

**A-17. 복합설계 계열 명칭 3중 + 담보/보장 혼용**
nav "복합설계 계산기"(`navigationConfig.ts:62`) / h1 "복합설계 AI 계산기"(`CompositeCalculatorHeader.tsx:20`) / h2 "AI 복합설계 계산이란?"(`CompositeGeneralIntro.tsx:48`). 같은 화면에서 `보장 필터`(`CompositeDesign.tsx:1297`) ↔ `담보 목록`(`:1305`) ↔ `가입한도`(`ConsultationHistoryView.tsx:163`). 내부어 "매트릭스/캡처" 노출(`:1196,1224`). 규모 **중간**

**A-14/A-15/A-34/A-35. 제목 구조 불일치**
h1 부재: `/mypage`(h2, `MyPage.tsx:149`) · `/crm/messenger`(h2, `:322`) · `/tools/pdf-editor`(제목 자체 없음) · `/tools/image-editor`(h1/h2 **0건**) → 메뉴에서 누른 이름이 화면에 다시 안 나와 현재 위치 확인 불가.
h2 오용: `Contents.tsx:32`·`Generate.tsx:332`·`FcpaGuide.tsx:121`·`AdminFcpa.tsx:189`·`AdminAnalytics.tsx:208`.
관리자 제목 접미사: `금소법 관리 (관리자)` 만 `(관리자)` 를 달고 나머지 12개는 없음. routes.ts 제목↔h1 불일치 5건(조직 관리→조직 & 구독 관리 등). 규모 **작음**

**A-41. 404 페이지만 영어**
`NotFound.tsx:14-18` `404` / `Oops! Page not found` / `Return to Home`. 전면 한국어 제품에서 유일. 게다가 비로그인 시 `/login` 으로 흡수되어 **표시되지도 않는다**(실브라우저 확인). 규모 **작음**

**A-20. 권한 거부 문구 4종 혼용**
"관리자 권한이 필요합니다"+버튼(`AdminNotices.tsx:116`) / "접근 권한이 없습니다"(`AdminCrmConfig.tsx:55`) / 문구 없이 `navigate("/")` 9개 화면 / 빈 화면(`AdminImageFeedback.tsx:104`). 규모 **작음**

### ④ 설명 부정확

**A-29. `/intro` "금소법 100% 사전 차단" — 무료·베이직엔 검증이 없다**
`Intro.tsx:47` "작성된 **모든** 글과 자료는 … 금소법 위반 소지를 **100%** 사전에 차단합니다" ↔ `Generate.tsx:793-802` 는 `!isPro` 일 때 "프로 플랜부터 … 자동으로 검토합니다" 안내만 띄운다. **무료/베이직은 검증이 아예 돌지 않는다.** 금융 도메인 특성상 표현 리스크. 규모 **작음** · **우선 정정 권고**

**A-28. 플랜 비교표가 실제 게이트와 어긋난다**
`AiOnestop.tsx:248-249` 베이직에 "금소법 자동 검증" 표기 ↔ `Generate.tsx:793` 은 `!isPro` 차단이고 `use-user-plan.ts:123` 상 Basic 은 `isPro=false` → **없는 혜택을 판다.**
`/ai-automation` 은 최상위 히든 플랜에서도 `AiAutomation.tsx:90` "현재 개발 중입니다" 인데 `UpgradeModal.tsx:24-28` 이 이를 **유료 셀링포인트로 제시**한다. 규모 **작음**

**A-32. `/pricing` FAQ 자기모순**
`Pricing.tsx:65` "현재 결제 시스템 연동을 준비 중" ↔ 같은 배열 `:44-46` "업그레이드 시 차액만 결제되고…", `:48-50` "세금계산서 발행이 가능합니다" 는 이미 되는 것처럼 답한다. A-2(죽은 버튼)와 합쳐 "되는 줄 알고 눌렀는데 무반응". 규모 **작음**

**A-31. `/mypage` 명함 URL 표시가 실제 복사값·실제 도메인과 다르다**
표시 `MyPage.tsx:199` `insuro.app/namecard/{8자}...`(하드코딩) ↔ 실제 복사값 `:193` `${window.location.origin}/namecard/${userId}` ↔ 실제 도메인 **insuro.biz**. 규모 **작음**

**A-21. `/tools/insuwiki` "주간 추이" 그래프가 합성치**
`InsuWikiIntro.tsx:301-307` 이 이번 주 값에 `0.7/0.8/0.88` 고정계수를 곱해 과거 3주를 만든다 → **항상 우상향**. 같은 카드 `:337` "총 콘텐츠 수 158편" 은 하드코딩(좌우 지표는 실데이터). 규모 **작음**

**A-27. `/generate` 무료 한도 분모가 하드코딩**
`Generate.tsx:75` 분자는 DB(`maxContentsValue`) 기반인데 `:364` 는 `{remainingCount}/5회` — **분모 5가 리터럴**. 관리자가 10으로 올리면 "10/5회"가 표시된다. 워크스페이스 하드코딩 금지 규칙 위반. 규모 **작음**

**A-26. 복합설계·Helper 안내문 복붙 오류**
담보 목록이 비면 "**버전 정보를** 불러오는 중입니다"가 뜬다(`CompositeDesign.tsx:1320-1322,1327-1329` — `CompositeExtensionGuide.tsx:199` 문구를 복사). HTTP 404 를 "백엔드 점검 중"으로 단정(`:1310`). 상담이력 0건은 "기능이 준비 중입니다"(`:1085-1088`)로 표시돼 재시도를 포기하게 만든다.
Helper 화면은 FAQ `:34` "기존 확장은 **자동 교체**됩니다" ↔ `:182-184` 수동 재로드 2단계 요구로 상충. 규모 **작음**

**A-25-b. `/info-keyword` 소요시간 안내가 코드 실측과 어긋남**
화면 `:694` "약 1~2분" ↔ 코드 주석 실측 `:30` "**5개 시 ~343초**", `:31` 상한 900s. 최대 5개 선택 가능(`:482`)인데 실제 ~5.7분. 규모 **작음**

**A-37. `/admin/fcpa` "자동 반영" 과장**
`AdminFcpa.tsx:193-195` "가이드, 체크리스트, PDF를 업데이트하면 프롬프트에 자동 반영" ↔ 실제 소비는 **checklist 하나뿐**(`supabase/functions/generate-content/index.ts:554` `.select("checklist")`). 벡터 반영도 자동이 아니라 별도 버튼(`:247-262`). 규모 **작음**

**A-38. `/admin/crm` 한 화면 안에서 자기모순**
`AdminCrmConfig.tsx:121` ElevenLabs STT `status="active"`(활성) ↔ `:153-160` 같은 화면 다른 탭 `(미연동)`·`미설정` ↔ `:190` `status="done"`(완료). 전부 하드코딩. 규모 **작음**

**A-19/A-22/A-23/A-24/A-30. 그 외 문구·필터 불일치**
- `엑셀 등록` 버튼이 `.xlsx` 를 거부 — `CustomerImport.tsx:204` 라벨 ↔ `:221` `accept=".csv,.txt"`
- `/market/premium-compare` 잠금 사유 오표기 — `:217` "제휴된 업체 소속 설계사만" ↔ 실제 게이트는 `:91` **데이터 행 수 0** 여부. 제휴사여도 데이터 미업로드면 오해. 분석 항목 3종도 하드코딩(`:20-24,283`)
- 같은 화면 잠금 탈출 버튼이 **404** — `:222` `navigate("/community")`, 해당 라우트 미정의(`/notices` 가 정답)
- `/tools/insurance-portal` `:163` "청구서 다운로드·설계사 필수 도구" ↔ 실제는 외부 링크 46개뿐, `:21` `isPlaceholder` 는 영구 false 인 죽은 분기. `Edge 전산접속` 2건(`insurance-companies.ts:19,23`)은 `microsoft-edge:` 프로토콜이라 macOS/모바일에서 무반응인데 경고 없음
- `/tools/calculators` 플랜명 하드코딩(`:323,437`), PV 결과 문구 어순 오류(`:411`)
- `/guide` 정렬 기준이 **죽은 9섹션 이름**을 참조(`HelpGuide.tsx:22`)하고 신규 7화면이 `SIDEBAR_MENU_URLS`(`:23-31`)에서 누락 → 목차 순서가 실제 메뉴와 어긋남

### ⑤ 보안 / 접근제어 (범위 밖이나 발견되어 보고 — **ANU 판단 요청**)

**A-33. `adminOnly` 라우트 가드가 존재하지 않는다**
`App.tsx:59-65` 는 `routes` 를 그대로 `<Route>` 로 펼치며 `adminOnly`/`premiumOnly` 를 **읽지 않는다**. 유일한 소비처가 `AppSidebar.tsx:185` 인데 그 컴포넌트가 죽어 있다(§C).
현재 막아주는 것은 13개 페이지가 각자 심은 `useIsAdmin()` 체크뿐(13/13 존재 확인). **신규 관리자 페이지에서 체크를 빠뜨리면 즉시 구멍.**
추가: `ContextSubMenu.tsx:28-57` 은 `pathname.startsWith("/admin")` 이면 **권한 확인 없이** 관리자 메뉴 12개를 렌더 → 비관리자가 `/admin/notices` 직접 입력 시 본문은 거부되지만 **좌측에 관리자 메뉴 전체 목록이 보인다**.
조치: `App.tsx` 에 `RequireAdmin` 래퍼 도입(라우터 단일 지점 강제) + ContextSubMenu 관리자 분기에 `isSystemAdmin` 조건. 규모 **작음**

**A-40. `ai_config` 평문 API 키가 전체 인증 사용자에게 SELECT 허용**
`supabase/migrations/20260308111136_...sql:6` `api_key TEXT`, `:17` `CREATE POLICY ... FOR SELECT TO authenticated USING (true)`. `AdminAIConfig.tsx:68,72` 가 값을 브라우저 폼에 복원. 완화 마이그레이션 미발견.
**⚠ 프로덕션 실제 정책은 미확인** — 마이그레이션 파일 기준 판정이다. 확정하려면 anon/authenticated 키로 프로덕션 REST 직접 프로브가 필요하다(본 태스크 범위 밖).

**A-39. `/namecard/:agentId` 공개 페이지가 anon 으로 `customers` 에 직접 쓰기**
`DigitalNamecard.tsx:69-71` SELECT, `:77-86` 기존 고객 `phone` 이 비어 있으면 **방문자 입력값으로 UPDATE**, `:110-116` 채팅 토큰을 클라이언트가 생성해 INSERT.
→ 이름을 맞히면 기존 고객 레코드가 재사용되고 그 고객의 대화 토큰이 발급될 수 있는 구조. **RLS 가 실제로 anon 쓰기를 막는지는 미확인**(`customers` 용 anon 정책은 grep 미발견 → 코드가 RLS 거부에 의존).
조치: SECURITY DEFINER RPC 로 이관(task-2991 caller-binding 패턴). **프로덕션 anon 프로브로 관통 여부 즉시 확인 필요.**

---

## 3. 회장님 발견 5건 — 위치 확인 (재조사 안 함)

| # | 내용 | 위치 | 비고 |
|---|---|---|---|
| 1 | 신규설계 비교가 `분석&도구` 분류 | `src/config/routes.ts:331-335` (`section:"분석&도구"`) | ★ **실제로는 라이브 메뉴에 부재**(A-1, 번들 실측). 근거가 된 `section` 값은 죽은 메타데이터 |
| 2 | 제목 "신규**설계**" ↔ 라벨 "신규 **견적**" | 제목 `routes.ts:332` / 라벨 `NewDesignComparison.tsx:196` "신규 견적 JSON (coverages)" | 전수 조사 결과 `견적` 은 **2개 파일 10건**뿐(`NewDesignComparison.tsx` 6 + `NewDesignComparisonTable.tsx` 4) → 치환 범위 한정 |
| 3 | JSON 직접 입력, 업로드 UI 없음 | `NewDesignComparison.tsx:186-205` Textarea 2개, placeholder `'{"coverages":[...]}'` `:190,202`, `JSON.parse` `:77,83` | 파일 업로드 요소 0건 |
| 4 | 약관 업로드가 설계사 메뉴 노출 | `routes.ts:303-307` + **라이브** `navigationConfig.ts:57` | 라이브 메뉴에 실재 확인(번들 `약관 업로드` 1건). 내부 식별자 노출도 확인(A-12) |
| 5 | 약관 업로드 설명 모순 | `PolicyTermsUpload.tsx:219-220` "…판별축(axes)을 확보합니다. **이후 보장분석 화면에서 증권과 함께 첨부하면**…" | 대상 화면은 `/crm/policy-analysis` 의 "약관 PDF (선택)" `PolicyAnalysis.tsx:560-619` |

---

## 4. 수정 제안 우선순위

| 순위 | 조치 | 근거 | 규모 |
|---|---|---|---|
| **1** | **네비게이션 단일 소스 확정** — `AppSidebar.tsx` 및 `routes.ts` 의 `section`/`menuSections`/`sidebarOnlyItems` 제거, `navigationConfig` 로 일원화 | A-10. 정의가 두 벌인 한 아래 수정이 전부 재드리프트 | 중간 |
| **2** | **메뉴 누락 5건 복구 + 신규설계 비교를 `고객관리` 로 이동** | A-1, 확정#1. 특정 고객 전제 → 고객관리. 실손계산기는 범용이라 분석&도구 잔류 | 작음 |
| **3** | **약관 업로드를 `관리자` 로 이동** + 설명문 정정 | 확정#4·#5. 상품 지식 DB 적재는 관리 작업 | 작음 |
| **4** | **`/pricing` 결제 CTA 결선 또는 "준비 중" 명시** | A-2. 유료 전환 동선 전체가 막혀 있음 | 작음 |
| **5** | **플랜 게이트 일원화**(`minPlan` 도입, `isPremium=isMax` alias 폐기) | A-5, A-16. Pro 결제자가 자기 기능에서 막힘 | 중간 |
| **6** | **`adminOnly` 라우터 가드(`RequireAdmin`) 도입** | A-33. 현재 페이지별 수기 방어뿐 | 작음 |
| **7** | **신규설계 비교에 PDF 업로드 UI 도입**(JSON textarea 제거) + 용어 "설계"로 통일 | 확정#2·#3. 10개 문자열 치환 + 업로드 결선 | **큼** |
| **8** | 과장·모순 문구 정정 — `/intro` "100%", `/ai-onestop` 채널·플랜표, `/pricing` FAQ, `/admin/fcpa` "자동 반영" | A-29·A-28·A-32·A-37. 금융 도메인 표현 리스크 포함 | 작음 |
| **9** | 제목 3자 통일(8건) · 내부코드명 제거(`ohmy history`·`WM삭제`·`terms_sha256`) · h1 보강 | A-13·A-12·A-14 | 작음 |
| **10** | 데이터 없는 지표 처리 — `총 보험료`, 인슈위키 합성 그래프, `/generate` 분모 하드코딩 | A-3·A-21·A-27 | 중간 |

### ANU 판단 요청 (본 태스크 범위 밖)
1. **A-39 `/namecard` anon 쓰기 경로** — 프로덕션 anon 프로브로 실제 관통 여부 확인 필요. 관통 시 P0.
2. **A-40 `ai_config` 평문 키 SELECT 개방** — 프로덕션 실제 RLS 정책 확인 필요.
3. **A-33 라우트 가드 부재** — 현재 실피해는 없으나(13/13 자체 체크) 구조적 구멍.
4. **배포 시점** — 라이브 번들과 repo HEAD 의 동기 여부. 본 진단의 메뉴 판정은 **프로덕션 번들 실측** 기준이다.

---

## L1 스모크테스트
- **서버 재시작**: 해당없음 (진단 전용 태스크, 코드 변경 0줄)
- **API 응답 확인**: `curl -s -o /dev/null -w "%{http_code}" https://insuro.biz/` → **200**. 프로덕션 번들 6개 + `DashboardLayout-HZzbI6Sn.js` 정상 수신(44,402 bytes)
- **스크린샷**:
  - `/home/jay/workspace/teams/dev5/.playwright-mcp/task-2994-privacy-public.png` — `/privacy` 공개 렌더 정상(육안 검증: 목차 10항목·본문 표시 확인)
  - `/home/jay/workspace/teams/dev5/.playwright-mcp/task-2994-loginwall.png` — **로그인월 화면**(기능 화면 아님을 명시)
- **실브라우저 라우트 프로브**: 58 라우트 전수 접근 시도. 공개 2건 렌더, 나머지 `/login` 리다이렉트 확인

## 검증 규율 메모
- 팀원 3인이 독립적으로 "AppSidebar 죽음"을 보고했으나 **그대로 채택하지 않고** 팀장이 프로덕션 번들을 직접 내려받아 재검증했다. 그 과정에서 minified 1-line JS 에 `grep -c` 를 쓴 자체 오류(라인 수↔출현 수)를 발견해 `grep -o | wc -l` 로 정정했고, lazy chunk 미조회로 "navigationConfig 미배포"라 판단할 뻔한 것을 `DashboardLayout-*.js` 조회로 바로잡았다.
- "메뉴에 없다"는 판정의 권위 근거는 소스가 아니라 **프로덕션 번들 실측**이다.

## 트립와이어
Critical7=0 · PII net-new=0 · 회귀실패=0(테스트 미실행, 코드 변경 없음) · forbidden_paths 침범=0 · nonce=task-2994

## 비고
- **코드 변경 0줄** — `src/**`·`server/**` 미수정. PR 없음. `git status` 상 InsuRo repo 워킹트리 변경 없음
- 미확인 항목은 각 문항에 명시(DB 주도 문구, 프로덕션 RLS, 화면 내부 실렌더)

---

## 종결 게이트 상태 (ANU 판단 요청)

`finish-task.sh task-2994 dev5-team /home/jay/workspace` 를 `FINALIZE_ONLY=1` 로 실행했으나 **QC 게이트가 환경 오류로 중단**되었다. QC 실패가 아니라 **실행 자체가 불가**한 상태다.

1차 오류 (PYTHONPATH 미설정):
```
File "teams/shared/verifiers/browser_verify.py", line 18
    from utils.task_id_parser import is_valid_task_id, TASK_ID_RE
ModuleNotFoundError: No module named 'utils'
```
→ `PYTHONPATH=/home/jay/workspace` 주입 후 2차 오류:
```
INTEGRITY_FAIL: verifiers 디렉토리가 shared로의 심볼릭 링크가 아닙니다
```

**본 태스크 고유 문제가 아니다** — 실측 결과 `teams/{dev1..dev8}/verifiers` 중 심볼릭 링크가 존재하는 팀은 **dev6 하나뿐**이고 dev1~5·7·8 은 전부 부재다. 즉 팀 디렉토리에서 QC 게이트를 통과할 수 있는 팀이 사실상 없다.

- 조치하지 않은 이유: `verifiers` 심볼릭 생성은 `teams/shared` 공용 인프라 변경이며 본 태스크 `allowed_resources.paths`(`memory/reports/task-2994.md`) 밖이다. 또한 검증전용 QC 해소(`## 레벨: 코드 수정 없음`)는 **부여 권한이 ANU** 이므로 팀장 자가부여를 하지 않았다.
- 완료 마커: `memory/events/task-2994.done` 은 **`task-timer.py end` 가 생성**한 것이다(수동 생성 아님). `task-2994.done.notified` 동반 생성 확인.
- **요청**: ① QC 게이트 환경(verifiers 심볼릭/PYTHONPATH) 복구는 별도 인프라 태스크로 분리 ② 본 진단 태스크의 종결 판정은 ANU 재량.

## 세션 통계
- 총 도구 호출: 0회

