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

# Plan - REVIEW_SMOKE_BUILD

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

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

## 배경

이전 원격 Android debug build는 성공했지만, 원격 checkout에 로컬 repo에 없는 미커밋 `apps/client/android/gradle.properties`와 `apps/client/pubspec.lock` 변경이 있었다. 또한 로컬 modified files가 이전 review의 구현 노트와 범위 판단에 반영되지 않아, 이 build가 현재 branch/patch를 검증했다는 신뢰가 닫히지 않았다. 이 follow-up은 기능 구현을 넓히지 않고 원격 build evidence의 tree equivalence만 복구한다.

## 분석 결과

### 읽은 파일

- `agent-task/m-mattermost-messaging-android-smoke/01_remote_build/plan_cloud_G07_0.log`
- `agent-task/m-mattermost-messaging-android-smoke/01_remote_build/code_review_cloud_G07_0.log`
- `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/android/gradle.properties`
- `apps/client/android/app/build.gradle.kts`
- `apps/client/android/app/src/main/AndroidManifest.xml`
- `apps/client/macos/Flutter/GeneratedPluginRegistrant.swift`
- `apps/client/push-notification-todo.md`
- `apps/client/README.md`
- `apps/client/lib/src/integrations/mattermost/mattermost_push_plugin_client.dart`
- `../nexo/packages/messaging_flutter/pubspec.yaml`
- `../nexo/packages/messaging_flutter/lib/nexo_messaging.dart`
- `../nexo/packages/messaging_flutter/lib/src/nexo_messaging_plugin.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`

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

- 이 follow-up은 새 runtime behavior를 만들지 않는다. Existing Flutter tests cover host integration callbacks, but they cannot prove remote Android SDK tree equivalence.
- Acceptance signal is remote Android build evidence from a clean or fully explained checkout plus local `flutter test` and `flutter analyze --no-fatal-infos`.

### 심볼 참조

- No symbol rename/removal is planned in this follow-up.
- Existing inspected names remain `nexo_messaging`, `NexoMessagingPlugin`, and `NexoFirebaseMessagingService`.

### 분할 판단

Split decision policy was evaluated. This is a single follow-up inside `m-mattermost-messaging-android-smoke/01_remote_build` because both Required findings block the same evidence artifact: a trustworthy remote build record. Splitting would duplicate SSH/tree-state verification and make the final evidence harder to review.

### 범위 결정 근거

Allowed changes are limited to this task's review evidence and, only if proven required by clean remote verification, `apps/client/android/gradle.properties` and `apps/client/pubspec.lock` via normal Flutter tooling. Local changes in `apps/client/macos/Flutter/GeneratedPluginRegistrant.swift` and `apps/client/push-notification-todo.md` must be classified as intended, pre-existing, or out of scope; do not revert unrelated user changes without an explicit user request. Do not implement runtime notification smoke, product UX, iOS/macOS runtime behavior, Mattermost server-side work, or record secrets.

### 빌드 등급

`cloud-G07`: prior review failed verification trust for SSH/Flutter build evidence, and recovery depends on terminal command output, remote checkout state, and stdout/stderr parsing.

## 구현 체크리스트

- [ ] 로컬 modified files와 원격 dirty diff를 수집하고, 각 파일이 intended / generated / pre-existing / out-of-scope 중 무엇인지 secret 없이 기록한다.
- [ ] 원격 Android build를 clean remote worktree 또는 완전히 설명된 equivalent patch에서 재실행하고, pre-build tree state와 post-build diff를 `CODE_REVIEW-cloud-G07.md`에 실제 stdout/stderr로 기록한다.
- [ ] clean remote verification에서 tracked file changes가 build success에 필요하다고 확인되면, 필요한 최소 `apps/client` 변경만 로컬 repo에 반영하고 local/remote 검증을 다시 실행한다.
- [ ] `flutter test`, `flutter analyze --no-fatal-infos`, remote `flutter pub get`, remote `flutter build apk --debug` 결과와 남은 blocker를 `CODE_REVIEW-cloud-G07.md`에 기록한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [REVIEW_SMOKE_BUILD-1] Remote Verification Tree Equivalence

문제: `code_review_cloud_G07_0.log:88` records a dirty remote checkout before the APK build, and review-time inspection found remote-only changes in `apps/client/android/gradle.properties` and `apps/client/pubspec.lock`. Because those changes are not local and not classified, the APK pass does not yet prove the current branch/patch builds.

해결 방법: Start the remote check from a clean temporary worktree, or make the remote tree's dirty diff explicitly equivalent to the local intended patch before building. If `flutter pub get` or the Flutter migrator creates tracked changes that are required for success, apply the same minimal changes locally and record them; otherwise record them as generated post-check output and explain why they are not part of the repo patch.

수정 파일 및 체크리스트:

- [ ] `CODE_REVIEW-cloud-G07.md` records remote pre-build `git rev-parse --short HEAD`, `git status --short`, and relevant diff output.
- [ ] `CODE_REVIEW-cloud-G07.md` records remote post-build `git status --short` and relevant diff output.
- [ ] `apps/client/android/gradle.properties` only if the clean remote verification proves the Flutter migrator flags are required repo state.
- [ ] `apps/client/pubspec.lock` only via `flutter pub get` if the clean remote verification proves lockfile updates are required repo state.

테스트 작성: 새 unit test는 작성하지 않는다. The bug is verification trust, and the acceptance signal is deterministic tree-state evidence plus the Android debug build.

중간 검증:

```bash
ssh toki@toki-labs.com 'set -euo pipefail; cd /Users/toki/jenkins/workspace/nomadcode; git rev-parse --short HEAD; git status --short; git diff -- apps/client/android/gradle.properties apps/client/pubspec.lock'
```

Expected: current active remote checkout state is visible and classified in the review.

### [REVIEW_SMOKE_BUILD-2] Local Diff Scope Reconciliation

문제: `apps/client/macos/Flutter/GeneratedPluginRegistrant.swift:16` and `apps/client/push-notification-todo.md:35` are modified locally, but `code_review_cloud_G07_0.log:64` records only the remote path/PATH deviations. The review artifact must say whether these files are part of this task, generated leftovers from earlier work, or unrelated user changes.

해결 방법: Record the local `git status --short` and file diffs in the review notes. For each local modified file, state whether it is intended for this remote-build task. If a file is unrelated or pre-existing, leave it untouched and do not use it as remote build evidence. If a file is intended, keep it in the `수정 파일 요약` and explain why it belongs in this scope.

수정 파일 및 체크리스트:

- [ ] `CODE_REVIEW-cloud-G07.md` records local `git status --short` and relevant `git diff -- apps/client/macos/Flutter/GeneratedPluginRegistrant.swift apps/client/push-notification-todo.md`.
- [ ] `apps/client/macos/Flutter/GeneratedPluginRegistrant.swift` is either documented as intended generated state or explicitly marked out of scope without being reverted.
- [ ] `apps/client/push-notification-todo.md` is either documented as intended evidence/doc state or explicitly marked out of scope without being reverted.

테스트 작성: 새 test 없음. This item reconciles scope/evidence notes only.

중간 검증:

```bash
git status --short
git diff -- apps/client/macos/Flutter/GeneratedPluginRegistrant.swift apps/client/push-notification-todo.md
```

Expected: every local modified file relevant to this task is classified in `CODE_REVIEW-cloud-G07.md`.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `apps/client/android/gradle.properties` | REVIEW_SMOKE_BUILD-1, only if clean remote verification proves the Flutter migrator flags are required repo state |
| `apps/client/pubspec.lock` | REVIEW_SMOKE_BUILD-1, only via `flutter pub get` if dependency lock updates are required repo state |
| `apps/client/macos/Flutter/GeneratedPluginRegistrant.swift` | REVIEW_SMOKE_BUILD-2, classification only unless explicitly intended |
| `apps/client/push-notification-todo.md` | REVIEW_SMOKE_BUILD-2, classification only unless explicitly intended |
| `agent-task/m-mattermost-messaging-android-smoke/01_remote_build/CODE_REVIEW-cloud-G07.md` | REVIEW_SMOKE_BUILD-1, REVIEW_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 'export PATH="/opt/homebrew/bin:/usr/local/bin:/Users/toki/SDK/flutter/bin:/opt/homebrew/opt/openjdk@11/bin:/Users/toki/SDK:/Users/toki/Library/Android/sdk/platform-tools:$PATH"; set -euo pipefail; base=/Users/toki/jenkins/workspace/nomadcode; tmp=$(mktemp -d /tmp/nomadcode-smoke-clean.XXXXXX); cd "$base"; git worktree add --detach "$tmp/worktree" HEAD; cd "$tmp/worktree"; git rev-parse --short HEAD; git status --short; flutter doctor -v; cd apps/client; flutter pub get; flutter build apk --debug; cd ../..; git status --short; git diff -- apps/client/android/gradle.properties apps/client/pubspec.lock; cd "$base"; git worktree remove "$tmp/worktree"; rmdir "$tmp"'
```

Expected: command starts from a clean temporary worktree, debug APK build completes successfully, and any post-build tracked changes are recorded and classified.

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