---
task_id: task-2991
scope: task
type: ci-watch
status: MERGE_READY → MERGED
watcher: dev2-team (오딘)
pr: 240
created: 2026-08-21
---

# task-2991 CI 감시 및 머지 — PR #240 상담 RLS caller-binding

## S — 상황

ANU 가 프로덕션 DB 에 task-2991 마이그레이션을 **이미 적용**하고 자체 프로브로 차단을 실증한 상태였다.
그러나 PR #240 이 OPEN 으로 남아 **DB 는 새 상태·코드는 옛 상태**로 어긋나 있었다.
ANU 는 `memory/events/task-2991.ci-watch-handoff.json` 로 CI 감시 + 조건부 머지를 dev2 팀에 위임했다
(CI_WATCH_HANDOFF — ANU 직접 CI 대기 금지 규율).

## C — 복잡성

- update-branch 직후라 CI 11 건이 재실행 중이었다 (감시 시작 시점 8 완료 / 3 진행).
- 자동수정 금지·expected_files 밖 변경 시 즉시 ANU 콜백이라는 하드 제약이 걸려 있었다.
- squash 머지이므로 `--is-ancestor <PR head>` 는 항상 ANCESTOR_NO 를 반환한다 → 반영 판정에 쓸 수 없다.

## Q — 질문

CI 11/11 이 실제로 green 인가, 변경 파일이 expected_files 8 개와 **정확히** 일치하는가, 머지가 main 에 실제로 반영되었는가.

## A — 답변 / 조치

CI 11/11 green, 파일 8/8 정확 일치, forbidden_paths 침범 0 건을 확인한 뒤 squash 머지했다.
반영 판정은 ancestor 검사 대신 **blob sha 동일성 8/8** 로 확정했다.

### CI 폴링 경과 (2 분 간격, 실측)

```
10:29:46  poll#1  total=11  pending=[diagnostic, ci, e2e-test]  failed=none
10:31:46  poll#2  total=11  pending=[diagnostic, ci]            failed=none
10:33:47  poll#3  total=11  pending=[ci]                        failed=none
10:35:48  poll#4  total=11  pending=none                        failed=none  → ALL_PASS
```

11 건 전량 `success`: cancel-kill-switch, ci, ci/guard, diagnostic, e2e-test,
gemini-review-gate, guard, hidden-path-audit, lock-in-check, merge-safety-check, qc-check.

ruleset 필수 체크는 8 건(cancel-kill-switch, qc-check, hidden-path-audit, lock-in-check,
merge-safety-check, gemini-review-gate, ci/guard, guard)이며 조기 머지가 가능했으나,
위임 명세가 "전부 pass"를 요구하므로 ci·diagnostic·e2e-test 까지 대기 후 머지했다.

### 머지 결과

- 머지 전 상태: `state=open`, `mergeable=true`, `mergeable_state=clean`, head `bc9b04c6` (감시 내내 불변)
- 명령: `gh api -X PUT repos/Jeon-Jonghyuk/InsuRo/pulls/240/merge -f merge_method=squash -f sha=bc9b04c688cc...`
- 결과: `{"merged": true}` — squash commit `44af8ff6299f925b8fc1e31993479f74dd3fa522`
- `origin/main` HEAD == `44af8ff6` (일치)
- squash commit 변경 파일 = 정확히 8 개 (added 6 / modified 2), 초과 0

★ `merged_by` 가 `JonghyukJeon` 으로 찍히나 이는 **owner PAT 사용에 따른 표기**이며 회장 직접 머지가 아니다.
실행 주체는 dev2 팀(오딘) 이다.

### 수정 파일별 검증 상태

| 파일 | 변경 | 명세 일치 | blob sha (head→main) | 상태 |
|---|---|---|---|---|
| src/pages/CustomerChat.tsx | +123/-129 | 일치 | df1a86423566 → df1a86423566 | verified |
| src/pages/__tests__/CustomerChat.gateNotice.test.tsx | +23/-31 | 일치 | 9be71eb58432 → 9be71eb58432 | verified |
| supabase/migrations/20260820T000000_task2991_caller_binding_ROLLBACK.sql | +105/-0 | 일치 | c82aec64c422 → c82aec64c422 | verified |
| supabase/migrations/20260820T000001_task2991_caller_binding.sql | +328/-0 | 일치 | a5ee2eff27ff → a5ee2eff27ff | verified |
| supabase/migrations/_backup/task-2991_pg_policies_before.json | +2174/-0 | 일치 | 5144ba957d5c → 5144ba957d5c | verified |
| supabase/migrations/_backup/task-2991_pg_policies_before.md | +75/-0 | 일치 | 326fda7062ca → 326fda7062ca | verified |
| tests/CustomerChat.test.tsx | +228/-0 | 일치 | f3f4f248a885 → f3f4f248a885 | verified |
| tests/security/task_2991_rls_probe.py | +144/-0 | 일치 | 346118b757df → 346118b757df | verified |

blob 대조는 40-hex 유효성을 선검사하여 **404==404 거짓 PASS 를 배제**했다. 8/8 전량 유효 hex 이며 동일하다.

### 범위 준수

- expected_files 8 개 ↔ 실제 변경 8 개: MISSING 0, EXTRA 0, 정확 일치
- forbidden_paths(`server/**`, `ops/**`, `scripts/deploy/**`, `.github/**`) 매칭: 0 건
- 코드 수정 0 줄, 자동수정 0 건, 위임 범위 밖 PR 머지 0 건

## 근본 원인 (Why)

- **1st Why**: 왜 감시가 필요했나 → PR #240 이 OPEN 인 채 DB 만 선행 적용되어 코드-DB 가 어긋났다.
- **2nd Why**: 왜 DB 가 선행됐나 → 보안 결함(익명 무제한 접근) 차단이 급해 DDL 을 먼저 적용하고 실증했다.
- **3rd Why**: 왜 머지가 늦었나 → scope-guard FAIL 1 건(`CustomerChat.gateNotice.test.tsx` 가 명세 `paths` 누락)이 걸렸고,
  이는 봇 잘못이 아닌 **ANU 명세 결함**으로 판정되어 override(`task-2991.scope-override.json`) 후 해소되었다.
  co-located 테스트를 명세 glob 이 덮지 못한 전형적 사례다.

## 소요

- 감시 시작 2026-08-21 10:29:12 KST → 머지 완료 10:36:04 KST
- 실소요 약 7 분 (상한 40 분, LOOP_BOUNDARY 미도달)

## 종단 상태

**MERGE_READY → MERGED** (terminal_states 중 MERGE_READY 경로)

## 잔여 / ANU 확인 필요

1. **프로덕션 배포 미확인** — main 머지는 끝났으나 InsuRo 프론트 빌드·배포는 이 위임 범위 밖이다.
   `CustomerChat.tsx` 가 RPC 경로로 바뀌었으므로 **배포 전까지 라이브 프론트는 여전히 옛 직접 테이블 접근 코드**다.
   (상담 기능 4 개월 미사용이라 즉각적 사용자 영향은 없을 것으로 보이나, 배포 여부는 ANU 판단 사항)
2. 롤백 SQL 이 함께 머지되었으나 실행되지 않았다 — 의도된 상태로 이해했다.
