# Milestone: Nexo 알림/메시지 Smoke 정합성

## 위치

- Roadmap: `agent-roadmap/ROADMAP.md`
- Phase: `agent-roadmap/phase/control-plane-portal-ops/PHASE.md`

## 목표

`../nexo`의 메시징/푸시 알림 검증 상태를 IOP client integration의 선행 게이트로 정리한다. `../nomadcode`에서 `nexo_messaging`을 실제 소비 앱에 적용하고 server-generated signed push smoke까지 완료한 결과를 기준으로, IOP `apps/client`가 같은 Flutter integration skeleton을 복제하기 위해 필요한 설정 차이를 확정한다.

## 상태

[완료]

## 구현 잠금

- 상태: 해제
- 결정 필요: 아래 체크리스트
  - [x] Nexo에서 valid signed push trigger를 제공해 notification display/opened/reply/dismiss까지 검증하는 방향으로 진행한다.
  - [x] IOP client의 Mattermost push routing은 내부 화면, 외부 링크, 운영 이벤트를 모두 지원한다. 남은 작업은 notification type/context별 기본 라우팅, fallback, 이벤트 기록 정책을 정의하는 것이다.

## 범위

- `../nomadcode`의 Mattermost server-generated signed push smoke evidence와 `../nexo/packages/messaging_flutter` host responsibility 확인
- IOP `apps/client`의 `nexo_messaging`, Firebase, Android application id, Google Services plugin, platform guard, plugin initialization 설정 차이 정리
- IOP client의 device token, auth token, signing key, notification opened routing callback 책임 경계 정리
- `Client Integration Clone Adoption`을 시작하기 전 필요한 선행 게이트와 후속 분리 항목 문서화

## 기능

### Epic: [nexo-smoke] Nexo smoke gate

Nexo 쪽 알림/메시지 smoke 상태를 IOP client adoption의 선행 조건으로 분류한다.

- [x] [handoff-status] `../nomadcode/agent-test/local/mattermost-server-generated-push-smoke.md` 기준으로 server-generated signed push smoke의 PASS/N/A 항목을 최신 상태로 확인한다. 검증: 2026-05-30 remote Android emulator에서 FCM receipt, valid signature, notification display, ACK, opened event, channel navigation, inline reply, dismiss, device token prefix PASS를 확인했다.
- [x] [signed-scope] valid signed push trigger를 확보해 notification display, opened routing, inline reply, dismiss까지 검증한 결과를 남긴다. 검증: positive path는 Mattermost REST `POST /api/v4/posts` server-generated DM이며 placeholder signature를 쓰지 않았다.

### Epic: [iop-consumer] IOP consumer 설정 정합성

IOP `apps/client`가 Nexo messaging plugin의 host app responsibility를 충족하는지 확인하고 부족한 설정을 adoption 작업 입력으로 만든다.

- [x] [dependency-gap] IOP `apps/client/pubspec.yaml`과 Android 설정에서 `nexo_messaging`, `firebase_core`, Google Services plugin, Firebase config, application id 차이를 정리한다. 검증: 현재 IOP client에는 해당 의존성과 Firebase Android wiring이 없으므로 clone adoption의 첫 변경 범위로 둔다.
- [x] [bootstrap-gap] Web + Android bootstrap에서 Firebase 초기화, `NexoMessagingPlugin.instance.initialize()`, platform guard, deterministic test escape hatch 필요 여부를 정리한다. 검증: Android는 NomadCode bootstrap 패턴을 이식하고, Web/desktop은 native push runtime을 no-op 또는 guard 처리한다.
- [x] [credential-boundary] device token, auth token, signing key 저장과 전달 책임을 IOP Control Plane/client 경계에 맞춰 정의한다. 검증: host는 auth/signing key/device token handoff만 소유하고 native FCM/ACK/reply/dismiss는 plugin에 둔다.
- [x] [routing-boundary] notification opened event가 내부 화면, 외부 링크, 운영 이벤트를 모두 사용할 수 있도록 notification type/context별 기본 라우팅, fallback, 이벤트 기록 정책을 정리한다. 검증: primary internal route, external link fallback, ops event recording을 adoption 기본 정책으로 둔다.

### Epic: [adoption-gate] Clone adoption handoff

기존 `Client Integration Clone Adoption` Milestone이 시작할 수 있는 입력과 남은 블로커를 추적 가능하게 만든다.

- [x] [clone-input] `Client Integration Clone Adoption`에서 가져갈 Nexo messaging skeleton, IOP 치환 항목, 후속 분리 항목을 checklist로 남긴다. 검증: 복제 대상은 `../nomadcode/apps/client/lib/src/integrations/mattermost/*`, bootstrap pattern, tests, Android Firebase/Google Services wiring이며 NomadCode 제품 화면은 제외한다.
- [x] [lock-sync] 이 Milestone과 `../nexo` `client-validation`의 외부 의존 잠금 상태가 workspace lock에 반영되어 있는지 확인한다. 검증: `../.agent-roadmap-sync/locks.yaml`의 `iop:nexo-notification-message-smoke-alignment` rely-on 상태가 `enable`이다.

## 완료 리뷰

- 상태: 승인됨
- 요청일: 2026-05-30
- 승인일: 2026-05-30
- 완료 근거: `../nomadcode`에서 `nexo_messaging` 적용 후 server-generated signed push smoke의 주요 runtime evidence가 PASS로 정리되었다.
- 완료 근거: IOP client의 dependency/bootstrap/credential/routing gap을 clone adoption 입력으로 분리했다.
- 완료 근거: workspace lock의 선행 의존 상태가 `enable`로 확인되었다.
- 리뷰 필요:
  - [x] 사용자가 완료 결과를 확인했다
  - [x] archive 이동을 승인했다
- 리뷰 코멘트: 사용자가 완료 및 archive 이동을 승인했다. 복제 시작 가능 후보다. 단, IOP 앱 자체의 Firebase config, application id, routing adapter 구현과 Android runtime smoke는 `Client Integration Clone Adoption`에서 별도로 검증한다.

## 범위 제외

- Nexo plugin runtime 대규모 재작성
- IOP client의 전체 제품 UI 재설계
- iOS/macOS native push 구현
- Control Plane-Edge wire protocol 세부 확정
- raw FCM token, auth token, signing key, private endpoint 값을 tracked 문서에 기록하는 일

## 작업 컨텍스트

- 관련 경로: `apps/client/`, `apps/client/android/`, `../nomadcode/apps/client/`, `../nomadcode/agent-test/local/mattermost-server-generated-push-smoke.md`, `../nexo/packages/messaging_flutter/`, `../nexo/apps/flutter-test/`
- 표준선(선택): Nexo `nexo_messaging`은 Android-first plugin runtime이고 host app은 Firebase config, plugin initialization, auth/signing key 저장, device token 전달, opened routing callback만 소유한다.
- 표준선(선택): IOP Web target은 messaging native runtime을 직접 실행하지 않고 platform guard와 no-op 또는 후속 확장 경계를 명확히 둔다.
- 표준선(선택): Mattermost push routing은 내부 화면, 외부 링크, 운영 이벤트를 배타적으로 고르지 않고 모두 지원한다. 구현에서는 type/context별 primary route, fallback route, audit/ops event 기록 여부를 정책으로 분리한다.
- 외부 의존 잠금: `nexo:agent-roadmap/phase/product-foundation/milestones/client-validation.md`
- 선행 작업: NomadCode의 `nexo_messaging` 적용과 server-generated signed push 기반 full notification smoke
- 후속 작업: `Client Integration Clone Adoption`
- 확인 필요: 사용자 완료 확인 후 archive 이동 여부를 결정한다. 구현 후속은 `Client Integration Clone Adoption`에서 IOP target 값으로 검증한다.
