<!-- task=m-mattermost-messaging-android-smoke/01_remote_build plan=0 tag=SMOKE_BUILD -->

# Plan - SMOKE_BUILD

## 이 파일을 읽는 구현 에이전트에게

`CODE_REVIEW-cloud-G07.md`의 구현 에이전트 소유 섹션 작성까지가 구현의 일부다. 검증 명령을 실행하고 실제 출력, 변경 사항, 판단을 review stub에 채운 뒤 active 파일을 그대로 두고 리뷰 준비를 보고한다. 최종 archive, `complete.log`, PASS/WARN/FAIL 판정은 code-review skill 전용이다.

## 배경

Mattermost messaging Android smoke Milestone에서 작은 scope-check는 처리되어 host 앱이 `../nexo/packages/messaging_flutter`의 현재 `nexo_messaging` API를 보도록 정리되었다. 남은 첫 환경 의존 작업은 원격 Android SDK runner에서 실제 Gradle/Flutter Android debug build가 통과하는지 확인하는 것이다. 이 단계가 통과해야 device/emulator runtime notification smoke를 신뢰할 수 있다.

## 분석 결과

### 읽은 파일

- `agent-ops/roadmap/current.md`
- `agent-ops/roadmap/phase/external-integration/PHASE.md`
- `agent-ops/roadmap/phase/external-integration/milestones/mattermost-messaging-android-smoke.md`
- `docs/test-environments.md`
- `apps/client/pubspec.yaml`
- `apps/client/pubspec.lock`
- `apps/client/README.md`
- `apps/client/push-notification-todo.md`
- `apps/client/lib/src/app/bootstrap.dart`
- `apps/client/lib/src/app/nomadcode_client_app.dart`
- `apps/client/lib/src/integrations/mattermost/mattermost_push_client.dart`
- `apps/client/lib/src/integrations/mattermost/mattermost_push_plugin_client.dart`
- `apps/client/lib/src/integrations/mattermost/mattermost_push_host_integration.dart`
- `apps/client/lib/src/integrations/mattermost/mattermost_auth_service.dart`
- `apps/client/test/integrations/mattermost_push_host_integration_test.dart`
- `apps/client/android/app/build.gradle.kts`
- `apps/client/android/app/src/main/AndroidManifest.xml`
- `../nexo/packages/messaging_flutter/pubspec.yaml`
- `../nexo/packages/messaging_flutter/README.md`
- `../nexo/packages/messaging_flutter/lib/nexo_messaging.dart`
- `../nexo/packages/messaging_flutter/lib/src/nexo_messaging_plugin.dart`
- `../nexo/packages/messaging_flutter/lib/src/notification_opened_event.dart`
- `../nexo/packages/messaging_flutter/lib/src/push_notification_type.dart`
- `../nexo/packages/messaging_flutter/android/src/main/AndroidManifest.xml`
- `../nexo/packages/messaging_flutter/android/src/main/kotlin/com/tokilabs/nexo/messaging/NexoMessagingPlugin.kt`
- `../nexo/packages/messaging_flutter/android/src/main/kotlin/com/tokilabs/nexo/messaging/NexoFirebaseMessagingService.kt`
- `../nexo/packages/messaging_flutter/test/nexo_messaging_test.dart`

### 테스트 커버리지 공백

- Local `flutter test` covers host integration initialization, navigation callback assignment, and notification stream forwarding.
- Local `flutter analyze --no-fatal-infos` catches Dart import/type regressions; current remaining findings are existing `avoid_print` infos in `mattermost_auth_service.dart`.
- Existing tests do not cover Android Gradle plugin registration, Firebase Android config wiring, native manifest merge, or remote SDK availability. This plan closes the Android build gap only.
- This plan does not prove real FCM delivery or notification arrival; that is split into `02+01_runtime_notification_smoke`.

### 심볼 참조

- Naming refactor is complete in the plugin package: the Dart package is `nexo_messaging`, the Flutter-facing singleton is `NexoMessagingPlugin`, Android plugin metadata points at `com.tokilabs.nexo.messaging.NexoMessagingPlugin`, and the FCM service is `com.tokilabs.nexo.messaging.NexoFirebaseMessagingService`.
- Current remaining host-side `MattermostPushClient`, `MattermostPushPluginClient`, `MattermostPushHostIntegration`, and `MattermostAuthService` names are intentional Mattermost integration boundary names. Do not treat those host adapter names as stale unless a separate host-boundary rename is requested.
- Any remote build evidence recorded before the completed naming refactor is stale. Re-run `flutter pub get`, `flutter test`, `flutter analyze --no-fatal-infos`, and the remote Android debug build against the latest checkout before marking this task ready for review.

### 분할 판단

Split decision policy was evaluated before writing plan files. Shared task group: `m-mattermost-messaging-android-smoke`.

- `01_remote_build`: no predecessor; validates remote Android SDK build.
- `02+01_runtime_notification_smoke`: depends on `01_remote_build`; requires device/emulator and Mattermost/FCM trigger environment.

The split is required because remote build failure can be reviewed independently before runtime notification work starts.

### 범위 결정 근거

This task may only touch `apps/client` build/config/doc files and the Milestone evidence if the remote build exposes a build regression. It must not implement product UX, iOS/macOS runtime behavior, Mattermost server-side plugin work, Plane/Jira/Agent Integrator adapters, or record secrets. If the remote host lacks the requested SDK/checkout, record an environment blocker instead of broadening scope.

### 빌드 등급

`cloud-G07`: the work is terminal/SSH build verification with external Android SDK state and possible long-running build diagnosis.

## 구현 체크리스트

- [ ] 원격 Android SDK runner checkout이 이 작업의 branch/commit 또는 동등한 patch를 포함하는지 확인하고, 동기화 방법을 secret 없이 기록한다.
- [ ] `docs/test-environments.md#android-sdk-remote-runner` 기준 environment check를 실행한다.
- [ ] 원격 `apps/client`에서 `flutter pub get`과 `flutter build apk --debug`를 실행한다. 실패가 `apps/client`의 build/config regression이면 이 plan 범위 안에서 최소 수정하고 재검증한다.
- [ ] 원격 build 결과와 남은 blocker를 `CODE_REVIEW-cloud-G07.md`에 실제 stdout/stderr로 기록한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [SMOKE_BUILD-1] Remote Android SDK Preflight

문제: Milestone은 원격 Android SDK runner build를 요구한다. `docs/test-environments.md:5`-`48`은 `toki@toki-labs.com`, Android SDK env check, `flutter build apk --debug` 기준을 정의한다.

해결 방법: remote checkout 위치, commit/patch 상태, Flutter/Android SDK 상태를 먼저 확인한다. `/config/workspace/nomadcode`가 없으면 `docs/test-environments.md:15`-`21`에 따라 active checkout을 찾고, 대체 경로와 이유를 review에 기록한다.

수정 파일 및 체크리스트:

- [ ] 소스 수정 없음.
- [ ] `CODE_REVIEW-cloud-G07.md`에 remote path, commit/patch 기준, SDK 상태를 기록한다.

테스트 작성: 새 테스트 없음. 이 항목은 원격 환경 preflight이며 existing unit test로 대체할 수 없다.

중간 검증:

```bash
ssh toki@toki-labs.com 'set -euo pipefail; cd /config/workspace/nomadcode; pwd; git rev-parse --short HEAD; git status --short; flutter doctor -v; echo "ANDROID_HOME=${ANDROID_HOME:-}"; echo "ANDROID_SDK_ROOT=${ANDROID_SDK_ROOT:-}"; flutter devices'
```

Expected: command completes, Flutter doctor reports Android toolchain, and no secret values are printed.

### [SMOKE_BUILD-2] Debug APK Build

문제: `agent-ops/roadmap/phase/external-integration/milestones/mattermost-messaging-android-smoke.md:36` requires remote `flutter pub get` and `flutter build apk --debug`. Local tests cannot validate Android Gradle/plugin registration. The current naming baseline must resolve `nexo_messaging` to `NexoMessagingPlugin` and `NexoFirebaseMessagingService`, not the pre-refactor package/class names.

해결 방법: run the Android build on the remote runner. If the build fails because of the app/package integration, fix the minimum file in `apps/client` and rerun local `flutter test`, local `flutter analyze --no-fatal-infos`, and remote build.

수정 파일 및 체크리스트:

- [ ] `apps/client/pubspec.yaml` only if dependency/build config needs a minimal correction.
- [ ] `apps/client/pubspec.lock` only via `flutter pub get`.
- [ ] `apps/client/lib/src/integrations/mattermost/mattermost_push_plugin_client.dart` only if the package API mismatch still breaks compilation.
- [ ] `../nexo/packages/messaging_flutter/pubspec.yaml` only if plugin metadata still points at stale Android package/class names.
- [ ] `../nexo/packages/messaging_flutter/android/src/main/**` only if native service or plugin class names still prevent Android registration.
- [ ] `apps/client/README.md` or `apps/client/push-notification-todo.md` only if evidence/instructions need a narrow correction.
- [ ] `CODE_REVIEW-cloud-G07.md` records actual build stdout/stderr or saved output path.

테스트 작성: 새 unit test는 작성하지 않는다. The acceptance signal is Android SDK build output; local tests were already used for Dart-level regression.

중간 검증:

```bash
ssh toki@toki-labs.com 'set -euo pipefail; cd /config/workspace/nomadcode/apps/client; flutter pub get; flutter build apk --debug'
```

Expected: debug APK build completes successfully.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `apps/client/pubspec.yaml` | SMOKE_BUILD-2, only if needed |
| `apps/client/pubspec.lock` | SMOKE_BUILD-2, only if needed |
| `apps/client/lib/src/integrations/mattermost/mattermost_push_plugin_client.dart` | SMOKE_BUILD-2, only if needed |
| `../nexo/packages/messaging_flutter/pubspec.yaml` | SMOKE_BUILD-2, only if stale plugin metadata remains |
| `../nexo/packages/messaging_flutter/android/src/main/**` | SMOKE_BUILD-2, only if stale native registration remains |
| `apps/client/README.md` | SMOKE_BUILD-2, only if needed |
| `apps/client/push-notification-todo.md` | SMOKE_BUILD-2, only if needed |
| `agent-task/m-mattermost-messaging-android-smoke/01_remote_build/CODE_REVIEW-cloud-G07.md` | SMOKE_BUILD-1, SMOKE_BUILD-2 |

## 최종 검증

```bash
cd apps/client
flutter test
flutter analyze --no-fatal-infos
```

Expected: tests pass; analyze exits successfully, with only existing `avoid_print` infos allowed.

```bash
ssh toki@toki-labs.com 'set -euo pipefail; cd /config/workspace/nomadcode/apps/client; flutter pub get; flutter build apk --debug'
```

Expected: debug APK build completes successfully on the Android SDK remote runner.

모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.
