# 작업 보고: task-2995 — InsuRo 개인정보처리방침 개정 (외부 법률검토 반영)

- **팀**: dev3-team (다그다)
- **레벨**: Lv.2 (법정 문서) · level=security · 회장 승인 완료(2026-08-21)
- **명세**: `/home/jay/workspace/memory/plans/tasks/task-2995.md` (정정본 sha256 앞16 `124f97196cc0d927` — 착수 시 대조 완료)
- **PR**: https://github.com/Jeon-Jonghyuk/InsuRo/pull/242 (OPEN, head `22271d2`)
- **워크트리**: `/home/jay/projects/InsuRo-worktrees/task-2995-dev3` (branch `task/task-2995-dev3`, base `origin/main` = `41b6b95`)

---

## S — 상황

task-2983 으로 `https://insuro.biz/privacy` 에 게시한 개인정보처리방침에 대해 외부 법률검토를 받았고,
회장님이 반영을 지시했다. 개정 항목은 4건이다.

착수 시점에 워크트리에는 **스펙 정정 이전 실행의 커밋 2건**(`826286c`, `9737d89`)이 이미 있었다.
개정 1~3 은 반영되어 있었으나 **개정 4 는 잘못된 우회 상태**였다.

## C — 문제

**우회의 내용**: 정정 이전 명세에서 `src/config/legalEntity.ts` 가 `allowed_resources` 밖이었기 때문에,
직전 실행이 `Privacy.tsx` 안에 로컬 상수를 새로 만들어 우회했다.

```
// src/pages/Privacy.tsx (직전 실행분)
const OPERATOR_NAME = "티오피사업단 전종혁";
```

이는 **task-2983 이 제거한 "하드코딩 2벌" 상태를 되살리는 것**이다. 처리방침 화면만 새 표기로 바뀌고
명함·상담화면·푸터는 옛 표기로 남아, 같은 서비스가 두 개의 사업자명을 노출하게 된다.
정정 명세는 이를 명시적으로 금지한다("개별 파일을 수정하지 마십시오").

## Q — 판단

1. 우회를 **원복**하고 `COMPANY_NAME` 단일 상수 1줄만 수정한다.
2. 옛 문자열을 하드코딩한 테스트를 갱신한다.
3. 명세와 실측이 어긋난 2건은 **임의 확장·수정하지 않고 ANU 에 보고**한다.

## A — 조치

### 개정 1 — 제9조 암호화 조항 (`Privacy.tsx`)
미적용 사실 명시(`현재 암호화 적용 대상이 아니며`)를 제거하고, 실제 수행 중인 조치는 유지.
조항 통째 삭제하지 않음(삭제 시 암호화 설명이 사라져 오히려 불투명해짐).

### 개정 2 — 제1조 민감정보 별도 동의 안내 (`Privacy.tsx`)
제1조 말미에 `type: "p"` 블록 추가. 설계사의 별도 명시적 동의 의무 + 당사 불관여 명시.

### 개정 3 — 제2조 파기 예외 (`Privacy.tsx`)
보존기간 조항 말미에 `type: "p"` 블록 추가.

### 개정 4 — 운영 주체 표기 (`legalEntity.ts` **1줄**)
```
- export const COMPANY_NAME = "인카금융서비스(주) 티오피사업단";
+ export const COMPANY_NAME = "티오피사업단 전종혁";
```
같은 파일의 `SERVICE_NAME` · `PRIVACY_OFFICER_NAME` · `PRIVACY_OFFICER_CONTACT` ·
`PRIVACY_POLICY_EFFECTIVE_DATE` 는 **불변**. 파일 상단 주석도 불변.

**파급 6개 참조처는 상수 자동 반영 — 개별 파일 수정 0건**:
`Privacy.tsx` · `DigitalNamecard.tsx` · `CustomerChat.tsx` · `AuthGuard.tsx` · `AuthForm.tsx` · `Footer.tsx`
회장님이 선택한 **(a) 전부 통일**이 의도된 결과다.

### 우회 원복
`Privacy.tsx` 에서 `OPERATOR_NAME` 상수 + 관련 주석 3줄 삭제, `COMPANY_NAME` import 복원,
`INTRO_TEXT` 를 `${COMPANY_NAME}` 사용으로 되돌림.
최종 확인: `grep -rn "OPERATOR_NAME" src/` → **0건**.

---

## 수정 파일별 검증 상태

| 파일 | 변경 내용 | grep 검증 | 상태 |
|---|---|---|---|
| /home/jay/projects/InsuRo-worktrees/task-2995-dev3/src/config/legalEntity.ts | COMPANY_NAME 1줄 정정 | grep "티오피사업단 전종혁" OK | verified |
| /home/jay/projects/InsuRo-worktrees/task-2995-dev3/src/pages/Privacy.tsx | 개정1·2·3 반영 + OPERATOR_NAME 우회 원복 | grep "분리하여 별도의 명시적 동의" OK | verified |
| /home/jay/projects/InsuRo-worktrees/task-2995-dev3/src/pages/__tests__/Privacy.test.tsx | verbatim 봉인 테스트 | grep "AMENDMENT_1_ENCRYPTION_RENDERED" OK | verified |
| /home/jay/projects/InsuRo-worktrees/task-2995-dev3/src/pages/__tests__/DigitalNamecard.test.tsx | 옛 문자열 갱신 | grep "티오피사업단 전종혁" OK | verified |
| /home/jay/projects/InsuRo-worktrees/task-2995-dev3/src/pages/__tests__/CustomerChat.gateNotice.test.tsx | 옛 문자열 갱신 | grep "티오피사업단 전종혁" OK | verified |

`git diff --stat origin/main..HEAD` → 5 files changed, 107 insertions(+), 5 deletions(-)

---

## 검증 결과

### 1. 개정 전 원문 기록 (대조 근거)
개정 전 4곳 원문을 착수 시점에 채집해 두었고, 개정 후 지정 문구와 1:1 대조했다.
- 암호화 조항: `Privacy.tsx:251` (개정 전) → 지정 교체 문구와 일치
- 민감정보 안내: 개정 전 **부재** → 신규 추가
- 파기 예외: 개정 전 **부재** → 신규 추가
- 운영 주체: `legalEntity.ts:9` → 지정 문구와 일치

### 2. 테스트
```
npx vitest run  →  Test Files 88 passed (88)
                   Tests 1265 passed (1265)
                   실패 0건 · VITEST_EXIT=0
```
★ 팀장이 팀원 보고를 신뢰하지 않고 **독립 재실행**한 결과다.

### 3. 빌드
```
npm run build  →  BUILD_EXIT=0  (✓ built in 11.94s, PWA precache 180 entries)
```
청크 크기 경고는 pre-existing 이며 본 변경과 무관.

### 4. 프로덕션 번들 실측 (repo 워킹트리 아님 — `dist/` 산출물)
minified 1-line 함정을 피하기 위해 `grep -o | wc -l` 로 계수했고, lazy chunk 를 포함한 `assets/` 전체를 훑었다.

```
티오피사업단 전종혁          → assets/index-DrLaRhBE.js  1건
인카금융서비스(주)           → 0건   ✅
현재 암호화 적용 대상이 아니  → 0건   ✅
서비스와 데이터베이스 간 통신은 HTTPS(TLS)로 암호화하며 → 1건
분리하여 별도의 명시적 동의   → 1건
지체 없이 파기됩니다         → 1건
2026년 8월 9일 (시행일)      → 1건   ✅ 불변
```

### 5. 실브라우저 E2E — **픽스처 아님**
빌드 산출물(`dist/`)을 `vite preview` 로 서빙(`http://localhost:4519/privacy`)하고 실제 Chromium 으로 접속했다.
로그인월 없이 정상 렌더되었고(`HTTP=200`, 콘솔 에러 0), 라이브 DOM `document.body.innerText` 기준 10개 항목을 검사했다.

```
개정4 신규표기 "티오피사업단 전종혁"          → true
개정4 구표기 "인카금융서비스(주)"             → false  ✅
"인카금융서비스" (처리방침 화면 전체)          → false  ✅
개정1 암호화 신문구 (전문 verbatim)           → true
개정1 금지문구 "현재 암호화 적용 대상이 아니"  → false  ✅
개정2 민감정보 별도동의 (전문 verbatim)        → true
개정3 파기 예외 (전문 verbatim)               → true
시행일 "2026년 8월 9일"                       → true   ✅ 불변
보호책임자 "전종혁 지점장"                     → true   ✅ 불변
연락처 "010-5280-5058"                        → true   ✅ 불변
```

인트로 실제 렌더값:
> 티오피사업단 전종혁(이하 "회사")은 InsuRo(인슈로) 서비스를 운영하며, 「개인정보 보호법」 등 관련 법령을 준수하여 이용자 및 고객의 개인정보를 다음과 같이 처리합니다.

**스크린샷** (4개 개정 각각을 요소 단위로 촬영, 눈으로 판독 완료):
```
/home/jay/workspace/memory/reports/assets/task-2995/task-2995-privacy-full.png        전체 페이지
/home/jay/workspace/memory/reports/assets/task-2995/task-2995-amend4-operator.png     개정4 운영주체
/home/jay/workspace/memory/reports/assets/task-2995/task-2995-amend1-encryption.png   개정1 암호화
/home/jay/workspace/memory/reports/assets/task-2995/task-2995-amend2-sensitive.png    개정2 민감정보
/home/jay/workspace/memory/reports/assets/task-2995/task-2995-amend3-destruction.png  개정3 파기예외
```

---

## L1 스모크테스트

실서버(빌드 산출물 `dist/` 를 `vite preview` 로 서빙) + 실제 Chromium 브라우저로 수행했다. 픽스처 아님, SKIP 아님.

| 항목 | 방법 | 결과 |
|---|---|---|
| 페이지 응답 | curl `http://localhost:4519/privacy` | HTTP 200 OK |
| 렌더 정상 | Chromium 실접속, 콘솔 에러 0건, 로그인월 없음 | 성공 |
| 개정1 암호화 문구 | 라이브 DOM `innerText` verbatim 대조 | PASS |
| 개정2 민감정보 별도동의 | 라이브 DOM `innerText` verbatim 대조 | PASS |
| 개정3 파기 예외 | 라이브 DOM `innerText` verbatim 대조 | PASS |
| 개정4 운영주체 표기 | 라이브 DOM `innerText` verbatim 대조 | PASS |
| 금지문자열 `인카금융서비스` | 라이브 DOM 부재 확인 | PASS (0건) |
| 금지문자열 `현재 암호화 적용 대상이 아니` | 라이브 DOM 부재 확인 | PASS (0건) |
| 시행일 불변 | `2026년 8월 9일` 존재 확인 | PASS |
| 회귀 | `npx vitest run` | 1265 tests passed, 실패 0 |
| 빌드 | `npm run build` | EXIT=0 성공 |

스크린샷(실렌더, 눈으로 판독 완료):
- `memory/screenshots/task-2995-privacy-full.png` — /privacy 전체 페이지
- `memory/screenshots/task-2995-amend4-operator.png` — 개정4 운영주체 표기
- `memory/screenshots/task-2995-amend1-encryption.png` — 개정1 암호화 조항
- `memory/screenshots/task-2995-amend2-sensitive.png` — 개정2 민감정보 별도동의
- `memory/screenshots/task-2995-amend3-destruction.png` — 개정3 파기 예외

**종합: L1 스모크테스트 PASS**

---

## ★ ANU 판단 요청 2건 (명세 ↔ 실측 차이 — 임의 판단하지 않음)

### 요청 1 — 옛 문자열 하드코딩 테스트가 2건이 아니라 **3건**이었다

명세는 2건(`Privacy.test.tsx:28`, `DigitalNamecard.test.tsx:84`)을 지정했으나, 실측 결과 3번째가 있었다.

```
src/pages/__tests__/CustomerChat.gateNotice.test.tsx:87
  expect(screen.getByText(/인카금융서비스\(주\) 티오피사업단/)).toBeInTheDocument();
```

**갱신한 근거** (자가 확장이 아님):
- 경로가 `allowed_resources.paths` 의 `src/pages/__tests__/**` **안**이다
- 명세 검증항목 5 가 "처리방침 관련 테스트가 문구를 하드코딩하고 있으면 그 테스트도 함께 갱신한다"를 지시한다
- 방치하면 회귀가 깨져 완료 조건 "회귀 유지"를 충족할 수 없다

참고로 `Privacy.test.tsx:28` 은 직전 실행에서 이미 갱신되어 있어 실제 손댄 것은 2건이다.

### 요청 2 — `인카금융서비스` **`src/` 전체 0건은 달성 불가**하다. 별개 문구가 2곳이 아니라 **3곳**이다

명세 검증항목 4 는 `src/` 전체 0건을 요구하면서 예외로 2곳을 들었으나, 실측 3곳이다.

```
src/components/composite/CompositeCalculatorHeader.tsx:34
  "인카금융서비스 전산 - 보장분석 메뉴를 통해 'ohmymanager' 접속해서 보험료를 비교해보세요"   ← 명세 인지
src/pages/CompositeExtensionGuide.tsx:142
  "이 확장은 인카금융서비스 FA 전용 도구이며, 본인이 보유한 ohmymanager 계정의 데이터만 처리합니다."  ← 명세 인지
src/pages/CompositeDesign.tsx:240
  "복합설계 계산기는 인카금융서비스 소속 FA 전용 기능입니다."                                  ← ★ 명세 미인지
```

셋 다 `COMPANY_NAME` 상수가 아닌 별개 표현이고 명세가 수정을 금지했으므로 **건드리지 않았다**.
다만 회장님 확정 근거("법인이 아니라 개인 운영")를 그대로 적용하면 이 3곳도 사실과 어긋날 소지가 있다.
**본 태스크 범위가 아니므로 발견 사실만 보고**하며, 처리 여부는 ANU/회장 판단 사항이다.

따라서 **실측 기준 완료 판정은 "`인카금융서비스` 가 처리방침 렌더 결과 및 `COMPANY_NAME` 파생 경로에서 0건"** 이며,
이는 위 실브라우저 검사와 번들 실측으로 충족되었다.

---

## ★ scope-guard FAIL — 자가해소하지 않음 (ANU 재스냅샷 필요)

`finish-task.sh` 의 scope-guard 가 위반 1건으로 머지를 차단했다.

```
VIOLATION: src/config/legalEntity.ts: paths 미포함 (scope 외 파일)
```

**이것은 범위 위반이 아니라 capability 스냅샷이 명세 정정보다 먼저 찍힌 것이다.** 근거:

```
capabilities 스냅샷  /home/jay/workspace/memory/capabilities/task-2995.json
  captured_at        2026-08-21T16:01:06  (dispatch 시점)
  source_sha256      d749c2a1585b569b5ebc7d148e43f16e50c98905afa36611039ec01cedd241c8
  paths              src/pages/Privacy.tsx · src/pages/__tests__/** · tests/** · e2e/**
                     · memory/reports/task-2995.md
                     ★ src/config/legalEntity.ts 없음

정정본 명세         /home/jay/workspace/memory/plans/tasks/task-2995.md
  sha256             124f97196cc0d92766d21f64da94de0c15ccf6e509280ca3dab2424d9aa288ef
  paths              ★ src/config/legalEntity.ts 포함 (정정으로 추가됨)
```

스냅샷 sha `d749c2a1…` ≠ 정정본 sha `124f9719…` 이므로, 스냅샷은 **정정 이전 명세**에서 채집된 것이 확정된다.
정정 지시문에도 "allowed_resources 에 legalEntity.ts 가 추가되었습니다" 라고 명시되어 있다.

**조치**: `bot-capability-model` 상 스냅샷은 immutable 이며 수정 권한은 ANU 에 있다.
봇이 스스로 스냅샷을 고치면 self-bypass 이므로 **건드리지 않았다.**
근거만 박제하고 ANU 의 재스냅샷 또는 `task-2995.anu-override.json` 을 기다린다.
생성된 마커: `memory/events/task-2995.escalate` · `task-2995.scope-violation.json`

머지는 어차피 ANU 소관이므로 본 태스크의 완료 조건(PR 생성)에는 영향이 없다.

## 범위 준수

- **수정한 것**: `legalEntity.ts`(COMPANY_NAME 1줄) · `Privacy.tsx` · `__tests__/` 3건 — 전부 `allowed_resources` 내부
- **수정하지 않은 것**: `src/components/**` · `server/**` · `supabase/**` · `ops/**` · `scripts/**` · `.github/**` — **변경 0건**
- **시행일 불변** · 연락처·보호책임자·다른 조항 불변
- **문구 창작 0건** — 개정 1·2·3 전부 명세 지정 문구 verbatim (봉인 테스트가 전문 일치를 강제)

## 팀 운영

- 팀장(다그다)은 직접 코딩하지 않았다. 구현은 **브리짓(프론트엔드, Sonnet)** 에게 위임했다.
- 팀장은 착수 전 baseline 채집, 명세 sha 대조, diff 검증, vitest/build 독립 재실행, 번들 실측,
  실브라우저 E2E, PR 작성을 수행했다.
- 팀원 보고 중 **1건을 교차검증으로 확인**: TypeScript 진단이 `COMPANY_NAME` 미사용으로 표시되어
  원복 실패를 의심했으나, 실제 파일 확인 결과 `Privacy.tsx:39` 에서 사용 중이었고 진단이 편집 중간 상태의
  stale 값이었다. 빌드 EXIT=0 으로 재확인.

## 비고

- **머지 금지 준수** — PR 생성까지가 범위다. 머지는 ANU 가 수행한다. (`FINALIZE_ONLY=1` 로 종결)
- **QC 게이트**: 10 PASS / 0 FAIL / 10 SKIP / 3 WARN — `.qc-result` · `.qc-done` 생성됨
- **CI 11/11 GREEN** (head `22271d2`) · `mergeable=true` · `mergeable_state=clean`
```
cancel-kill-switch  success     ci                  success
ci/guard            success     diagnostic          success
e2e-test            success     gemini-review-gate  success
guard               success     hidden-path-audit   success
lock-in-check       success     merge-safety-check  success
qc-check            success
```
- GitHub 호출은 전부 `GH_TOKEN="$BOT_GITHUB_TOKEN"` 로 수행했다(회장 개인 PAT 미사용).

## dev3-team 추가 항목

- **GLM 코드 품질**: 해당 없음(GLM 미사용).
- **버그 발견/수정**:
  1. (수정) 직전 실행분의 `OPERATOR_NAME` 로컬 상수 우회 — 단일 소스 원칙 위반. 원복 완료.
  2. (보고) 명세 미인지 테스트 1건 `CustomerChat.gateNotice.test.tsx:87` — allowed_resources 내부이므로 갱신.
  3. (보고, 미수정) 명세 미인지 별개 문구 1곳 `CompositeDesign.tsx:240`.

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

