diff --git a/agent-ops/rules/project/domain/app-shell/rules.md b/agent-ops/rules/project/domain/app-shell/rules.md index b958813..c00cdc4 100644 --- a/agent-ops/rules/project/domain/app-shell/rules.md +++ b/agent-ops/rules/project/domain/app-shell/rules.md @@ -1,14 +1,14 @@ --- domain: app-shell -last_rule_review_commit: c1c4c41886f44727ad5b9297ec164198d1dd5bd9 -last_rule_updated_at: 2026-06-14 +last_rule_review_commit: fea3860d011f006a058506cb1f054407a5975a87 +last_rule_updated_at: 2026-06-24 --- # app-shell ## 목적 / 책임 -AppSok의 전역 앱 구성, startup session restore wiring, navigation shell, theme, feature 간 진입/상태 전달을 담당한다. +AppSok의 전역 앱 구성, startup session restore wiring, navigation shell, theme, feature 간 진입/설치 상태 전달을 담당한다. ## 포함 경로 @@ -28,7 +28,7 @@ AppSok의 전역 앱 구성, startup session restore wiring, navigation shell, t ## 주요 구성 요소 - `AppSokApp` — 앱 루트 widget -- `AppSokShell` — 좌측 navigation, 상단 상태 영역, feature 간 설치 대기 상태 전달 +- `AppSokShell` — 좌측 navigation, 상단 상태 영역, feature 간 설치 대기/결과 상태 전달 - `PendingInstall` — staged APK를 device-console에 넘기는 cross-feature DTO - `AppTheme` — AppSok Material 3 light theme @@ -38,14 +38,14 @@ AppSok의 전역 앱 구성, startup session restore wiring, navigation shell, t - 사용자 표시명은 `AppSok`으로 통일한다. Dart package, URL scheme, bundle id처럼 소문자 식별자가 필요한 곳만 `appsok`을 유지한다. - navigation item 추가 시 domain 경계를 먼저 정하고, shell에는 route/entry wiring만 둔다. - shell은 Jenkins session, artifact staging, ADB loader/installer 같은 dependency를 주입·연결하되 실제 외부 호출 semantics는 service 도메인에 둔다. -- 설치 대기 상태와 staged file cleanup은 페이지 dispose에 끊기지 않도록 shell에서 소유한다. +- 설치 대기 상태, 설치 중 상태, 마지막 설치 시도 결과, staged file cleanup은 페이지 dispose에 끊기지 않도록 shell에서 소유한다. - 버튼과 상태 표시는 icon을 우선 사용하고, 긴 설명성 문구는 화면 안에 넣지 않는다. - 카드 반경은 8px 이하를 유지한다. ## 다른 도메인과의 경계 - **artifact-flow**: Jenkins 인증/빌드 목록/다운로드/staged APK 생성은 artifact-flow가 소유하고, shell은 loader와 install handoff만 연결한다. -- **device-console**: ADB 연결 상태, 설치 실행, logcat session은 device-console이 소유하고, shell은 device 선택과 pending install 전달만 조율한다. +- **device-console**: ADB 연결 상태, 설치 실행, 설치 결과 모델, logcat session은 device-console이 소유하고, shell은 device 선택, pending install 전달, 마지막 설치 결과 보관만 조율한다. - **macos-platform**: 앱 이름, URL scheme, entitlement 변경은 platform 설정에서 처리한다. ## 금지 사항 diff --git a/agent-ops/rules/project/domain/artifact-flow/rules.md b/agent-ops/rules/project/domain/artifact-flow/rules.md index 16c9af4..bf43693 100644 --- a/agent-ops/rules/project/domain/artifact-flow/rules.md +++ b/agent-ops/rules/project/domain/artifact-flow/rules.md @@ -1,7 +1,7 @@ --- domain: artifact-flow -last_rule_review_commit: c1c4c41886f44727ad5b9297ec164198d1dd5bd9 -last_rule_updated_at: 2026-06-14 +last_rule_review_commit: fea3860d011f006a058506cb1f054407a5975a87 +last_rule_updated_at: 2026-06-24 --- # artifact-flow @@ -45,6 +45,8 @@ Jenkins 인증, Web Login token 발급 bridge, session restore, job/build/artifa - Jenkins API 응답 parsing은 모델 factory 또는 전용 parser에 둔다. - Jenkins URL path 조합은 context path를 보존하는 helper를 사용하고, 문자열 덧붙이기로 login/API 경로를 만들지 않는다. - WebView token bridge는 same-origin fetch로 `whoAmI`, crumb, token 발급 응답을 확인하고, token 이름에는 secret을 넣지 않는다. +- `whoAmI` 응답이 anonymous이거나 사용자 id가 비어 있으면 인증 실패로 취급한다. +- `JenkinsClientException.toString`은 Authorization, token, password, crumb 값을 redaction한 문자열만 노출한다. - `DownloadProgressEvent`는 누적 byte와 chunk byte를 함께 전달하고, 취소 시 stream을 닫아 partial staging이 남지 않게 한다. - staging된 파일은 `.apk` 확장자와 non-empty 조건을 검증하고, 취소/오류/설치 완료/대기 취소 시 cleanup 경로를 유지한다. - session 저장은 저장 직후 restore 검증까지 성공했을 때만 완료로 보고, 실패하면 저장값을 rollback한다. diff --git a/agent-ops/rules/project/domain/device-console/rules.md b/agent-ops/rules/project/domain/device-console/rules.md index adcdb0d..aad8c80 100644 --- a/agent-ops/rules/project/domain/device-console/rules.md +++ b/agent-ops/rules/project/domain/device-console/rules.md @@ -1,7 +1,7 @@ --- domain: device-console -last_rule_review_commit: c1c4c41886f44727ad5b9297ec164198d1dd5bd9 -last_rule_updated_at: 2026-06-14 +last_rule_review_commit: fea3860d011f006a058506cb1f054407a5975a87 +last_rule_updated_at: 2026-06-24 --- # device-console @@ -15,6 +15,7 @@ USB로 연결된 Android 기기 조회, APK 설치, ADB runtime 해석/진단, l - `lib/src/features/devices/` — ADB device 목록과 설치 대상 선택 UI - `lib/src/features/console/` — logcat viewer와 필터 UI - `lib/src/models/adb_device.dart` — ADB device 모델 +- `lib/src/models/install_attempt_result.dart` — 설치 시도 결과, 요약, masked copy report 모델 - `lib/src/services/adb_service.dart` — `adb devices`, `adb install`, `adb logcat` 실행 ## 제외 경로 @@ -34,6 +35,7 @@ USB로 연결된 Android 기기 조회, APK 설치, ADB runtime 해석/진단, l - `AdbLogcatSession` — running `adb logcat` process lifetime wrapper - `AdbRuntimeDiagnostics` — ADB executable path/source/version/SHA-256 진단 결과 - `AdbInstallResult`, `AdbException` — 설치 결과와 ADB 오류 표현 +- `InstallAttemptResult`, `InstallAttemptOutcome` — pending APK, device, ADB install result를 묶은 설치 결과와 민감정보 masking 리포트 ## 유지할 패턴 @@ -41,6 +43,7 @@ USB로 연결된 Android 기기 조회, APK 설치, ADB runtime 해석/진단, l - ADB runtime 선택은 custom path, bundled path, system fallback 순서를 유지하고, 기본 AppSok 전용 server port는 `5038`로 둔다. - `adb devices -l` parsing은 다양한 state(`device`, `unauthorized`, `offline`)를 허용한다. - 설치 결과는 exit code, stdout, stderr를 모두 보존해 사용자에게 원인 파악 정보를 제공한다. +- 설치 결과 요약이나 복사용 리포트는 URL, token/password/secret, device serial을 masking한 값만 UI/clipboard에 노출한다. - logcat stream은 pause/clear/filter 같은 UI 상태와 process lifetime을 분리하고, `AdbLogcatSession.stop`으로 process를 종료한다. - 콘솔 UI는 오래 실행되는 logcat session에서 화면 보관 line 수를 제한하고 level/text filter를 UI 상태로만 관리한다. - ADB 진단은 `adb version` timeout과 executable SHA-256 계산을 best-effort로 수행한다. @@ -48,12 +51,13 @@ USB로 연결된 Android 기기 조회, APK 설치, ADB runtime 해석/진단, l ## 다른 도메인과의 경계 - **artifact-flow**: 설치할 staged APK path와 metadata만 입력으로 받고 Jenkins 인증/다운로드 상태에는 의존하지 않는다. settings 화면에 ADB diagnostics panel이 있어도 진단 타입과 loader semantics는 device-console 소유다. -- **app-shell**: pending install과 선택 device handoff는 shell이 조율하고, device-console은 설치/logcat 요청을 수행한다. +- **app-shell**: pending install, 선택 device, 마지막 설치 결과의 lifecycle state는 shell이 조율하고, device-console은 설치/logcat 요청 수행과 설치 결과 표현 모델을 소유한다. - **macos-platform**: bundled ADB 리소스, sandbox, codesign, packaging 제약은 macos-platform에서 관리하고, runtime 선택과 command semantics는 device-console에서 관리한다. ## 금지 사항 - device serial, logcat 원문에 secret이 포함될 수 있으므로 불필요하게 tracked 파일에 저장하지 않는다. +- 설치 실패 stdout/stderr, 복사용 리포트, device serial 원문을 masking 없이 UI나 clipboard에 노출하지 않는다. - split APK/APKS/AAB 설치를 단일 APK 설치 흐름에 섞어 임시 처리하지 않는다. - 무한 logcat stream을 dispose 없이 방치하지 않는다. - 화면 widget에서 ADB binary 경로, environment, server port를 직접 구성하지 않는다. diff --git a/agent-ops/rules/project/domain/macos-platform/rules.md b/agent-ops/rules/project/domain/macos-platform/rules.md index fe853fd..bbc45da 100644 --- a/agent-ops/rules/project/domain/macos-platform/rules.md +++ b/agent-ops/rules/project/domain/macos-platform/rules.md @@ -1,26 +1,29 @@ --- domain: macos-platform -last_rule_review_commit: c1c4c41886f44727ad5b9297ec164198d1dd5bd9 -last_rule_updated_at: 2026-06-14 +last_rule_review_commit: fea3860d011f006a058506cb1f054407a5975a87 +last_rule_updated_at: 2026-06-24 --- # macos-platform ## 목적 / 책임 -macOS desktop target의 bundle metadata, entitlement, URL scheme, runner 설정, bundled ADB resource packaging, certified build/signing/notarization tooling을 담당한다. +macOS desktop target의 bundle metadata, entitlement, URL scheme, runner 설정, bundled ADB resource packaging, certified build/signing/notarization tooling, certified Jenkins job provisioning을 담당한다. ## 포함 경로 - `macos/Runner/Info.plist` — bundle metadata와 `appsok://` URL scheme - `macos/Runner/Configs/` — product name, bundle identifier, build config +- `macos/Runner/Assets.xcassets/` — macOS app icon asset catalog - `macos/Runner/AppDelegate.swift`, `macos/Runner/MainFlutterWindow.swift`, `macos/Runner/Base.lproj/` — macOS app/window/menu runner wiring - `macos/Runner/*.entitlements` — sandbox/network 권한 - `macos/Runner/Resources/adb-runtime/` — bundled ADB runtime metadata와 NOTICE - `macos/Runner.xcodeproj/`, `macos/Runner.xcworkspace/` — Xcode project/workspace 설정 -- `macos/Flutter/GeneratedPluginRegistrant.swift` — Flutter plugin 등록 +- `macos/RunnerTests/` — macOS Runner XCTest scaffold +- `macos/Flutter/` — Flutter generated xcconfig와 plugin 등록 - `scripts/build-certified-macos.sh` — Flutter gate, Developer ID signing, notarization, final zip 생성 - `scripts/setup-appsok-ci-secrets.sh` — SOPS age key, encrypted CI secret, notary profile setup +- `scripts/upsert-jenkins-certified-job.sh` — certified macOS artifact Jenkins job XML dry-run/create/update - `.sops.yaml`, `secrets/*.sops.json` — encrypted CI signing/notary input 설정과 암호화 payload ## 제외 경로 @@ -37,8 +40,9 @@ macOS desktop target의 bundle metadata, entitlement, URL scheme, runner 설정, - `DebugProfile.entitlements`, `Release.entitlements` — sandbox와 network client 권한 - `Runner.xcodeproj` build phase — pinned Android platform-tools `adb`를 app bundle resource로 복사하고 adhoc sign - `GeneratedPluginRegistrant.swift` — `app_links`, `flutter_secure_storage_darwin`, `webview_flutter_wkwebview` plugin 등록 -- `build-certified-macos.sh` — release build, bundled `adb` signing, app signing, notarization/staple/assessment packaging -- `setup-appsok-ci-secrets.sh` — SOPS-encrypted CI input 생성과 `notarytool` profile 저장 +- `build-certified-macos.sh` — release build, bundled `adb` signing, app signing, notarization/staple/assessment packaging, SHA-256 sidecar 생성 +- `setup-appsok-ci-secrets.sh` — SOPS-encrypted CI input 생성, Jenkins credential input 암호화, `notarytool` profile 저장 +- `upsert-jenkins-certified-job.sh` — credential-free SCM URL 기반 `appsok-macos-certified` Jenkins job XML 생성/갱신 ## 유지할 패턴 @@ -50,6 +54,8 @@ macOS desktop target의 bundle metadata, entitlement, URL scheme, runner 설정, - bundled ADB는 `source.properties`의 pinned `Pkg.Revision`과 실제 `adb version`을 맞춘 뒤 app resource로 복사한다. - app bundle 안의 `adb-runtime/adb`는 app signing/notarization 전에 별도로 codesign 검증한다. - CI signing/notary secret은 SOPS-encrypted payload와 macOS Keychain profile로만 다루고 raw password/key를 tracked 문서나 로그에 남기지 않는다. +- Jenkins certified job upsert는 dry-run을 기본값으로 두고, SCM URL userinfo를 거부하며, Jenkins credential은 SOPS payload에서 읽어 임시 curl config로만 전달한다. +- certified build 산출물은 `AppSok-certified.zip`과 같은 경로의 `.sha256` sidecar를 함께 생성한다. - 배포 전에는 sandbox 상태에서 ADB binary 실행과 USB 접근 가능 여부를 macOS host에서 검증한다. - macOS build/signing 검증은 local container가 아니라 standard remote Mac runner `toki@toki-labs.com`의 `$HOME/docker/services/code-server/data/volume/workspace/appsok` checkout을 기준으로 한다. - certified build script는 `flutter analyze`, `flutter test`, `flutter build macos` gate 이후 signing/notarization/package 순서를 유지한다. @@ -57,7 +63,7 @@ macOS desktop target의 bundle metadata, entitlement, URL scheme, runner 설정, ## 다른 도메인과의 경계 -- **artifact-flow**: deep link payload가 Jenkins job/build/artifact를 가리킬 수 있으나 parsing/권한 확인은 artifact-flow에서 담당한다. +- **artifact-flow**: deep link payload가 Jenkins job/build/artifact를 가리킬 수 있으나 parsing/권한 확인은 artifact-flow에서 담당한다. certified Jenkins job provisioning은 배포 CI 설정으로 macos-platform 책임이다. - **device-console**: bundled ADB resource, sandbox, codesign, packaging 제약은 macos-platform에서 관리하고, runtime 선택과 command semantics는 device-console에서 관리한다. - **app-shell**: 앱 이름과 window metadata는 platform 설정에서 관리하고, 화면 layout은 app-shell에서 관리한다. @@ -66,4 +72,5 @@ macOS desktop target의 bundle metadata, entitlement, URL scheme, runner 설정, - entitlement를 넓힐 때 사유 없이 sandbox를 해제하지 않는다. - macOS 설정 파일을 Flutter 자동 생성물과 충돌하는 방식으로 수동 대량 편집하지 않는다. - notarization, signing, MDM 배포 전제를 확인하지 않고 배포 가능하다고 단정하지 않는다. +- Jenkins job XML이나 SCM URL에 username/password/token을 직접 포함하지 않는다. - SOPS key, keychain password, Apple ID password, notary credential 원문을 tracked 파일, task log, 최종 응답에 기록하지 않는다. diff --git a/agent-ops/rules/project/rules.md b/agent-ops/rules/project/rules.md index 153c0b2..f0017d7 100644 --- a/agent-ops/rules/project/rules.md +++ b/agent-ops/rules/project/rules.md @@ -57,9 +57,9 @@ |----------|--------|----------| | `lib/main.dart`, `lib/src/app.dart`, `lib/src/features/app_shell.dart`, `lib/src/models/pending_install.dart`, `lib/src/theme/**` | app-shell | `agent-ops/rules/project/domain/app-shell/rules.md` | | `lib/src/features/builds/**`, `lib/src/features/settings/**`, `lib/src/models/jenkins_build.dart`, `lib/src/services/jenkins_client.dart`, `lib/src/services/jenkins_artifact_session.dart`, `lib/src/services/artifact_staging_service.dart`, `lib/src/services/token_store.dart` | artifact-flow | `agent-ops/rules/project/domain/artifact-flow/rules.md` | -| `lib/src/features/devices/**`, `lib/src/features/console/**`, `lib/src/models/adb_device.dart`, `lib/src/services/adb_service.dart` | device-console | `agent-ops/rules/project/domain/device-console/rules.md` | +| `lib/src/features/devices/**`, `lib/src/features/console/**`, `lib/src/models/adb_device.dart`, `lib/src/models/install_attempt_result.dart`, `lib/src/services/adb_service.dart` | device-console | `agent-ops/rules/project/domain/device-console/rules.md` | | `macos/**` | macos-platform | `agent-ops/rules/project/domain/macos-platform/rules.md` | -| `scripts/build-certified-macos.sh`, `scripts/setup-appsok-ci-secrets.sh`, `.sops.yaml`, `secrets/*.sops.json` | macos-platform | `agent-ops/rules/project/domain/macos-platform/rules.md` | +| `scripts/build-certified-macos.sh`, `scripts/setup-appsok-ci-secrets.sh`, `scripts/upsert-jenkins-certified-job.sh`, `.sops.yaml`, `secrets/*.sops.json` | macos-platform | `agent-ops/rules/project/domain/macos-platform/rules.md` | ## 스킬 라우팅 diff --git a/agent-roadmap/ROADMAP.md b/agent-roadmap/ROADMAP.md index 676b892..87e64f4 100644 --- a/agent-roadmap/ROADMAP.md +++ b/agent-roadmap/ROADMAP.md @@ -14,9 +14,9 @@ AppSok은 Jenkins Android artifact를 네트워크 제약이 있는 Android 기 - [완료] 사용 가능한 MVP - 경로: `agent-roadmap/archive/phase/usable-mvp/PHASE.md` - 요약: Jenkins build 조회, 사용자별 credential, APK 다운로드, USB 설치, logcat 확인까지 하루 업무에 쓸 수 있는 최소 흐름을 만든다. -- [진행중] 업무 흐름 통합 +- [보류] 업무 흐름 통합 - 경로: `agent-roadmap/phase/workflow-integration/PHASE.md` - - 요약: Teams 메시지/deep link와 현재 설치 오류 리포트로 QA와 개발자의 반복 사용 흐름을 줄인다. + - 요약: 설치 오류 리포트는 완료했고, Teams deep link는 MVP 사용자 테스트 뒤에 재개한다. - [스케치] 보안과 조직 배포 - 경로: `agent-roadmap/phase/security-distribution/PHASE.md` - 요약: macOS 배포, sandbox, signing, 사내 인증 확장 후보를 검토해 조직 표준 도구로 키울 수 있는 조건을 정리한다. diff --git a/agent-roadmap/phase/workflow-integration/PHASE.md b/agent-roadmap/phase/workflow-integration/PHASE.md index 2357e58..706dc22 100644 --- a/agent-roadmap/phase/workflow-integration/PHASE.md +++ b/agent-roadmap/phase/workflow-integration/PHASE.md @@ -2,7 +2,7 @@ ## 상태 -[진행중] +[보류] ## 목표