update docs and roadmap files, remove outdated docs

This commit is contained in:
toki 2026-05-30 06:59:08 +09:00
parent 79c9747d88
commit 55e0139cca
6 changed files with 8 additions and 255 deletions

View file

@ -86,6 +86,7 @@ flutter run
| `docs/` | 아키텍처와 운영 문서입니다. |
| `bin/` | root test, lint, build, dev helper 명령입니다. |
| `agent-ops/` | AI 에이전트 규칙, 도메인 라우팅, 로드맵, 반복 작업 skill입니다. |
| `agent-test/local/` | local 테스트 profile과 runner별 검증 규칙입니다. |
## 작업 맥락
@ -125,9 +126,9 @@ IOP 경계가 걸린 작업은 같은 workspace에 sibling IOP repository가 있
| Core | `WORKFLOW_TASK_TIMEOUT_SEC` | 선택 | workflow task timeout 기본값을 조정합니다. |
| Core | `MATTERMOST_BASE_URL`, `MATTERMOST_TOKEN` | 선택 | Mattermost adapter 연동용 설정입니다. |
| Core | `PLANE_BASE_URL`, `PLANE_TOKEN` | 선택 | Plane work item 조회, comment, state update 연동용 설정입니다. token 값은 문서에 기록하지 않습니다. |
## 참고 문서
- `docs/monorepo.md`
- `services/core/README.md`
- `apps/client/README.md`
- `packages/contracts/README.md`

View file

@ -36,7 +36,6 @@ NomadCode 원레포 운영 도메인이다. 루트 helper, 문서, ignore 정책
- `bin/lint` — vet/check/analyze entrypoint.
- `bin/build` — build entrypoint.
- `bin/dev` — development entrypoint 안내.
- `docs/monorepo.md` — monorepo layout 설명.
- `AGENTS.md`, `CLAUDE.md`, `GEMINI.md` — agent별 루트 진입 규칙.
- `agent-test/local/rules.md` — local 테스트 환경 routing과 private input 사용 경계.
- `agent-ops/rules/project/rules.md` — 프로젝트 전체 agent routing.
@ -50,7 +49,7 @@ NomadCode 원레포 운영 도메인이다. 루트 helper, 문서, ignore 정책
- 공통 agent-ops 영역과 프로젝트 특화 영역을 섞지 않는다.
- roadmap은 `agent-roadmap/`에 두고, 서비스별 README에 Phase 계획을 중복 유지하지 않는다.
- `.gitignore`에는 private rules와 local-only `agent-test/local/`, `agent-test/runs/`만 제외하고, `agent-task/archive/**`는 AI ignore/permission 파일에서 제어한다.
- 원레포 구조 변경은 README와 docs를 함께 갱신한다.
- 원레포 구조 설명은 README를 기준으로 갱신하고, 별도 운영/아키텍처 세부가 있을 때만 docs에 분리한다.
## 다른 도메인과의 경계

View file

@ -39,7 +39,7 @@ Work Item Provider Pipeline Design과 workflow core 이후 남은 Plane/Jira 확
- [ ] [plane-adapter-expand] Plane issue 생성, comment, status update adapter 확장. 검증: core가 Plane에 issue, comment, status update를 요청할 수 있다.
- [ ] [jira-adapter] Jira issue 조회, comment, status transition adapter 구현. 검증: core가 Jira에 issue 조회, comment, status transition을 요청할 수 있다.
- [ ] [mattermost-adapter] Mattermost 메시지 발송 adapter 구현과 `../nexo/packages/messaging_flutter` host notification boundary 정합성 유지. 검증: core가 Mattermost에 메시지를 발송하고, server-generated signed push smoke가 `docs/test-environments.md` 기준으로 FCM/ACK/opened/reply/dismiss evidence를 남긴다.
- [ ] [mattermost-adapter] Mattermost 메시지 발송 adapter 구현과 `../nexo/packages/messaging_flutter` host notification boundary 정합성 유지. 검증: core가 Mattermost에 메시지를 발송하고, server-generated signed push smoke가 `agent-test/local/mattermost-server-generated-push-smoke.md` 기준으로 FCM/ACK/opened/reply/dismiss evidence를 남긴다.
- [ ] [agent-integrator] Agent Integrator 호출 경계 정의. 검증: Agent Integrator 또는 그 대체 연결 지점이 명확히 정의되어 있다.
- [x] [iop-responses] IOP OpenAI API Responses-compatible 경로를 NomadCode의 기본 실행 호출 경로로 정리. 검증: IOP OpenAI API Responses-compatible 호출 경로가 core workflow와 연결된다.
- [x] [model-reclass] direct model endpoint / Ollama fallback 표현과 설정을 IOP 경유 호출 기준으로 재분류. 검증: NomadCode의 기본 실행 경로가 직접 모델 호출이 아니라 IOP 경유 호출임이 로드맵과 운영 문서에서 일관되게 읽힌다.
@ -71,7 +71,7 @@ Work Item Provider Pipeline Design과 workflow core 이후 남은 Plane/Jira 확
- 주요 작업 영역: `services/core/internal/adapters/`, `services/core/internal/scheduler/`, `services/core/internal/workflow/`
- 선행 작업: Work Item Provider Pipeline Design, Workflow Core, Mattermost Nexo Messaging Alignment
- 후속 작업: Project Workspace Management UX
- Mattermost signed push smoke 재현 가이드: `docs/test-environments.md#mattermost-server-generated-push-smoke`
- Mattermost signed push smoke 재현 가이드: `agent-test/local/mattermost-server-generated-push-smoke.md`
- private 환경값 router: `agent-test/local/mattermost-server-generated-push-smoke.md` (ignored local file)
- Mattermost 책임 경계: core는 Mattermost REST 메시지 발송과 task notification 발행을 담당하고, `../nexo/packages/messaging_flutter`는 client-side FCM 수신, signature 검증, ACK, notification display, opened-routing, inline reply, dismiss를 담당한다.
- Nexo host 정합성: NomadCode host는 Firebase 설정, Mattermost credential handoff, signing key, optional server identifier, navigation callback만 `MattermostPushClient` 경계로 전달한다. native push 처리 로직은 `apps/client/android`에 복제하지 않는다.

View file

@ -32,8 +32,8 @@
현재 작업보다 먼저 Mattermost messaging/notification 경계를 nexo-owned package 기준으로 정렬한다.
- [x] [host-identifier] NomadCode host가 optional Mattermost server identifier를 `MattermostPushClient``nexo_messaging``setAuthToken(..., identifier:)` 경계로 전달한다. 검증: `cd apps/client && flutter test`.
- [x] [docs-boundary] `docs/test-environments.md`, `apps/client/push-notification-todo.md`, contracts note, External Integration context가 nexo package의 Android-first/stub-platform 상태와 server-generated signed push smoke 기준을 일관되게 설명한다. 검증: 문서에서 raw token/password/signing key/FCM token 값을 기록하지 않는다.
- [ ] [signed-smoke-refresh] 실제 Android runner에서 server-generated signed push smoke를 재실행해 FCM receipt, valid signature, ACK, notification display, opened event, inline reply, dismiss evidence를 redaction 상태로 남긴다. 검증: `docs/test-environments.md#mattermost-server-generated-push-smoke`의 Evidence Checklist가 PASS/PARTIAL/BLOCKED로 기록된다.
- [x] [docs-boundary] `agent-test/local/mattermost-server-generated-push-smoke.md`, `apps/client/push-notification-todo.md`, contracts note, External Integration context가 nexo package의 Android-first/stub-platform 상태와 server-generated signed push smoke 기준을 일관되게 설명한다. 검증: 문서에서 raw token/password/signing key/FCM token 값을 기록하지 않는다.
- [ ] [signed-smoke-refresh] 실제 Android runner에서 server-generated signed push smoke를 재실행해 FCM receipt, valid signature, ACK, notification display, opened event, inline reply, dismiss evidence를 redaction 상태로 남긴다. 검증: `agent-test/local/mattermost-server-generated-push-smoke.md`의 Evidence Checklist가 PASS/PARTIAL/BLOCKED로 기록된다.
## 완료 리뷰
@ -55,7 +55,7 @@
## 작업 컨텍스트
- 관련 경로: `apps/client/lib/src/integrations/mattermost/`, `apps/client/push-notification-todo.md`, `docs/test-environments.md`, `packages/contracts/notes/flutter-core-api-candidates.md`, `../nexo/packages/messaging_flutter`
- 관련 경로: `apps/client/lib/src/integrations/mattermost/`, `apps/client/push-notification-todo.md`, `agent-test/local/mattermost-server-generated-push-smoke.md`, `packages/contracts/notes/flutter-core-api-candidates.md`, `../nexo/packages/messaging_flutter`
- 표준선(선택): `../nexo/packages/messaging_flutter`는 Android-first client-side messaging/notification SDK이고, NomadCode host는 Firebase 설정, credential handoff, signing key, optional server identifier, navigation callback만 전달한다.
- 선행 작업: Mattermost Messaging Android Smoke
- 후속 작업: Workflow Core 재개, External Integration의 `[mattermost-adapter]` 구현

View file

@ -1,12 +0,0 @@
# Monorepo Layout
The workspace is organized by runtime boundary rather than by task.
- `services/core` owns orchestration, persistence, scheduling, and external model/service adapters.
- `apps/client` owns the Flutter-first product UI across mobile, desktop, and optional web targets.
- `apps/web` was the previous React/Vite console scaffold, which has been removed as part of the Flutter-first client consolidation.
- `packages/contracts` owns schemas shared across clients and services.
- `agent-ops` owns root agent routing, domain rules, and repeatable task workflows.
- `docs/test-environments.md` records shared verification environments such as the remote Android SDK runner.
Keep feature work scoped by domain, but land cross-boundary changes in one branch when API contracts, generated clients, and UI behavior must move together.

View file

@ -1,235 +0,0 @@
# Shared Test Environments
NomadCode milestones can reference this document when a verification step needs a shared machine or platform SDK that is not expected to exist in every agent workspace.
## Android SDK Remote Runner
Use the Toki Labs host for Android SDK dependent checks.
### Access
```bash
ssh toki@toki-labs.com
```
After connecting, use the NomadCode checkout prepared on that host. If the checkout is under the same workspace convention as local agent workspaces, start here:
```bash
cd /config/workspace/nomadcode
```
If that path is absent, use the active NomadCode checkout on the host and make sure it is on the branch or commit that contains the change being verified.
### Environment Check
Run these before Android-specific verification:
```bash
flutter doctor -v
echo "$ANDROID_HOME"
echo "$ANDROID_SDK_ROOT"
flutter devices
```
`flutter doctor -v` should show an Android toolchain with an installed SDK. `flutter devices` is allowed to show no physical device when the check only needs a build. A device or emulator is required only for an interactive smoke run.
### Standard Checks
For Android SDK dependent client milestones, run from the Flutter host:
```bash
cd apps/client
flutter pub get
flutter build apk --debug
```
`flutter build apk --debug` is the default Android SDK validation for roadmap completion when no device smoke is explicitly required. It verifies Gradle, Android SDK, plugin registration, Firebase Android config wiring, and Dart bootstrap compilation for Android.
Generic Dart/widget checks such as `flutter test` and `flutter analyze --no-fatal-infos` may be run locally or on the remote host when the milestone explicitly asks for them. Do not treat the remote host as the source of truth for non-Android SDK checks unless its Flutter SDK version is part of the milestone evidence.
### Optional Device Smoke
Run this only when the milestone asks for an Android runtime smoke or notification/device behavior:
```bash
cd apps/client
flutter devices
flutter run -d <device-id>
```
For Mattermost push work, confirm the app boots, Firebase initialization does not crash, and notification navigation callbacks remain observable. Do not record tokens, credentials, signing keys, or private server values in roadmap or docs.
## Mattermost Server-Generated Push Smoke
Use this when NomadCode needs to reproduce the same signed FCM path that was verified from the sibling `../nexo` messaging plugin environment.
### Roadmap Target
The current matching roadmap target is:
- Phase: `agent-roadmap/phase/external-integration/PHASE.md`
- Milestone: `agent-roadmap/phase/external-integration/milestones/external-integration.md`
- Task fit: `[mattermost-adapter]` and Mattermost notification evidence for external integration validation.
### Private Inputs
Before running this smoke, read `agent-test/local/rules.md` and the routed local Mattermost smoke rule. Use the local-only secret file referenced there. Do not print or commit raw bot tokens, passwords, FCM tokens, signing keys, or push signatures.
Create the ignored credential asset used by `apps/client`:
```json
{
"serverUrl": "<mattermost-base-url-from-local-test-secrets>",
"loginId": "<receiver-test-account-email-from-local-test-secrets>",
"password": "<receiver-test-account-password-from-local-test-secrets>"
}
```
Write it to:
```bash
apps/client/assets/mattermost_credentials.json
```
This asset is intentionally ignored by `apps/client/.gitignore`. It lets `MattermostAuthService` login, call `setAuthToken`, fetch the server signing public key, call `setSigningKey`, and register the current FCM device token.
If the private environment provides a Mattermost server identifier that appears in FCM payloads as `server_id`, add it as `serverId` or `serverIdentifier` in the ignored credential asset. The host passes it through `setAuthToken(..., identifier:)` so `nexo_messaging` can resolve `server_url` even when more than one server is registered.
### Workspace Shape
The remote Android runner needs the same sibling workspace layout as the local agent workspace:
```text
<workspace>/
nomadcode/
nexo/
proto-socket/
```
`apps/client/pubspec.yaml` depends on:
```yaml
nexo_messaging:
path: ../../../nexo/packages/messaging_flutter
proto_socket:
path: ../../../proto-socket/dart
```
Make sure the remote `../nexo` checkout contains the current `packages/messaging_flutter` changes, especially the Android opened-intent fix that converts nested `Bundle` extras into Flutter codec-safe values. Without that fix, tapping a notification can crash with `Unsupported value: 'Bundle[EMPTY_PARCEL]'`.
NomadCode already uses Android `applicationId = "com.tokilabs.mattermost"` in `apps/client/android/app/build.gradle.kts`; unlike the standalone Nexo test harness, no Gradle application-id override is expected.
### Run App
On the Android remote runner:
```bash
cd <workspace>/nomadcode/apps/client
flutter pub get
flutter analyze --no-fatal-infos
flutter test
flutter run -d emulator-5554 --no-resident
```
Expected app-side setup logs include:
```text
FirebaseApp initialization successful
[MattermostAuth] Logging in to ...
[MattermostAuth] Login OK ...
[MattermostAuth] Signing key stored.
[MattermostAuth] FCM device token registered successfully.
```
If login or signing-key storage is skipped, fix the ignored credential asset or private environment before triggering the push. A valid server-generated push should not require manually injecting server URL rows or signing keys.
### Trigger Signed Push
Use the bot token from local test secrets to send a normal Mattermost DM or mention to the receiver test account through the Mattermost REST API. The important property is that the message is created by the server, then delivered through push-proxy to FCM; do not use a hand-built placeholder signature as the positive test.
The generic API flow is:
```bash
# 1. Resolve bot user and receiver user.
GET /api/v4/users/me
GET /api/v4/users/email/<receiver-email>
# 2. Open or create a direct channel.
POST /api/v4/channels/direct
# body: ["<bot-user-id>", "<receiver-user-id>"]
# 3. Post the smoke message.
POST /api/v4/posts
# body: {"channel_id":"<direct-channel-id>","message":"nomadcode signed push smoke <timestamp>"}
```
All calls use:
```text
Authorization: Bearer <bot-access-token-from-local-test-secrets>
```
### Expected Evidence
Collect redacted evidence only. Good evidence is logcat snippets, sanitized UI text, or `dumpsys notification` excerpts that omit raw payload signatures and tokens.
The positive signed path should show:
```text
NexoFCM : >>> onMessageReceived ENTER
NexoFCM : onMessageReceived type=message ... serverUrl=<mattermost-base-url>
ReceiptDelivery: Send ACK=...
NexoFCM : Sending notification event to Flutter: type=message
```
It should not show:
```text
Cannot verify
No signing key
Notification skipped: signature verification failed
```
Then verify:
- System notification displays the server-generated message and has a `Reply` action.
- Tapping the notification invokes the host channel navigation callback.
- Inline reply sends successfully. NomadCode should be able to test this fully because `MattermostAuthService` calls `setAuthToken`; if reply fails, inspect auth-token handoff before treating plugin behavior as failed.
- Dismiss/clear path logs the dismiss or cancel event.
- Device registration uses the `android_rn-v2:` prefix before the raw FCM token is registered with Mattermost.
### Negative Controls
If direct push-proxy access is available, send one placeholder-signature payload and one unsigned payload as negative controls. Both may reach `onMessageReceived` and ACK, but must stop before notification display with:
```text
Notification skipped: signature verification failed
```
### Evidence Checklist
Record these outcomes in the relevant `agent-task` review stub or milestone evidence. Use `PASS`, `PARTIAL`, `BLOCKED`, or `N/A` rather than overstating results.
| 항목 | 기대 |
|------|------|
| FCM payload wakes / receipt | PASS |
| valid server-generated signature 처리 | PASS |
| invalid / unsigned drop | PASS |
| notification display | PASS |
| ACK request | PASS |
| opened event | PASS |
| channel navigation | PASS |
| thread navigation | N/A unless the payload has `root_id` |
| inline reply | PASS expected for NomadCode host auth wiring |
| dismiss / clear | PASS |
| device token prefix | PASS |
### Roadmap Evidence
When a milestone depends on this environment, leave only a short evidence note in the milestone, for example:
```text
Android SDK check: see docs/test-environments.md#android-sdk-remote-runner; flutter build apk --debug passed on toki@toki-labs.com.
```
Keep detailed reusable environment instructions in this document, not in individual milestone files.