## Verdict
**ITERATE**

## Claim Checks
- 대상 확인: `index.jsonl`의 Revision 5 경로와 SHA-256이 요청값 `c1604876d6557b18759cfb6bf3d66d369a6da3fdbfa07ad63b99b6061663bb6c`와 일치한다. Revision 4와 5를 함께 검토했으며 Architect 산출물은 사용하지 않았다.
- 프런트엔드 경로 보정은 정확하다. 실제 `web/vite.config.ts`는 `outDir: "../hermes_cli/web_dist"`이고, `hermes_cli/main.py` 및 `hermes_cli/web_server.py`도 `hermes_cli/web_dist`를 빌드·서빙한다. Revision 4의 `web/dist`는 Revision 5가 올바르게 폐기한다.
- 서비스 소유권 보정도 필요하고 타당하다. 실제 `hermes dashboard --stop`은 `hermes_cli/main.py`에서 모든 dashboard 프로세스를 스캔해 종료하므로, 이를 금지하고 `physique-coach-dashboard.service`만 조작하는 Revision 5가 격리 원칙과 맞는다. `--isolated` 플래그는 실제 `hermes_cli/subcommands/dashboard.py`와 실행 경로에 존재한다.
- 쿠키 보정은 원칙상 맞다. loopback 평문 HTTP에서 bare cookie + HttpOnly + SameSite=Strict + Path=/ + Domain 없음으로 정한 것은 Revision 4의 `__Host-` 이름/`Secure` 불일치를 제거한다.
- 프로필 루트 보정은 구현 경계가 명확하다. 기존 Hermes는 `HERMES_HOME`을 런타임 루트로 사용하므로 config 값을 allowlist 비교값으로만 쓰는 계약은 기존 구조와 맞는다.
- 대표 작업 1(서비스 + probe)을 실제 코드에 대입하면 아직 막힌다. 현재 dashboard unit은 존재하지 않아 새로 만드는 것이 예정상 정상이나, Revision 4의 정확한 unit에는 `HERMES_DASHBOARD_SESSION_TOKEN` 또는 token-file 설정이 없다. 실제 `web_server.py`는 해당 환경변수가 없으면 프로세스 내부에서 임의 토큰을 생성한다. Revision 5는 probe가 systemd 환경 또는 unit이 만든 0600 파일에서 토큰을 얻는다고만 하고, 어느 방식을 선택하는지, unit이 어떻게 같은 토큰을 서버에 전달하는지, 파일 경로·생성·회전·삭제가 무엇인지 정하지 않았다. 현 계약대로 unit과 probe를 구현하면 probe가 서버의 임의 토큰을 알 수 없다.
- 대표 작업 2(플래그-off 배포 후 health)를 시뮬레이션하면 순서가 모순된다. Revision 4는 `dashboard.physique_coach_approval_console=false`를 명시하고 bootstrap이 feature flag를 요구한다. Revision 5는 서비스들을 “flags off”로 재시작한 직후 bootstrap 기반 live probe를 필수화한다. worker flag까지 꺼진 의미라면 `<10s` heartbeat 조건도 충족할 수 없다. 어떤 플래그가 off이고 어떤 readiness 경로가 on인지 실행자가 추측해야 한다.
- 대표 작업 3(브라우저/외부 E2E)를 시뮬레이션하면 검증 ledger가 불완전하다. `web/package.json`에는 Vitest만 있고 Playwright test 의존성·script가 없으며, Hermes Python dev extra에도 Playwright가 없다. 저장소에서 이 테스트를 실행할 별도 Playwright 설정/명령도 찾지 못했다. 따라서 Revision 5가 요구한 실제 브라우저 cookie 지속·회전·idle expiry·replay 검증은 현재의 exact commands 어디에서도 실행되지 않는다.
- real-Telegram 격리 방향은 맞다. 현재 `pyproject.toml`은 `integration`만 등록하고 기본 `addopts`도 `not integration`이므로 `e2e` 등록과 기본 제외 변경이 실제로 필요하다. 다만 전용 자격 증명 변수명, production/customer 식별자와의 비교 기준, 명시 실행 시 자격 증명 누락을 skip이 아닌 실패로 다루는 기준은 아직 없다.
- 새로 계획된 `tests/e2e/test_physique_coach_pilot.py`, `tests/gateway/test_customer_outbound_worker.py`, `tests/hermes_cli/test_physique_coach_routes.py`, profile privacy/delivery/decision/pilot 테스트, probe script 및 dashboard unit은 현재 없음을 확인했다. 계획이 생성 대상으로 명시하므로 부재 자체는 결함이 아니지만, 위 검증 접합부는 파일 생성만으로 결정되지 않는다.

## Missing Evidence
- **확실히 누락:** dashboard launch bearer의 단일 선택된 provisioning 계약. unit delta, 정확한 runtime path/env, 원자적 0600 생성, 서버와 probe의 동일 토큰 사용, 프로세스 재시작별 회전, stale 파일 제거, 종료 시 삭제가 없다.
- **확실히 누락:** 기존 전역 API auth middleware와 새 console session의 조합. 현재 `/api/*`는 launch token middleware를 통과해야 하므로, health 요청에도 launch header를 유지할지 또는 새 console 경로만 좁게 예외 처리할지 명시해야 한다.
- **확실히 모순:** console bootstrap/worker heartbeat가 필요한 live probe와 “flags off” 상태. 현재 순서대로는 gate를 통과할 수 없다.
- **확실히 누락:** 실제 브라우저 테스트의 파일 경로, 의존성/lockfile 변경, 서버 대상, 실행 명령과 ledger 편입.
- **얇음:** real-Telegram preflight의 구체적 자격 증명/식별자 계약과 명시 실행 실패 조건.

## Approval Boundary
Revision 5의 bare loopback cookie, named-unit-only lifecycle, `hermes_cli/web_dist`, `HERMES_HOME` canonical ownership은 다음 수정의 고정 제약으로 사용할 수 있다. 그러나 서비스 설치/재시작, probe gate, browser/Telegram E2E 및 고객 활성화를 포함한 구현 실행은 승인되지 않는다. 위 접합부를 닫은 단일 실행 계약이 필요하다.

## Summary
- Clarity: 핵심 보정은 명확하지만 token source와 flag 의미는 선택되지 않았다.
- Verifiability: pytest/빌드/rehearsal 명령은 크게 좋아졌으나 browser gate가 실행 명령에 연결되지 않았다.
- Completeness: 배포 직전 auth와 readiness 접합부가 아직 닫히지 않았다.
- Big Picture: 사람 승인, 단일 메시지, 고객 분리, fail-closed 원칙과 일치한다.
- Principle/Option Consistency: named-unit 격리는 일관되나 flags-off와 bootstrap/heartbeat 요구가 충돌한다.
- Alternatives Depth: launch bearer에 systemd environment 또는 token file 두 선택지를 남겨 실행자가 보안·수명주기를 결정해야 한다.
- Risk/Verification Rigor: 외부 E2E 격리와 exact rehearsal은 강하지만 실제 브라우저와 token lifecycle 검증은 아직 비실행 상태다.

## Required Changes
1. launch bearer 방식을 하나로 선택하고 exact unit 계약을 추가한다: 환경변수/파일의 정확한 이름과 경로, 생성 주체, 원자적 mode 0600, 서버 주입, probe 읽기, 매 프로세스 시작 회전, stale/stop cleanup, redaction을 명시한다. bootstrap 이후 health에 기존 launch header도 보낼지, 아니면 console 경로에 한정한 middleware 인증을 추가할지도 고정한다.
2. rollout 플래그를 이름별로 열거하고 순서를 수정한다. 고객 outbound/registry 활성화는 off로 유지하되 bootstrap과 heartbeat readiness가 실제로 동작하는 상태를 정의하거나, 별도 flag-independent readiness endpoint를 설계한다. probe 성공 뒤 test customer와 real pilot을 각각 어떤 receipt로 활성화하는지 연결한다.
3. 실제 브라우저 검증을 실행 가능한 gate로 만든다: 테스트 파일, Playwright 선택(Python 또는 Node 중 하나), manifest/lockfile 변경, 대상 서버의 시작·종료/격리 방식, persistence·rotation·idle expiry·old-cookie/CSRF replay 기대값, 정확한 명령을 ledger에 추가한다. 의존성/브라우저가 없으면 통과나 skip이 아니라 rollout 차단이어야 한다.
4. real-Telegram E2E 계약을 구체화한다: 전용 env 변수명, 허용 test chat/topic 기준, profile production token 및 registry 고객 식별자와의 fail-closed 비교, 기본 suite의 `not e2e` 설정, 명시 `-m e2e` 실행에서 자격 증명 누락/production 일치 시 hard failure를 명시한다.
