From 40897c4d9311f436a73c560655b4604b926ba299 Mon Sep 17 00:00:00 2001 From: Michael Kaltner Date: Fri, 17 Jul 2026 12:03:41 -0700 Subject: [PATCH 1/3] docs: add agent guidance --- AGENTS.md | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..0637d9f --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,93 @@ +# Arcane Android Agent Guidance + +Arcane Android is a Jetpack Compose companion for the Arcane Docker management server. It is an +operational client, so correctness, server compatibility, lifecycle behavior, and safe destructive +actions matter more than visual novelty. + +## Collaboration Scope + +Michael Kaltner is an authorized collaborator and an active Android feature contributor. Changes +may cover application code, tests, navigation, CI, Gradle, AGP, Kotlin, JDK, dependencies, and +coordinated SDK integration. + +Use a focused branch by default. Do not push, merge to `main`, tag, sign, publish an APK, or create +a GitHub release unless the user explicitly requests it. + +Always inspect `git status` first and preserve unrelated local changes and untracked files. + +## Architecture + +- `app/src/main/kotlin/app/getarcane/android/core/` — client ownership, authentication, preferences, + environment state, streams, formatting, and shared application state. +- `app/src/main/kotlin/app/getarcane/android/nav/` — bottom-tab selection, persistence, swapping, + and back-navigation behavior. +- `app/src/main/kotlin/app/getarcane/android/ui/screens/` — resource list/detail screens and + operational flows. +- `app/src/main/kotlin/app/getarcane/android/ui/components/` — reusable Compose components. +- `app/src/test/` — JVM unit tests. Prefer extracting deterministic mapping/state logic so it can + be tested without an emulator. + +`ArcaneClientManager` is the central owner of server configuration, authentication state, current +user, capabilities, active environment, and the `ArcaneClient`. Do not create competing client +owners or independent authentication stores. + +The app uses a single-activity Compose architecture. Follow the existing navigation and screen +patterns instead of introducing a second navigation framework or unrelated state-management +system. + +## SDK Boundary + +The app depends on the sibling `../libarcane-kotlin` checkout when it exists and its Android Gradle +Plugin version matches the app. Otherwise Gradle resolves the SDK from its Git source. Pass +`-Parcane.remoteSdk` only when intentionally testing the remote dependency. + +Treat `libarcane-kotlin` as the sole application API client: + +- use `ArcaneClient` services and SDK models directly; +- do not duplicate REST endpoints, DTOs, token refresh, serialization, WebSocket, or NDJSON logic; +- do not add pass-through wrappers around SDK methods; +- when the Arcane wire contract is unsupported, update and test the SDK first. + +For cross-repository API work, inspect the matching types and handlers in `../arcane`, then update +the SDK, then update Android. + +## Implementation Conventions + +- Use Kotlin coroutines and structured cancellation. Rethrow `CancellationException`. +- Keep long-lived work in an explicitly owned scope and cancel or replace jobs when lifecycle or + environment state changes. +- Keep environment-specific operations tied to the selected `EnvironmentId`; `"0"` represents the + local Docker environment. +- Preserve authentication restoration without flashing the login UI. +- Treat unknown server enum values and optional fields defensively. +- Keep list/detail navigation mobile-native and preserve back and tab re-selection behavior. +- Put destructive operations behind clear resource- and environment-specific confirmation. +- Prefer existing shared components and formatting helpers before adding new ones. +- Add or update tests for nontrivial mapping, selection, status, retry, and navigation logic. +- Prefer Android string resources for new user-facing text when practical; do not mix a focused + change with a broad localization rewrite. + +## Toolchain and Verification + +The checked-in build defines the authoritative versions. The expected baseline is JDK 21, JVM +target 17, Android API 24 minimum, and Android API 35 compile/target SDK. + +Run the CI-equivalent checks: + +```sh +./gradlew :app:testDebugUnitTest :app:assembleDebug +``` + +When the sibling SDK changed, run this first from `../libarcane-kotlin`: + +```sh +./gradlew :arcane-core:test :arcane-android:assembleRelease +``` + +For lifecycle, navigation, streaming, authentication, or destructive-action changes, also test on +an emulator or device against an appropriate Arcane server when available. Clearly report when +manual/device testing was not possible. + +Release signing is optional for development. Never request, expose, or commit signing secrets. +Do not commit generated Gradle output, local SDK paths, APKs, keystores, or machine-specific +configuration. From b564545e538624ebfa3b095545cd3ee26087e090 Mon Sep 17 00:00:00 2001 From: Michael Kaltner Date: Fri, 17 Jul 2026 13:06:58 -0700 Subject: [PATCH 2/3] docs: add iOS parity analysis and backlog --- docs/ios-android-gap-analysis.md | 417 +++++++++++++++++++ docs/ios-parity-task-list.md | 682 +++++++++++++++++++++++++++++++ 2 files changed, 1099 insertions(+) create mode 100644 docs/ios-android-gap-analysis.md create mode 100644 docs/ios-parity-task-list.md diff --git a/docs/ios-android-gap-analysis.md b/docs/ios-android-gap-analysis.md new file mode 100644 index 0000000..e1acf7a --- /dev/null +++ b/docs/ios-android-gap-analysis.md @@ -0,0 +1,417 @@ +# iOS-to-Android gap analysis + +Last reviewed: 2026-07-17 + +This document compares Arcane's iOS application with the Android application to guide Android +product planning. It is a source-analysis snapshot, not a promise that Android will reproduce every +iOS implementation detail. + +## Comparison baseline + +The analysis is pinned to these product revisions: + +| Component | Revision | Notes | +| --- | --- | --- | +| iOS | [`03f2f3d11e40f759ca62f0207bb3d59418a42933`](https://github.com/getarcaneapp/iOS/tree/03f2f3d11e40f759ca62f0207bb3d59418a42933) | `main`, app version 0.5.4, dated 2026-07-10 | +| iOS resolved Swift SDK | [`c1016b2e0aaebffc112893179560c2462c1a013a`](https://github.com/getarcaneapp/libarcane-swift/tree/c1016b2e0aaebffc112893179560c2462c1a013a) | `libarcane-swift` revision resolved by the iOS project | +| Android | [`c500c262e4e71b094e16ca8afc049f2286d22cfa`](https://github.com/getarcaneapp/android/tree/c500c262e4e71b094e16ca8afc049f2286d22cfa) | `origin/main` product baseline | +| Kotlin SDK | [`991dfdc1ee747c171ebf1b5953fe5fb61ceadfb8`](https://github.com/getarcaneapp/libarcane-kotlin/tree/991dfdc1ee747c171ebf1b5953fe5fb61ceadfb8) | `origin/main` product baseline | + +The Android and Kotlin SDK checkouts also had `agent/add-agent-guidance` commits at review time. +Those commits add only repository guidance and are not treated as product functionality. + +### Method and limitations + +This is a static source comparison of application structure, visible routes, stores, service calls, +models, persistence, tests, and release automation. No iOS build was run because the review was +performed on Windows. No emulator/device or live Arcane server was used, and neither application's +complete runtime behavior was manually exercised. Items that depend on server version, runtime +permissions, signing, background execution limits, or App Store/Play distribution should therefore +be validated before implementation decisions are made. + +The current Android/Kotlin composite checkout did pass +`./gradlew :app:testDebugUnitTest :app:assembleDebug` during this analysis. That result confirms the +reviewed source compiles and its JVM unit tests pass; it does not validate device or live-server +behavior. + +The comparison distinguishes product capabilities from platform-specific mechanisms. For example, +an iOS Live Activity does not imply that Android needs a literal copy; the Android question is +whether a persistent notification or another Android-native surface should provide the same +operational continuity. + +## Status legend + +| Status | Meaning | +| --- | --- | +| **Parity** | Android provides the same core user outcome, even if the UI or platform API differs. | +| **Partial** | Android implements a useful subset, but an important workflow, state, or polish layer is absent. | +| **Android gap** | The iOS user outcome has no meaningful Android implementation at this baseline. | +| **Shared gap** | Both applications lack the capability or expose only a placeholder. | +| **Android strength** | Android is ahead or has a materially stronger implementation in this area. | +| **Validate** | Static inspection is insufficient or the SDK/server prerequisite needs confirmation. | + +## Executive summary + +Android is already a substantial operational client rather than a shell. Its resource coverage is +broad: containers, images, projects, volumes, networks, ports, updates, activities, events, jobs, +Git repositories, GitOps, registries, templates, user administration, RBAC, notifications, +authentication settings, system settings, builds, and upgrades are all represented. The application +also has live streams for important operational views and a larger JVM unit-test body plus working +CI than the iOS repository. + +The largest difference is depth and continuity, not the count of resource screens. iOS has a more +mature application shell and operational layer: disk-backed stale-while-revalidate caching, +adaptive tablet navigation, profile management, a complete project-file workspace, richer log +workflows, image attestations, persistent deployment progress, and several native entry points. +iOS also contains an optional on-device AI assistant, although that implementation is tied to +Apple's Foundation Models and should be treated as a product concept rather than a direct Android +port. + +The most urgent Android work is smaller than those strategic gaps. Change-server can leave +prior-server state or credentials alive; some admin destinations lose their drill-down callbacks +when selected as main tabs; the appearance selector is non-persistent and does not drive the app +theme; and Settings links point to the iOS repository. Those should be fixed before broad parity +work. Separately, decide whether to expose the currently unreachable environment +list/detail/test surface. + +The recommended sequence is: + +1. Fix reachable-navigation and settings defects. +2. Complete high-value daily workflows: project files, profile/account management, logs, image + attestations, and missing container actions. +3. Add resilient cached reads and persistent long-running operation state. +4. Add Android-native equivalents for adaptive navigation, widgets, shortcuts, deep links, and + ongoing-operation notifications. +5. Consider optional strategic features such as AI assistance and multi-server profiles only after + the operational foundation is reliable. + +## Detailed capability matrix + +### Application shell, navigation, and presentation + +| Capability | iOS baseline | Android baseline | Status and action | +| --- | --- | --- | --- | +| Application architecture | SwiftUI state machine with setup, authentication, login, and authenticated states; service/store ownership around the SDK. | Single `ComponentActivity`, Compose auth router, central `ArcaneClientManager`, and screen-local stores. See `app/src/main/kotlin/app/getarcane/android/MainActivity.kt`, `ui/ArcaneApp.kt`, and `core/ArcaneClientManager.kt`. | **Parity** for the core application lifecycle. Preserve one client/auth owner. | +| Configurable primary tabs | Four user-swappable resource tabs plus Settings, with tab state and independent navigation. | Four user-swappable resource tabs plus fixed Settings; selected tabs persist through `nav/NavTabsStore.kt`. | **Parity** in basic configuration. | +| Adaptive large-screen navigation | Compact navigation and an optional regular-width sidebar/drawer. | Bottom navigation only; no tablet-adaptive rail/sidebar strategy was found. | **Android gap.** Add a `NavigationSuiteScaffold`-style adaptive shell or equivalent after navigation defects are fixed. | +| Per-tab navigation continuity | Independent navigation stacks, environment-aware rebuild, deep-link restoration. | Android rebuilds the selected tab's content and loses that tab's nested stack when switching tabs. | **Android gap.** Preserve independent stacks across tab switches; separately validate configuration-change and process-recreation restoration. | +| Deep links and external entry points | Deep links can select tab/environment/container/project; quick actions and widgets use them. | OIDC callback handling exists, but no comparable authenticated resource deep-link system was found. | **Android gap.** Define stable internal routes before widgets and shortcuts. | +| Release notes | Version-aware release notes display automatically when appropriate. | A manually reachable What's New surface exists, but Android does not automatically present new-version notes. | **Android gap.** Add version-gated automatic presentation after correcting the Android release-note data. | +| Appearance | Accent, sidebar preference, alternate icons, material compatibility, motion-aware polish. | Accent preference exists. Light/Dark/Auto is screen-local state, resets, and does not drive the application theme. | **Partial/defect.** Wire theme mode into persistent app-wide state before adding further appearance options. | +| Localization | English-only; future-language intent is visible. | Most user-visible text is hard-coded; only minimal string resources exist. | **Shared gap**, with higher Android remediation cost. New work should use resources without coupling a feature to a full rewrite. | +| Accessibility and interaction polish | Haptics, toasts, custom confirmations, reduce-motion handling, skeletons, tips, and review prompts. | Standard Compose semantics and confirmations exist, but no comparable coordinated polish layer was identified. | **Partial.** Audit accessibility, motion, haptics, and destructive confirmations as cross-cutting work. | + +### Server setup, authentication, and account + +| Capability | iOS baseline | Android baseline | Status and action | +| --- | --- | --- | --- | +| Server setup | Server URL setup with DNS/bootstrap retry and local-server allowances. | URL normalization and server setup exist. | **Parity** for the primary outcome; compare error recovery during live testing. | +| Password authentication | Password login, secure persisted credentials/tokens, session restore, and logout. | Password login, encrypted token storage, restoration, and logout via `ArcaneClientManager`. | **Parity.** | +| OIDC | Uses `ASWebAuthenticationSession` and public provider information. | Current and legacy OIDC callback/deep-link handling. | **Parity** at the product level; device-test provider variants. | +| Demo mode | Demo provisioning and session behavior. | Demo provisioning, heartbeat, and countdown. | **Parity**, with Android exposing explicit heartbeat/countdown behavior. | +| User profile | View/update display name and email, change password, avatar/Gravatar handling, sign out, and change server. | Current-user data is held for authorization, but no comparable end-user profile/account workflow was found. | **Android gap.** Add a profile route distinct from admin user management. | +| Multiple server profiles | No complete multi-profile manager was identified; change-server flow exists. | One active server is persisted. `changeServer` only transitions to setup; stale client, user, capabilities, cookies, or tokens may survive, and stored tokens are not scoped by server. | **Shared profile gap plus Android security/correctness defect.** Immediately invalidate all prior-server state and scope credentials by server before considering profiles. | +| Biometric application lock | No core capability identified. | No core capability identified. | **Shared gap**, not required for iOS parity. Consider separately if threat modeling supports it. | + +### Dashboard and environment management + +| Capability | iOS baseline | Android baseline | Status and action | +| --- | --- | --- | --- | +| Fleet dashboard | Fleet totals, server cards, stats/sparklines, needs-attention groups, failed activities, pinned resources/actions, update-all, and card actions for environment sync/system/upgrade/prune. | Fleet totals/cards, stats/sparklines, needs attention, failed activities, pins/actions, update-all, and per-environment prune/detail/active behavior; sync/system/upgrade card actions are absent. | **Partial.** Add the missing high-value card actions with permission and server-capability gating. | +| Live dashboard updates | v2 stream with legacy fallback and bounded concurrent stats streams. | Dashboard streaming with reconnect behavior and resource statistics streams. | **Partial.** Validate fallback/version behavior and connection limits under many environments. | +| Environment selection | Active environment selection and environment-aware navigation. | Active environment selection, detail/test, persistence, and client rebuild. | **Parity** for selection. | +| Environment management | Neither pinned client exposes a confirmed full create/edit/delete workflow. | `ui/screens/environments/EnvironmentsScreen.kt` contains an unreachable list/detail/set-active/metadata/version/test surface; it is not full CRUD. | **Shared/undefined capability.** Decide the supported server workflow before adding full management. Android may separately expose its existing read/detail/test surface if that has product value. | +| Fleet pagination | Environment-backed views load the complete relevant fleet. | The SDK environment list defaults to 20. `DashboardScreen`, `UpdatesScreen`, `AllEnvironmentsImageUpdatesScreen`, and `EnvironmentListScreen` call it without pagination, silently omitting environments above 20. | **Android correctness defect.** Implement explicit paging or a deliberate complete-fleet query and test fleets of 0, 20, 21, and multiple pages. | +| Offline dashboard snapshot | Disk cache and last-known server snapshots support stale display. | No disk-backed response cache/database was found. | **Android gap.** See the resilience section. | + +### Containers + +| Capability | iOS baseline | Android baseline | Status and action | +| --- | --- | --- | --- | +| Inventory and filtering | List/search/filter, selection, bulk deletion, and prune. | List/search/filter, pin, resource actions, and prune. | **Partial.** Confirm bulk selection/delete parity. | +| Lifecycle actions | Start, stop, restart, pause, unpause, redeploy, rename, and delete as applicable. | Start, stop, restart, unpause, redeploy, rename, and delete are visible across list/detail flows. Pause and kill are absent from the UI even though the pinned Kotlin SDK exposes them. | **Android UI gap.** Add pause and kill with current-state gating and explicit confirmation appropriate to their impact. | +| Detail depth | Configuration, health, ports, environment, labels, mounts, and networks. | Overview, live stats, logs, inspect/copy, and operational actions. | **Partial.** Compare detail fields on real containers and fill high-value metadata gaps. | +| Statistics | Live CPU, memory, network, and I/O presentation. | Live statistics and charts. | **Parity.** | +| Logs | Search/filter, pause, timestamps, retention, ANSI rendering, copy/share/export. | Live logs and ANSI handling are present, but the iOS-level copy/share/export workflow was not identified. | **Partial.** Add select/copy/share/export and verify cancellation/reconnect behavior. | +| Terminal | Interactive terminal with special keys, copy, and clear. | Interactive terminal exists. | **Partial to parity.** Device-test IME, lifecycle, special-key, and reconnect behavior. | +| Ask AI from resource context | Resource-aware entry to the on-device assistant. | No AI assistant. | **Android gap**, but strategic and optional rather than core container parity. | + +### Projects and Compose workflows + +| Capability | iOS baseline | Android baseline | Status and action | +| --- | --- | --- | --- | +| Project list and lifecycle | Active/archived projects, create, deploy/redeploy, start/stop/restart, logs, archive/delete. | Active/archived projects, create from blank/template, lifecycle streams, logs, archive/delete. | **Parity** for broad lifecycle coverage. | +| Project creation | Compose and `.env` input, templates, variable-resolution support. | Blank/template creation with Compose and `.env` input. | **Parity** for initial creation. | +| Existing project files | File tree, Compose/`.env` editor, save, create, rename, move, and delete. GitOps/archived projects are read-only where appropriate. | Existing-project Compose is effectively read-only; there is no complete file workspace. | **Major Android gap.** This is the highest-value feature-depth gap for users managing projects from mobile. | +| Variable resolution | Resolution preview plus resolved YAML in the editing workflow. | Preview exists, but it is not part of a full editable existing-project workspace. | **Partial.** Fold it into the file editor rather than building another isolated preview. | +| Persistent deployment progress | Operation store survives sheet dismissal; floating progress pill, activity IDs, reconnect/cancel, and background grace. | Streaming action screens exist, but no equivalent process-resilient or app-wide operation presentation was found. | **Android gap.** Add application-owned operation state and an ongoing notification where appropriate. | +| Project logs | Searchable/shareable operational logs integrated with deployment state. | Project logs exist. | **Partial.** Align the useful log operations with container logs. | + +The pinned Kotlin SDK is ready for the project workspace: `ProjectsService` exposes Compose, +file-list/read, and project-update operations, while `UpdateProject.fileChanges` has typed +`create_file`, `create_folder`, `update_file`, `rename`, `move`, and `delete` changes. This is +therefore Android UI/state work, with serialization and live-server contract tests required before +release. Do not add application-local HTTP calls or duplicate DTOs. + +### Images, updates, and supply-chain data + +| Capability | iOS baseline | Android baseline | Status and action | +| --- | --- | --- | --- | +| Image inventory and lifecycle | List/detail, pull, streamed tar upload through `UploadImageView`, delete/prune, inspect/config/layers, and update workflows. | Filtered inventory, streamed pull, tar upload, remove/prune, inspect/config/layers, and update flows. | **Parity.** | +| Vulnerability scanning | Scan, filter, ignore, and inspect vulnerabilities. Some DTOs are app-local raw REST because of an iOS SDK mismatch. | Scan/filter/ignore and aggregate/detail vulnerability flows are present through the Kotlin stack. | **Parity/Android strength.** Keep DTOs in the SDK and verify unknown values defensively. | +| Image attestations | Attestation list/filter/detail and statement copy. | No attestation UI was identified; the pinned Kotlin SDK exposes attestation operations. | **Android UI gap.** Add the workflow using SDK types and confirm payload behavior against the target server. | +| Image updates | Per-image and fleet update flows. | Per-image, update overview, updater, and fleet-update flows. | **Parity/Android strength.** Android has substantial explicit updater behavior. | + +### Volumes, networks, and ports + +| Capability | iOS baseline | Android baseline | Status and action | +| --- | --- | --- | --- | +| Volumes | Create/remove/prune, detail, browser, backups, restore/delete/download. | Create/remove/prune, detail, browser, backups, restore/delete/download. | **Parity.** | +| Network management | List/create/delete/detail plus a topology view. The current topology is a list rather than a graph. | List/create/delete/detail plus topology presented as nodes/list. | **Parity with a shared gap.** A graph is a future product enhancement, not an Android parity defect. | +| Network summary accuracy | Some internal/container-count values are stubbed in the iOS app. | Android data should be compared with server responses rather than copied from iOS summaries. | **Validate.** Do not treat known iOS stubs as a target. | +| Ports | Read-only port inventory. | Read-only port inventory. | **Parity.** | + +### Activities, events, jobs, Git, and Swarm + +| Capability | iOS baseline | Android baseline | Status and action | +| --- | --- | --- | --- | +| Activities | v2 activity stream, filtering, cancellation/clearing, environment context. | All-environment v2 live stream, filtering, cancel, and clear. | **Parity.** The pinned Kotlin SDK includes activity error/heartbeat support; validate event behavior against the target server. | +| Events | Event inventory and details. | Event inventory and details. | **Parity.** | +| Live event updates | Event presentation refreshes as server events arrive. | The Android screen loads paginated snapshots; no live polling or event stream refresh was identified. | **Partial.** Add lifecycle-aware polling or a server-supported stream, with visible refresh/error state. | +| Jobs | Job inventory and actions/details. | Job surfaces are present. | **Parity at screen level; validate** live lifecycle operations. | +| Git repositories and GitOps | Repository and GitOps management. | Typed Git repository and GitOps screens are present. | **Parity** in broad coverage. | +| Dynamic/generic resources | Generic resource presentation supports some server-driven expansion. | More domains are represented by typed screens; no equivalent general dynamic-resource UI was identified. | **Partial.** Prefer typed daily-use experiences; add generic fallback only if it materially improves forward compatibility. | +| Swarm | Placeholder. | `ui/screens/swarm/SwarmScreen.kt` is a placeholder. | **Shared gap.** Do not prioritize as an Android parity issue until the product defines the workflow. | + +### Administration, RBAC, and server settings + +| Capability | iOS baseline | Android baseline | Status and action | +| --- | --- | --- | --- | +| User administration | User list/detail and account administration. | User list/detail and role-related management. | **Parity** in broad coverage; this does not replace an end-user profile screen. | +| API keys | API key management. | API key management. | **Parity.** | +| Roles and OIDC mappings | Role/RBAC and OIDC mapping administration. | Roles/RBAC and OIDC mapping administration. | **Parity** at screen level. | +| Notification providers and webhooks | Provider-specific notification configuration and webhooks. | Notification and webhook configuration. | **Parity** in broad coverage; compare provider-specific validation. | +| Authentication/system/build/upgrade | Server authentication settings, system information/settings, builds, and upgrade. | Authentication, system, build, and upgrade surfaces. | **Parity** in broad coverage. | +| Admin destinations as swappable tabs | Destinations retain their expected drill-down behavior. | Users, Notifications, System, and Roles use empty drill-down callbacks when selected as primary tabs in `nav/MainTabView.kt`; they work through Settings. | **Android defect.** Reuse one route owner or pass functional callbacks in both entry contexts. | +| Documentation/support links | iOS repository links are appropriate to the app. | App Settings GitHub/issue links point to the iOS repository. | **Android defect.** Point source and issue links to the Android repository or a deliberate cross-project destination. | + +### Streaming, caching, offline behavior, and background work + +| Capability | iOS baseline | Android baseline | Status and action | +| --- | --- | --- | --- | +| Read caching | Server/user/environment/path-scoped disk cache with stale-while-revalidate, request coalescing, LRU limits, and seven-day expiry. | Preferences and pins persist, but no general response cache/database was found. | **Major Android gap.** Start with safe read-only snapshots for dashboard and resource lists. | +| Offline behavior | Last-known snapshots can render; mutations still require connectivity and are not queued. | Network failure generally leaves each screen to its own loading/error path. No offline mutation queue exists. | **Partial/shared boundary.** Match stale reads; do not queue destructive mutations without a separate design. | +| Stream ownership | Reconnect behavior plus application-owned deployment state and bounded background grace. | Dashboard, stats, activities, logs, terminal, project actions, and image progress stream. Ownership is screen/store dependent. | **Partial.** Standardize retry, environment changes, and cancellation. | +| Activity Center failure recovery | Activity work can recover after transient stream/list failures. | The Activity Center has live and paginated behavior, but a clear user retry path after terminal failure was not identified. | **Partial/defect.** Add retry and test per-environment partial failure without discarding healthy results. | +| Coroutine/task cancellation | Structured task ownership with Swift concurrency. | Coroutines are used broadly, but `CancellationException` handling is uneven. | **Android hardening gap.** Audit broad catches and always rethrow cancellation. | +| Background execution | Limited background grace for active deployment operations and native Live Activity integration. | No WorkManager/background service or operation notification was found. | **Android gap.** Use an ongoing notification/foreground service only for user-initiated work that truly must outlive the screen; use WorkManager for eligible deferred work. | + +Caching must be scoped by server, user, environment, and request identity. Authentication changes, +server changes, environment deletion, and destructive mutations need explicit invalidation. A cache +should never make a failed mutation appear successful. + +### Platform-native integration + +These rows compare user outcomes, not identical APIs. + +| User outcome | iOS mechanism | Appropriate Android direction | Status | +| --- | --- | --- | --- | +| At-a-glance status | Home-screen widgets for status, environments, and updates; App Group snapshots. | Glance widgets backed by explicitly scoped, sanitized snapshots. | **Android gap.** | +| Persistent operation progress | Live Activities and Dynamic Island for deployments. | Ongoing notification, foreground service when justified, and in-app operation surface. | **Android gap.** | +| Voice/automation entry | App Intents, Siri, and Shortcuts for open/start/stop/restart and entity queries. | App shortcuts, deep links, and optionally App Actions where support and value justify them. | **Android gap.** | +| Quick launch | Home-screen quick actions. | Static/dynamic app shortcuts. | **Android gap.** | +| Responsive larger-screen UI | Optional sidebar. | Adaptive navigation rail/drawer and list-detail layouts. | **Android gap.** | +| Share/export | Native log sharing/export. | Android Sharesheet and Storage Access Framework/MediaStore as appropriate. | **Partial.** Android already uses MediaStore/download and share primitives in some flows, but not consistently for logs. | +| File input/output | Native pickers and share sheets. | Android file picker, MediaStore downloads, clipboard, share, and autofill are already used. | **Parity/Android strength.** | +| Alternate application icon | Supported. | Launcher alias approach is possible but launcher-dependent. | **Optional platform difference**, not a parity priority. | +| On-device AI | Apple Foundation Models on supported iOS 26 hardware, with streaming, read tools, and staged confirmed mutations. | If pursued, define provider, privacy boundary, device/server capability, tool permissions, and mandatory confirmation independently. | **Strategic Android gap**, not a literal port. | + +No Android notification, widget, shortcut, share-in, resource app-link, QR setup, or biometric-lock +system was identified at the baseline. These should not be delivered as one monolithic “native +features” project; each needs a clear user scenario and data-security review. + +### Persistence, security, and backup + +| Capability | iOS baseline | Android baseline | Status and action | +| --- | --- | --- | --- | +| Tokens | Shared Keychain with migration and widget access controls. | Encrypted token storage through the Android SDK layer. | **Parity** for secure application storage; review backup/extraction behavior. | +| Preferences | App settings, navigation, cache policy, and account context persist. | DataStore persists server, accent, environment, and navigation tabs; SharedPreferences stores pins. Theme mode does not persist. | **Partial.** Consolidate ownership when adding theme/cache/operation state. | +| Response data | Bounded disk cache. | No equivalent response store. | **Android gap.** | +| Android backup policy | Not applicable. | `app/src/main/AndroidManifest.xml` sets `android:allowBackup="true"` while `res/xml/data_extraction_rules.xml` retains template TODO guidance. | **Android defect/risk.** Explicitly exclude tokens and sensitive cached/server data; validate both legacy and current backup rules. | + +### Quality, testing, CI, and distribution + +| Capability | iOS baseline | Android baseline | Status and action | +| --- | --- | --- | --- | +| Unit tests | Approximately 19 XCTest methods across five files, focused mainly on utilities. | 19 JVM test files and roughly 84 test methods, with useful coverage of navigation, dashboard/updater logic, URL handling, and ANSI parsing. | **Android strength.** | +| UI/instrumented tests | No meaningful UI test suite identified. | Only the template/example instrumentation test was identified. | **Shared gap.** Add a small navigation/auth/destructive-confirmation suite before attempting broad UI automation. | +| Integration/network contract tests | No broad suite identified. | No broad end-to-end contract suite identified. | **Shared gap.** SDK serialization/service tests should carry most wire-contract coverage. | +| CI | No repository CI workflow was identified in the inspected iOS baseline. | CI uses JDK 21/API 35 and runs unit tests/build, with optional signed tag release support. | **Android strength.** | +| Static quality/security gates | No comprehensive suite identified. | No lint, detekt, ktlint, instrumentation, or security scan gate was identified in CI. | **Android gap.** Add targeted gates incrementally; do not create a noisy all-at-once migration. | +| Release maturity | Version 0.5.4/build 260710 and more distribution-oriented product surfaces. App Store status was not confirmed. | Version 0.1.0; minification disabled; repository messaging still warns that the app is not intended for devices. | **Android maturity gap.** Define alpha/beta support criteria before production claims. | +| Release-note integrity | Notes correspond to iOS releases and platform behavior. | `ui/screens/whatsnew/ReleaseNotes.kt` begins at 0.2.1 while the app reports 0.1.0 and contains copied iOS-specific claims. | **Android release-hygiene defect.** Replace with Android-verified notes and enforce version ordering. | + +## SDK/API prerequisites versus Android-only work + +The repository dependency direction remains: + +`Arcane server contract -> libarcane-kotlin -> Android` + +Do not close a parity gap by adding app-local endpoints, streaming parsers, auth handling, or DTO +copies. Inspect the Arcane Go types/handlers first, then implement missing Kotlin SDK support with +tests, then build the Android UI. + +### Likely Android-only work + +These items appear to have sufficient application or SDK foundations and are primarily Android +composition, persistence, or platform work: + +- decide whether to expose the currently unreachable environment list/detail/test surface, and + repair admin-tab drill-down callbacks; +- persist and apply Light/Dark/Auto appearance; +- correct Android source/issue links; +- add an end-user profile route using the SDK's existing user update, password-change, and avatar + retrieval/display support; +- add log copy/share/export; +- add adaptive navigation and authenticated resource deep links; +- add widgets, shortcuts, and ongoing-operation notifications; +- add response caching around existing read services; +- fix all complete-fleet callers to page through `EnvironmentsService` explicitly; +- implement the project-file workspace using the pinned typed SDK operations; +- harden coroutine cancellation and stream ownership; +- define Android backup/extraction rules. + +### Validate SDK coverage before estimating + +These need an explicit SDK/server capability check at the pinned revisions: + +- exact activity stream error, heartbeat, and forward-compatible event handling; +- dynamic/generic resource descriptors, if a generic fallback UI is desired; +- server-version fallbacks for dashboard and fleet updates. + +The pinned Kotlin SDK already exposes user update/password and avatar retrieval, image attestation +operations, explicit environment pagination queries, container pause/kill, typed project-file +changes, and activity/stream APIs. Profile, attestation, container-action, and project-workspace +gaps should therefore begin as Android UI/state work, while still receiving focused serialization +and contract tests against the target server version. + +No current SDK blocker was identified for these top gaps. The pinned SDK revision, the sibling +composite-build revision, and the target server version must nevertheless be recorded together +because active SDK development can change that conclusion. + +### Server or product-definition prerequisites + +- Swarm remains a placeholder in both clients and needs a defined product/API workflow. +- A true network topology graph is not present in either app and should be specified as a shared + enhancement. +- Multi-server profiles require an explicit credential, cache, deep-link, and active-operation + model. +- AI assistance requires a separate product/security design, especially for mutations. + +## Android strengths to preserve + +- Broad typed coverage across operational and administrative domains. +- Strong update/updater and fleet-update surfaces. +- Kotlin SDK boundary avoids the app-local raw DTO workaround used by some iOS vulnerability + flows. +- More JVM unit tests and an active build/test CI baseline than the inspected iOS repository. +- Existing Android-native file picker, MediaStore download, clipboard, share, and autofill + integrations. +- Central ownership of client, authentication, active environment, and capabilities through + `ArcaneClientManager`. +- A practical mobile list/detail Compose architecture rather than a wholesale attempt to copy the + iOS presentation. + +Parity work should extend these strengths. It should not replace typed Android screens with generic +views, create a second client/cache owner, or reproduce Apple-specific UI metaphors. + +## Prioritized roadmap + +### P0: Correctness and reachable functionality + +1. Make change-server safe: clear the prior client, current user, capabilities, cookies, and active + environment, and store credentials/tokens under a normalized server identity. +2. Repair the empty callbacks for Users, Notifications, System, and Roles when used as swappable + main tabs. +3. Decide whether to expose Android's existing environment list/detail/test surface; do not label + it full CRUD without a defined shared workflow. +4. Persist Light/Dark/Auto and apply it at the application theme root. +5. Correct source, documentation, and issue links that point to the iOS repository. +6. Fix silent 20-environment truncation in dashboard, updates, all-environment image updates, and + environment management; add multi-page tests. +7. Replace copied iOS release notes with Android-specific, version-consistent notes, then add + version-gated automatic presentation. +8. Define backup/data-extraction exclusions for tokens, server data, future caches, and operation + state. +9. Audit broad coroutine exception catches and rethrow cancellation. + +### P1: Complete high-frequency operational workflows + +1. Build the existing-project file workspace: file tree, Compose/`.env` editing, save/create, + rename/move/delete, resolution preview, and resolved YAML. +2. Add the signed-in user's profile/account workflow, separate from administrator user management. +3. Complete log search/copy/share/export and lifecycle consistency across container/project logs. +4. Add image attestation list/detail/filter/copy using the existing SDK support. +5. Fill missing container lifecycle/detail actions that the server and SDK support. +6. Add application-owned long-running operation state with reconnect/cancel and an in-app progress + surface. +7. Add lifecycle-aware event refresh and an explicit Activity Center retry path. + +### P2: Resilience and Android-native continuity + +1. Add scoped, bounded stale-read caching for dashboard and high-value resource lists. +2. Standardize stream retry, cancellation, selected-environment changes, and stale-state markers. +3. Add an ongoing notification for user-initiated deployments or updates that outlive a screen; + use foreground execution only when Android policy requires it. +4. Add authenticated resource deep links and dynamic shortcuts. +5. Add adaptive navigation and list-detail layouts for tablets/foldables. +6. Add one or two privacy-reviewed Glance widgets using sanitized snapshots. + +### P3: Product expansion + +1. Evaluate a multi-server profile model. +2. Establish a localization path and move existing text incrementally to resources. +3. Evaluate AI assistance as a platform-neutral product capability with read-only tools first and + explicit confirmation for mutations. +4. Add broader UI/integration testing and incremental lint/static-analysis gates. +5. Revisit Swarm and topology visualization only after shared product requirements exist. + +## Acceptance criteria for parity work + +For each roadmap item: + +- pin the Android, Kotlin SDK, and server revisions used; +- state whether the work is Android-only, SDK-plus-Android, or requires an upstream Arcane change; +- test unknown/optional wire values and older-server behavior where applicable; +- preserve unrelated local changes and keep cross-repository commits independently reviewable; +- run SDK tests before Android tests when the SDK changes; +- report unit/build/device/live-server validation separately; +- update the relevant matrix row and baseline SHA when the work lands. + +The standard local checks are: + +```text +# libarcane-kotlin, when changed +./gradlew :arcane-core:test :arcane-android:assembleRelease + +# android +./gradlew :app:testDebugUnitTest :app:assembleDebug +``` + +Use JDK 21. A successful JVM build does not replace emulator/device verification for navigation, +authentication, streaming, background execution, file handling, or destructive operations. + +## Maintaining this document + +This report belongs in `docs/` because it is durable product and implementation research. +`AGENTS.md` should remain concise operational guidance for contributors and agents; it is not the +only project-persistence mechanism and should not become a product backlog. + +When refreshing this report: + +1. update all pinned baseline revisions before changing conclusions; +2. compare source and reachable navigation, not file names alone; +3. distinguish missing functionality from intentional platform analogues; +4. move completed items to **Parity** and retain any follow-up validation; +5. identify whether an apparent Android gap is actually shared by iOS; +6. avoid treating known iOS workarounds or stubs as the desired architecture. diff --git a/docs/ios-parity-task-list.md b/docs/ios-parity-task-list.md new file mode 100644 index 0000000..b20e2e4 --- /dev/null +++ b/docs/ios-parity-task-list.md @@ -0,0 +1,682 @@ +# Android iOS-parity task list + +Last updated: 2026-07-17 + +This is the working backlog for bringing Arcane Android to product-outcome parity with iOS. It +turns the findings in [the pinned gap analysis](ios-android-gap-analysis.md) into issue-sized work; +it does not repeat that research. + +The source comparison is pinned to: + +- iOS `03f2f3d11e40f759ca62f0207bb3d59418a42933` +- libarcane-swift `c1016b2e0aaebffc112893179560c2462c1a013a` +- Android `c500c262e4e71b094e16ca8afc049f2286d22cfa` +- libarcane-kotlin `991dfdc1ee747c171ebf1b5953fe5fb61ceadfb8` + +Revalidate conclusions against current source before starting an item. Record the Android, Kotlin +SDK, and Arcane server revisions in the resulting issue or pull request. + +## Status legend + +| Status | Meaning | +| --- | --- | +| **Ready** | Evidence and prerequisites are sufficient to begin. | +| **Needs revalidation** | The item is plausible or previously active, but current source, PR, CI, SDK, or runtime behavior must be checked before changing code. | +| **Blocked/Hold** | Do not implement until the named external dependency or product decision changes. | +| **Deferred** | Deliberately sequenced behind foundation work or not required for current parity. | +| **Done/verify** | Later notes suggest the work progressed or landed; confirm current behavior and close or reopen with new evidence. | + +Priorities are **P0** correctness/security, **P1** high-frequency workflow parity, **P2** +resilience/native continuity, and **P3** maturity or optional expansion. Dependencies name task IDs; +`None` means the task can be started independently. + +## Definition of parity and done + +Parity means Android provides the same useful outcome as iOS through Android-native conventions. +It does not mean copying Apple APIs or presentation. Examples include an ongoing notification +instead of a Live Activity, Glance instead of WidgetKit, and Android shortcuts/deep links instead +of App Intents. + +An implementation task is done only when: + +- its acceptance criteria are met and user-visible states cover loading, empty, error, success, + authorization, and unsupported-server behavior as applicable; +- API work follows `Arcane contract -> libarcane-kotlin -> Android`, without app-local endpoint, + DTO, auth, or stream duplication; +- focused tests are added and the Android CI-equivalent checks pass; +- SDK checks pass first when the SDK changes; +- device/emulator and live-server results are reported separately where required; +- sensitive state is scoped by normalized server and user identity; and +- the gap analysis and this backlog are updated when the work lands. + +The standard checks are: + +```text +# libarcane-kotlin, when changed +./gradlew :arcane-core:test :arcane-android:assembleRelease + +# android +./gradlew :app:testDebugUnitTest :app:assembleDebug +``` + +## Phase 0: Revalidate active history and stop correctness leaks + +### PAR-001 — Revalidate PR #29 authentication/session unlock + +- **Status:** Needs revalidation +- **Priority:** P0 +- **Dependencies:** None +- **Scope:** Inspect the current branch, PR #29 state, review feedback, and final CI results. Reproduce + the original session-unlock failure before deciding whether any code remains. +- **Acceptance criteria:** + - The PR's merge/close state, head revision, reviews, and CI conclusion are recorded. + - Login restoration and unlock are exercised for fresh login, restored session, invalid token, + logout, and process recreation. + - The task is closed if current code already fixes the issue; otherwise a new issue describes the + still-reproducible behavior and contains focused regression coverage. + +### PAR-002 — Make change-server state and credential scoping safe + +- **Status:** Ready +- **Priority:** P0 +- **Dependencies:** PAR-001 +- **Scope:** Ensure changing servers cannot reuse the prior server's client, current user, + capabilities, cookies, active environment, token, cache, or operation state. Normalize server + identity and scope credentials by that identity. +- **Acceptance criteria:** + - Selecting change server immediately invalidates all in-memory state belonging to the old server. + - Persisted tokens and other sensitive state cannot be loaded for a different normalized server. + - Tests cover two servers, equivalent URL spellings, logout, invalid credentials, and process + recreation. + - Device testing confirms no prior-server data flashes or actions remain available. + +### PAR-003 — Fix complete-container loading before local filtering + +- **Status:** Ready +- **Priority:** P0 +- **Dependencies:** None +- **Scope:** Make the Containers tab filter a complete result set rather than the SDK's default + first page of 20. Do not assume `limit = -1` is supported: inspect the Arcane handler and SDK + semantics, then use explicit paging unless an unlimited query is documented and safely bounded. +- **Acceptance criteria:** + - The server and SDK behavior for page size, start, limit, ordering, and terminal-page detection is + documented in focused tests or issue evidence. + - An environment with more than 20 containers displays and filters across the full set without + duplicates, omissions, or infinite requests. + - Search/status filters are proven to run after complete loading, or are moved server-side with + equivalent semantics. + - Loading, partial-page failure, refresh, cancellation, and empty states are covered. + +### PAR-004 — Audit all complete-list call sites for silent pagination truncation + +- **Status:** Ready +- **Priority:** P0 +- **Dependencies:** PAR-003 +- **Scope:** Inventory every list call whose UI or calculation claims fleet-wide or complete + results. Prioritize environments, dashboard totals/cards, updates, all-environment image updates, + and environment management. +- **Acceptance criteria:** + - A checked inventory records each caller as intentionally paged, intentionally bounded, or fixed. + - All complete-environment callers work with more than 20 environments. + - Shared paging logic has duplicate/empty/short/final-page, cancellation, and error coverage. + - UI copy does not claim complete totals when a view is intentionally bounded. + +### PAR-005 — Revalidate OIDC and admin-tab navigation + +- **Status:** Needs revalidation +- **Priority:** P0 +- **Dependencies:** PAR-001 +- **Scope:** Device-test current and legacy OIDC callbacks and verify Users, Notifications, System, + and Roles retain drill-down actions both through Settings and when configured as primary tabs. +- **Acceptance criteria:** + - OIDC success, cancel, invalid callback, provider error, and process-recreated callback flows are + exercised on a device/emulator. + - Each affected admin screen opens all supported details/actions from both navigation entry points. + - Back behavior, tab switching, authorization loss, and environment changes do not strand a route. + - Any remaining defect has a focused navigation regression test. + +### PAR-006 — Correct Android links, release notes, and version hygiene + +- **Status:** Ready +- **Priority:** P0 +- **Dependencies:** None +- **Scope:** Replace iOS repository/issue destinations and copied iOS release claims with deliberate + Android links and Android-verified notes. Align displayed notes with the app version. +- **Acceptance criteria:** + - Source, issue, documentation, privacy, and support links resolve to intentional destinations. + - Release notes contain only shipped Android behavior and have consistent version ordering. + - The current app version maps to an appropriate note, and future automatic presentation cannot + show notes for an unshipped version. + - Link and release-note mapping logic has focused coverage. + +### PAR-007 — Define Android backup and data-extraction policy + +- **Status:** Ready +- **Priority:** P0 +- **Dependencies:** PAR-002 +- **Scope:** Replace template backup rules with explicit policy for tokens, server/account data, + future caches, snapshots, and operation state across supported Android versions. +- **Acceptance criteria:** + - Sensitive credentials, cookies, cached server responses, and operation payloads are excluded. + - Legacy backup rules and current data-extraction rules express the same intended boundary. + - Backup/restore behavior is checked on a supported emulator or documented platform test. + - No machine-specific paths, secrets, or backup artifacts are committed. + +### PAR-008 — Audit coroutine cancellation and stream ownership + +- **Status:** Ready +- **Priority:** P0 +- **Dependencies:** None +- **Scope:** Find broad exception handling in stores and streams, rethrow `CancellationException`, + and ensure environment/server/screen changes cancel the correct work. +- **Acceptance criteria:** + - Broad catches no longer convert cancellation into user-visible failures or reconnect loops. + - Tests cover cancellation during refresh, paging, reconnect, and environment/server changes. + - At most one intended stream/job owner remains for each screen-level operation. + - No stale result from a canceled prior environment can overwrite current state. + +## Phase 1: Validate destructive behavior and complete daily workflows + +### PAR-101 — Validate System Prune end to end + +- **Status:** Needs revalidation +- **Priority:** P0 +- **Dependencies:** PAR-002 +- **Scope:** Treat PR #12's UI/result handling as implemented but not operationally proven. Exercise + prune against disposable environments with known resources; do not infer server effects from UI + or unit tests. +- **Acceptance criteria:** + - A real-device/emulator plus live-server matrix covers success, nothing-to-prune, partial/error, + authorization failure, disconnect, cancellation, and repeated invocation. + - Before/after server state proves exactly which eligible resources were removed and retained. + - The UI reports server results accurately and cannot imply success after a failed mutation. + - Results identify tested Android, SDK, server, and API versions. + +### PAR-102 — Match per-environment Upgrade Arcane capability gating + +- **Status:** Needs revalidation +- **Priority:** P1 +- **Dependencies:** PAR-004 +- **Scope:** Recheck current server/SDK support for the iOS `checkUpgrade.canUpgrade` outcome. Show + the environment action only from authoritative capability/version data, not duplicated UI + heuristics. +- **Acceptance criteria:** + - Current Arcane handler/type and both SDK contracts are compared before implementation. + - The action is visible and enabled only when the selected environment can upgrade. + - Unsupported, unauthorized, loading, error, and older-server states are explicit. + - Multi-environment tests prove gating is calculated per environment. + +### PAR-103 — Build the existing-project file workspace + +- **Status:** Ready +- **Priority:** P1 +- **Dependencies:** PAR-002 +- **Scope:** Use the typed Kotlin SDK project-file operations to add a file tree; Compose, `.env`, + and text editing; save/create; rename/move/delete; variable-resolution preview; and resolved YAML. + Keep archived and GitOps projects read-only where required. +- **Acceptance criteria:** + - Users can inspect and perform every supported file mutation with clear dirty/conflict state. + - Destructive actions identify the project/environment and require confirmation. + - Reload, save failure, concurrent server change, unsupported/binary file, and archived/GitOps + states preserve data and explain why an action is unavailable. + - Typed SDK calls are used directly and mapping/state logic has focused tests. + +### PAR-104 — Add signed-in account/profile management + +- **Status:** Ready +- **Priority:** P1 +- **Dependencies:** PAR-002 +- **Scope:** Add a non-admin account destination for viewing/updating display name and email, + changing password, displaying avatar/Gravatar behavior, signing out, and changing server using + existing SDK support. +- **Acceptance criteria:** + - Profile editing and password change validate inputs and report server errors without losing data. + - The route is clearly distinct from administrator user management. + - Updated identity propagates to current-user state and authorization-dependent UI. + - Sign-out and change-server paths satisfy PAR-002's invalidation rules. + +### PAR-105 — Add image attestation workflows + +- **Status:** Ready +- **Priority:** P1 +- **Dependencies:** None +- **Scope:** Use existing Kotlin SDK support to provide attestation list, filter, detail, and safe + statement copy for an image. +- **Acceptance criteria:** + - Empty, malformed/unknown, loading, error, unauthorized, and unsupported-server states are clear. + - Selection remains tied to the correct image digest and environment. + - Copied/exported data is complete and intentionally labeled. + - DTO/serialization coverage remains in the SDK; Android adds state and presentation tests. + +### PAR-106 — Complete container lifecycle and detail actions + +- **Status:** Ready +- **Priority:** P1 +- **Dependencies:** PAR-003 +- **Scope:** Compare current Android actions with supported server/SDK operations and add high-value + omissions such as pause and kill where appropriate, without copying unsupported iOS behavior. +- **Acceptance criteria:** + - An action inventory records parity, intentional omission, permission gate, and server gate. + - Added actions use resource/environment-specific confirmation and accurate result/error feedback. + - State refreshes after success without losing selection or showing stale controls. + - Device/live-server validation covers each destructive lifecycle action added. + +### PAR-107 — Add log and terminal copy/share/export continuity + +- **Status:** Ready +- **Priority:** P1 +- **Dependencies:** PAR-008 +- **Scope:** Provide Android Sharesheet/Storage Access Framework or MediaStore outcomes for container + and project logs, plus consistent search, copy, pause/resume, timestamp, ANSI, retention, and + terminal copy/clear behavior. +- **Acceptance criteria:** + - Users can copy selected content and share/export a clearly scoped log without truncation surprises. + - Large streams use bounded memory and cancellation; secrets receive an explicit product review. + - Export failure, permission/canceled picker, reconnect, and environment changes are safe. + - Shared formatting/state logic has focused tests and device sharing is exercised. + +### PAR-108 — Add lifecycle-aware live event refresh + +- **Status:** Ready +- **Priority:** P1 +- **Dependencies:** PAR-008 +- **Scope:** Provide live-enough Events behavior via a server-supported stream or bounded, + lifecycle-aware polling. Do not invent an app-local protocol. +- **Acceptance criteria:** + - The chosen mechanism and interval/backoff are based on the current Arcane/SDK contract. + - Events update while visible, stop when no longer owned, and do not duplicate or reorder entries. + - Refresh, reconnect, partial failure, environment change, and stale-state UI are covered. + - Battery/network impact is bounded and documented. + +### PAR-109 — Add Activity Center terminal-failure retry + +- **Status:** Ready +- **Priority:** P1 +- **Dependencies:** PAR-008 +- **Scope:** Add an explicit recovery path when live or paginated activity loading terminates, while + preserving healthy data from other environments. +- **Acceptance criteria:** + - Users can identify which environment/source failed and retry it without discarding healthy results. + - Repeated retry is bounded, cancellation-aware, and does not duplicate activities. + - Tests cover terminal stream error, heartbeat timeout, one-environment failure, full failure, and + successful recovery. + +## Phase 2: Own long-running operations before adding system surfaces + +### PAR-201 — Specify the app-level operation store + +- **Status:** Ready +- **Priority:** P1 +- **Dependencies:** PAR-002, PAR-008 +- **Scope:** Write a reviewed design before implementation for deploy, pull, build, update, and other + user-initiated long-running work. Define identity, ownership, persistence, reconnect/reattach, + cancellation, bounded logs, concurrency, process death, server/user/environment scoping, and + v1/v2 behavior. +- **Acceptance criteria:** + - The specification includes state transitions, persistence schema, invalidation, recovery, + retention, concurrency policy, and security boundaries. + - It identifies which operations can reattach server-side and which can only preserve a terminal + or unknown state after process death. + - It assigns one source of truth and explicitly prevents screens, services, and notifications from + becoming competing operation owners. + - Test strategy and migration/rollout plan are included before implementation begins. + +### PAR-202 — Implement the app-level operation store and in-app surface + +- **Status:** Deferred +- **Priority:** P1 +- **Dependencies:** PAR-201 +- **Scope:** Implement the approved store and an in-app operation center/floating progress surface. + Migrate one representative operation first, then the remaining approved operation types. +- **Acceptance criteria:** + - Operations survive screen changes and expose progress, bounded logs, reconnect, cancel, success, + failure, and indeterminate/unknown states from one owner. + - Server, account, and environment changes cannot cross-contaminate operation state. + - Process-death recovery follows the spec and never fabricates successful completion. + - State-machine, persistence, concurrent-operation, cancellation, and migration tests pass. + +### PAR-203 — Add Android ongoing operation notifications + +- **Status:** Deferred +- **Priority:** P2 +- **Dependencies:** PAR-202 +- **Scope:** Project operation-store state into Android notifications. Use foreground execution only + for eligible user-initiated work that Android policy requires to continue beyond the screen. +- **Acceptance criteria:** + - Notifications are projections of PAR-202 state and never own or duplicate the operation. + - Progress, cancel/open actions, completion, failure, permission denial, and notification-disabled + behavior are correct. + - Foreground-service types, lifecycle, disclosure, and recent Android background restrictions are + satisfied. + - Device tests cover backgrounding, rotation, process pressure/recreation, multiple operations, + server change, and notification taps. + +## Phase 3: Resilient reads and Android-native continuity + +### PAR-301 — Design and implement a scoped API response cache + +- **Status:** Ready +- **Priority:** P2 +- **Dependencies:** PAR-002, PAR-004 +- **Scope:** Add bounded stale-read caching for dashboard and selected high-value resource lists. + Scope entries by normalized server, user, environment, request identity, and relevant permissions. + Do not queue mutations. +- **Acceptance criteria:** + - The design defines expiry, LRU/size bounds, request coalescing, invalidation, schema migration, + stale markers, and sensitive-data treatment. + - Initial screens render last-known data offline and visibly distinguish stale from current state. + - Auth/server/environment changes and successful destructive mutations invalidate affected entries. + - Corrupt cache, permission change, refresh race, no-network, and storage-bound tests pass. + +### PAR-302 — Establish a durable sanitized snapshot pipeline + +- **Status:** Deferred +- **Priority:** P2 +- **Dependencies:** PAR-301 +- **Scope:** Derive small, versioned, credential-free snapshots for external surfaces from the + authoritative app/cache state. Keep the snapshot writer separate from widget presentation. +- **Acceptance criteria:** + - The schema contains only reviewed at-a-glance fields and no tokens, cookies, secrets, raw logs, + or mutation capability. + - Snapshots are atomically written, size-bounded, versioned, scoped, and invalidated on logout or + server/account change. + - Freshness and error metadata let consumers avoid implying live status. + - Process-death, corrupt/old schema, account switch, and offline update tests pass. + +### PAR-303 — Add privacy-reviewed Glance widgets + +- **Status:** Deferred +- **Priority:** P2 +- **Dependencies:** PAR-302, PAR-305 +- **Scope:** Add one or two focused Android widgets for outcomes such as fleet status or environments, + backed only by the snapshot pipeline. +- **Acceptance criteria:** + - Widgets never instantiate a second authenticated API client or expose secrets. + - Stale, signed-out, unavailable, and loading states are explicit. + - Taps use authenticated internal routes and cannot open the wrong server/environment. + - Widget resize, refresh limits, reboot, logout, and process-death behavior is device-tested. + +### PAR-304 — Add adaptive navigation and list-detail layouts + +- **Status:** Ready +- **Priority:** P2 +- **Dependencies:** PAR-005 +- **Scope:** Map iOS sidebar outcomes to Android's adaptive rail/drawer/list-detail patterns while + preserving configurable tabs, back behavior, and compact-phone usability. +- **Acceptance criteria:** + - Compact, medium, and expanded widths have deliberate navigation behavior. + - Tab selection and independent route state survive resizing, rotation, and process recreation. + - Large screens do not merely stretch phone layouts where list-detail presentation is appropriate. + - Foldable/tablet emulator tests and accessibility navigation checks are recorded. + +### PAR-305 — Define authenticated resource routes and Android shortcuts + +- **Status:** Ready +- **Priority:** P2 +- **Dependencies:** PAR-002, PAR-005 +- **Scope:** Define stable internal routes for tabs, environments, containers, and projects, then add + a small set of static/dynamic app shortcuts. This is the Android-native counterpart to iOS deep + links, quick actions, and selected App Intents—not a promise of Siri-equivalent behavior. +- **Acceptance criteria:** + - Route identity includes server/environment/resource context and validates authentication, + authorization, existence, and unsupported destinations. + - Cold start, warm start, login-required, stale shortcut, and wrong-server paths fail safely. + - Shortcut publication removes stale or unauthorized entities. + - Navigation and device tests cover external intents and back-stack construction. + +## Phase 4: Quality, accessibility, localization, and distribution + +### PAR-401 — Establish an incremental localization path + +- **Status:** Ready +- **Priority:** P3 +- **Dependencies:** None +- **Scope:** Define string-resource conventions and migrate text as touched, then address the highest + traffic and accessibility-critical screens. iOS is also English-only, so this is product maturity + rather than a literal missing iOS parity item. +- **Acceptance criteria:** + - New user-visible text is resource-backed with plural, formatting, and accessibility conventions. + - A scoped first migration covers authentication, navigation, destructive confirmations, and + operation status without combining all app text into one risky change. + - Pseudolocale checks find no clipping in the migrated flows. + - Formatting does not concatenate grammar-sensitive fragments. + +### PAR-402 — Run a cross-cutting accessibility and interaction audit + +- **Status:** Ready +- **Priority:** P2 +- **Dependencies:** PAR-304 +- **Scope:** Audit TalkBack semantics, focus order, touch targets, contrast, font scaling, reduced + motion, progress announcements, destructive confirmations, and useful haptic feedback. +- **Acceptance criteria:** + - Core auth, navigation, dashboard, container action, project operation, and Settings flows pass a + documented manual accessibility checklist. + - Automated Compose accessibility checks cover representative screens. + - At 200% font scale, critical actions and status remain reachable and understandable. + - Motion/haptics convey state without becoming the only signal. + +### PAR-403 — Add focused UI and live-server test foundations + +- **Status:** Ready +- **Priority:** P2 +- **Dependencies:** PAR-001, PAR-005 +- **Scope:** Replace the template instrumentation test with a small reliable suite for authentication + routing, configurable admin tabs, destructive confirmation, and environment switching. Define a + disposable live-server harness for destructive/streaming validation. +- **Acceptance criteria:** + - Tests are deterministic, use controlled fixtures/fakes where appropriate, and run on a documented + emulator API level. + - CI runs the selected instrumentation suite or clearly separates a scheduled/manual device lane. + - Live-server tests cannot target an unapproved production server and clean up disposable state. + - Unit, instrumented, and live-server claims remain separately reported. + +### PAR-404 — Add incremental static-quality and security gates + +- **Status:** Ready +- **Priority:** P3 +- **Dependencies:** None +- **Scope:** Add Android lint first, then evaluate focused formatting/static analysis and dependency + or secret scanning without introducing a noisy all-at-once migration. +- **Acceptance criteria:** + - Each enabled gate has a documented baseline and fails only on actionable new violations. + - Security-sensitive manifest, backup, exported-component, cleartext, and dependency findings are + triaged rather than blanket-suppressed. + - CI runtime and local commands are documented. + - No mass reformat or unrelated cleanup is bundled with gate enablement. + +### PAR-405 — Prepare F-Droid packaging and metadata + +- **Status:** Ready +- **Priority:** P2 +- **Dependencies:** PAR-006, PAR-007 +- **Scope:** Research and prepare reproducible F-Droid-compatible release packaging and metadata, + including application identity, licensing, source/build recipe, changelog, icons/screenshots, + network-service disclosure, and dependency eligibility. +- **Acceptance criteria:** + - The build recipe succeeds from a clean checkout without proprietary build-time dependencies or + uncommitted machine configuration. + - Version code/name, supported SDKs, signing boundary, update metadata, and release-source tag + workflow are documented. + - Metadata, fastlane assets if chosen, license, privacy/network disclosures, and anti-feature + declarations pass applicable F-Droid validation. + - No signing key or release is created/published as part of this preparation task without separate + authorization. + +### PAR-406 — Define Android alpha/beta release criteria + +- **Status:** Ready +- **Priority:** P3 +- **Dependencies:** PAR-006, PAR-403, PAR-405 +- **Scope:** Replace ambiguous “not intended for devices” messaging with explicit support, + compatibility, verification, known-limitations, and release-channel criteria. +- **Acceptance criteria:** + - Minimum supported Arcane/server, Android, and Kotlin SDK compatibility expectations are stated. + - Alpha/beta promotion gates cover builds, tests, device/live-server matrix, privacy, backup, + upgrade, rollback, and release-note integrity. + - Distribution channels and signing/publishing responsibilities are documented without embedding + credentials. + - User-facing repository messaging matches the actual release state. + +## Hold and deferred product tracks + +### PAR-501 — Arcane Updates counts and navigation + +- **Status:** Blocked/Hold +- **Priority:** P1 after hold clears +- **Dependencies:** Kyle/upstream Arcane Updates changes +- **Scope:** Do not modify current counts, aggregation, or navigation based on prior conclusions. + When upstream work lands, restart analysis from current Arcane handlers/types, SDKs, iOS, and + Android source rather than applying an old patch or assumption. +- **Acceptance criteria:** + - Upstream dependency and target revisions are explicitly recorded before work begins. + - Counts are defined for pagination, permissions, unavailable environments, and server versions. + - Navigation targets use authoritative resource/environment identity. + - Multi-environment live-server tests prove counts and destination consistency. + +### PAR-502 — Multi-server profiles + +- **Status:** Deferred +- **Priority:** P3 +- **Dependencies:** PAR-002, PAR-202, PAR-301, PAR-305 +- **Scope:** Specify profiles only after single-server credential, cache, operation, and route scoping + are correct. +- **Acceptance criteria:** + - The design covers credentials, cookies, caches, snapshots, operations, routes, active selection, + deletion, migration, and concurrent server behavior. + - Switching cannot leak data or actions between servers/users. + - Product scope distinguishes saved profiles from simultaneous fleet aggregation. + - Implementation is split into reviewable persistence, client ownership, and UI tasks. + +### PAR-503 — Evaluate an Android AI assistant + +- **Status:** Deferred +- **Priority:** P3 +- **Dependencies:** Stable operational foundation +- **Scope:** Treat iOS Foundation Models as a product concept, not a portable implementation. Define + provider/device support, privacy, cost, context, tool permissions, and confirmation independently. +- **Acceptance criteria:** + - A product/security design establishes data boundaries and starts with read-only tools. + - Every mutation is staged, explained, scoped, and explicitly confirmed. + - Unsupported devices and offline/provider failure have a complete non-AI app path. + - No provider SDK or server dependency is added before the design is approved. + +### PAR-504 — Swarm workflow + +- **Status:** Deferred +- **Priority:** Not an Android-parity priority +- **Dependencies:** Shared Arcane product/API definition +- **Scope:** Both clients currently expose placeholders. Do not count Swarm as an Android deficit or + implement speculative client behavior. +- **Acceptance criteria:** + - Shared user workflows, Arcane API contract, authorization, and server compatibility are defined. + - SDK work precedes Android UI where required. + - The gap analysis is updated from **Shared gap** only after a real product target exists. + +### PAR-505 — Network topology visualization + +- **Status:** Deferred +- **Priority:** Not an Android-parity priority +- **Dependencies:** Shared product definition and accurate server data +- **Scope:** Both clients present topology primarily as a list. A graph is a shared enhancement and + must not copy known iOS summary stubs. +- **Acceptance criteria:** + - Node, edge, grouping, scale, interaction, and accessibility requirements are defined. + - Counts and relationships come from authoritative server data. + - Large and partially unavailable environments have a usable non-graph fallback. + +## Done/verify candidates + +These items appear to have progressed or landed in later workspace notes. They are not active +implementation work unless current-source or runtime verification finds a regression. + +### PAR-V01 — Pinned dashboard resources and context actions + +- **Status:** Done/verify +- **Priority:** P1 if reopened +- **Dependencies:** PAR-004 +- **Scope:** Verify pins, context actions, persistence, permission changes, and correct environment + targeting on current source. +- **Acceptance criteria:** + - More than one environment and process recreation preserve the intended pins. + - Unauthorized/stale resources disappear or become safely unavailable. + - Close as verified or reopen with a focused reproduction. + +### PAR-V02 — Needs Attention action items + +- **Status:** Done/verify +- **Priority:** P1 if reopened +- **Dependencies:** PAR-004 +- **Scope:** Verify counts, actions, navigation, partial failures, and authorization on current source. +- **Acceptance criteria:** + - Items navigate to the correct server/environment/resource. + - Fleet pagination and partial environment failure do not create false totals. + - Close as verified or reopen with a focused reproduction. + +### PAR-V03 — Dashboard stream foundation and live-stats recovery + +- **Status:** Done/verify +- **Priority:** P1 if reopened +- **Dependencies:** PAR-008 +- **Scope:** Verify reconnect, version fallback, cancellation, connection bounds, and recovery after + server/environment changes. +- **Acceptance criteria:** + - A current target server demonstrates recovery without duplicate streams or stale overwrites. + - Unsupported/legacy behavior is explicit. + - Close as verified or reopen with a focused reproduction. + +### PAR-V04 — Update All environments + +- **Status:** Done/verify +- **Priority:** P1 if reopened +- **Dependencies:** PAR-004, PAR-501 +- **Scope:** Verify complete environment coverage and result reporting, but do not change Arcane + Updates counts/navigation while PAR-501 is on hold. +- **Acceptance criteria:** + - More than 20 environments are included exactly once where eligible. + - Partial, unsupported, unauthorized, cancel, and error results are accurately attributed. + - Close as verified or reopen outside PAR-501 only with independent evidence. + +### PAR-V05 — Environment card actions + +- **Status:** Done/verify +- **Priority:** P1 if reopened +- **Dependencies:** PAR-102 +- **Scope:** Verify current sync, system, upgrade, prune, detail, and active-environment actions + against permissions and server capabilities. +- **Acceptance criteria:** + - Every visible action targets the card's environment and has an accurate enabled state. + - Upgrade behavior is tracked by PAR-102 and prune runtime behavior by PAR-101. + - Close remaining actions as verified or reopen individually. + +### PAR-V06 — Failed Activity badge + +- **Status:** Done/verify +- **Priority:** P1 if reopened +- **Dependencies:** PAR-004, PAR-109 +- **Scope:** Verify count, environment attribution, clearing/retry behavior, and navigation. +- **Acceptance criteria:** + - Pagination, live updates, clearing, and partial failures cannot leave a misleading badge. + - Tapping opens the relevant Activity Center context. + - Close as verified or reopen with a focused reproduction. + +### PAR-V07 — Black bottom inset + +- **Status:** Done/verify +- **Priority:** P2 if reopened +- **Dependencies:** None +- **Scope:** Check representative light/dark themes, gesture/three-button navigation, keyboard, + rotation, and edge-to-edge screens. +- **Acceptance criteria:** + - No unintended black inset appears across the checked configurations. + - Close as verified or reopen with screenshots, device/API details, and a focused reproduction. + +## Backlog maintenance + +- Keep one primary task per issue; split implementation subtasks when they cross repository + boundaries or cannot be reviewed independently. +- Change **Needs revalidation** to **Ready**, **Blocked/Hold**, or **Done/verify** only with current + evidence. +- Move landed work to **Done/verify** until required device/live-server checks pass, then record the + verified outcome in the gap analysis. +- Never reopen a closed candidate merely because it appeared in an older note. +- Refresh the pinned gap-analysis baseline before a broad reprioritization. From dd53076d8b784decbc1777b1110f2340393beb28 Mon Sep 17 00:00:00 2001 From: Michael Kaltner Date: Fri, 17 Jul 2026 13:14:42 -0700 Subject: [PATCH 3/3] docs: add parity backlog checkboxes --- docs/ios-parity-task-list.md | 426 ++++++++++++++++++----------------- 1 file changed, 223 insertions(+), 203 deletions(-) diff --git a/docs/ios-parity-task-list.md b/docs/ios-parity-task-list.md index b20e2e4..6015a9a 100644 --- a/docs/ios-parity-task-list.md +++ b/docs/ios-parity-task-list.md @@ -30,6 +30,19 @@ Priorities are **P0** correctness/security, **P1** high-frequency workflow parit resilience/native continuity, and **P3** maturity or optional expansion. Dependencies name task IDs; `None` means the task can be started independently. +## Checkbox policy + +- The checkbox on each task title records completion; **Status** records workflow state. +- Mark a task `[x]` only when every required acceptance criterion is checked and validation evidence + is recorded. +- Tasks with **Blocked/Hold**, **Deferred**, **Needs revalidation**, or **Done/verify** status remain + unchecked until their required implementation and verification are complete. +- Reopened tasks return to `[ ]`, along with any acceptance criteria that are no longer satisfied. +- Code inspection alone cannot satisfy acceptance criteria that require device, emulator, or live + Arcane server validation. +- Existing progress, including the dashboard items under **Done/verify candidates**, identifies + verification candidates and does not by itself establish completion. + ## Definition of parity and done Parity means Android provides the same useful outcome as iOS through Android-native conventions. @@ -61,7 +74,7 @@ The standard checks are: ## Phase 0: Revalidate active history and stop correctness leaks -### PAR-001 — Revalidate PR #29 authentication/session unlock +- [ ] **PAR-001 — Revalidate PR #29 authentication/session unlock** - **Status:** Needs revalidation - **Priority:** P0 @@ -69,13 +82,13 @@ The standard checks are: - **Scope:** Inspect the current branch, PR #29 state, review feedback, and final CI results. Reproduce the original session-unlock failure before deciding whether any code remains. - **Acceptance criteria:** - - The PR's merge/close state, head revision, reviews, and CI conclusion are recorded. - - Login restoration and unlock are exercised for fresh login, restored session, invalid token, + - [ ] The PR's merge/close state, head revision, reviews, and CI conclusion are recorded. + - [ ] Login restoration and unlock are exercised for fresh login, restored session, invalid token, logout, and process recreation. - - The task is closed if current code already fixes the issue; otherwise a new issue describes the + - [ ] The task is closed if current code already fixes the issue; otherwise a new issue describes the still-reproducible behavior and contains focused regression coverage. -### PAR-002 — Make change-server state and credential scoping safe +- [ ] **PAR-002 — Make change-server state and credential scoping safe** - **Status:** Ready - **Priority:** P0 @@ -84,13 +97,13 @@ The standard checks are: capabilities, cookies, active environment, token, cache, or operation state. Normalize server identity and scope credentials by that identity. - **Acceptance criteria:** - - Selecting change server immediately invalidates all in-memory state belonging to the old server. - - Persisted tokens and other sensitive state cannot be loaded for a different normalized server. - - Tests cover two servers, equivalent URL spellings, logout, invalid credentials, and process + - [ ] Selecting change server immediately invalidates all in-memory state belonging to the old server. + - [ ] Persisted tokens and other sensitive state cannot be loaded for a different normalized server. + - [ ] Tests cover two servers, equivalent URL spellings, logout, invalid credentials, and process recreation. - - Device testing confirms no prior-server data flashes or actions remain available. + - [ ] Device testing confirms no prior-server data flashes or actions remain available. -### PAR-003 — Fix complete-container loading before local filtering +- [ ] **PAR-003 — Fix complete-container loading before local filtering** - **Status:** Ready - **Priority:** P0 @@ -99,15 +112,15 @@ The standard checks are: first page of 20. Do not assume `limit = -1` is supported: inspect the Arcane handler and SDK semantics, then use explicit paging unless an unlimited query is documented and safely bounded. - **Acceptance criteria:** - - The server and SDK behavior for page size, start, limit, ordering, and terminal-page detection is + - [ ] The server and SDK behavior for page size, start, limit, ordering, and terminal-page detection is documented in focused tests or issue evidence. - - An environment with more than 20 containers displays and filters across the full set without + - [ ] An environment with more than 20 containers displays and filters across the full set without duplicates, omissions, or infinite requests. - - Search/status filters are proven to run after complete loading, or are moved server-side with + - [ ] Search/status filters are proven to run after complete loading, or are moved server-side with equivalent semantics. - - Loading, partial-page failure, refresh, cancellation, and empty states are covered. + - [ ] Loading, partial-page failure, refresh, cancellation, and empty states are covered. -### PAR-004 — Audit all complete-list call sites for silent pagination truncation +- [ ] **PAR-004 — Audit all complete-list call sites for silent pagination truncation** - **Status:** Ready - **Priority:** P0 @@ -116,12 +129,12 @@ The standard checks are: results. Prioritize environments, dashboard totals/cards, updates, all-environment image updates, and environment management. - **Acceptance criteria:** - - A checked inventory records each caller as intentionally paged, intentionally bounded, or fixed. - - All complete-environment callers work with more than 20 environments. - - Shared paging logic has duplicate/empty/short/final-page, cancellation, and error coverage. - - UI copy does not claim complete totals when a view is intentionally bounded. + - [ ] A checked inventory records each caller as intentionally paged, intentionally bounded, or fixed. + - [ ] All complete-environment callers work with more than 20 environments. + - [ ] Shared paging logic has duplicate/empty/short/final-page, cancellation, and error coverage. + - [ ] UI copy does not claim complete totals when a view is intentionally bounded. -### PAR-005 — Revalidate OIDC and admin-tab navigation +- [ ] **PAR-005 — Revalidate OIDC and admin-tab navigation** - **Status:** Needs revalidation - **Priority:** P0 @@ -129,13 +142,13 @@ The standard checks are: - **Scope:** Device-test current and legacy OIDC callbacks and verify Users, Notifications, System, and Roles retain drill-down actions both through Settings and when configured as primary tabs. - **Acceptance criteria:** - - OIDC success, cancel, invalid callback, provider error, and process-recreated callback flows are + - [ ] OIDC success, cancel, invalid callback, provider error, and process-recreated callback flows are exercised on a device/emulator. - - Each affected admin screen opens all supported details/actions from both navigation entry points. - - Back behavior, tab switching, authorization loss, and environment changes do not strand a route. - - Any remaining defect has a focused navigation regression test. + - [ ] Each affected admin screen opens all supported details/actions from both navigation entry points. + - [ ] Back behavior, tab switching, authorization loss, and environment changes do not strand a route. + - [ ] Any remaining defect has a focused navigation regression test. -### PAR-006 — Correct Android links, release notes, and version hygiene +- [ ] **PAR-006 — Correct Android links, release notes, and version hygiene** - **Status:** Ready - **Priority:** P0 @@ -143,13 +156,13 @@ The standard checks are: - **Scope:** Replace iOS repository/issue destinations and copied iOS release claims with deliberate Android links and Android-verified notes. Align displayed notes with the app version. - **Acceptance criteria:** - - Source, issue, documentation, privacy, and support links resolve to intentional destinations. - - Release notes contain only shipped Android behavior and have consistent version ordering. - - The current app version maps to an appropriate note, and future automatic presentation cannot + - [ ] Source, issue, documentation, privacy, and support links resolve to intentional destinations. + - [ ] Release notes contain only shipped Android behavior and have consistent version ordering. + - [ ] The current app version maps to an appropriate note, and future automatic presentation cannot show notes for an unshipped version. - - Link and release-note mapping logic has focused coverage. + - [ ] Link and release-note mapping logic has focused coverage. -### PAR-007 — Define Android backup and data-extraction policy +- [ ] **PAR-007 — Define Android backup and data-extraction policy** - **Status:** Ready - **Priority:** P0 @@ -157,12 +170,12 @@ The standard checks are: - **Scope:** Replace template backup rules with explicit policy for tokens, server/account data, future caches, snapshots, and operation state across supported Android versions. - **Acceptance criteria:** - - Sensitive credentials, cookies, cached server responses, and operation payloads are excluded. - - Legacy backup rules and current data-extraction rules express the same intended boundary. - - Backup/restore behavior is checked on a supported emulator or documented platform test. - - No machine-specific paths, secrets, or backup artifacts are committed. + - [ ] Sensitive credentials, cookies, cached server responses, and operation payloads are excluded. + - [ ] Legacy backup rules and current data-extraction rules express the same intended boundary. + - [ ] Backup/restore behavior is checked on a supported emulator or documented platform test. + - [ ] No machine-specific paths, secrets, or backup artifacts are committed. -### PAR-008 — Audit coroutine cancellation and stream ownership +- [ ] **PAR-008 — Audit coroutine cancellation and stream ownership** - **Status:** Ready - **Priority:** P0 @@ -170,14 +183,14 @@ The standard checks are: - **Scope:** Find broad exception handling in stores and streams, rethrow `CancellationException`, and ensure environment/server/screen changes cancel the correct work. - **Acceptance criteria:** - - Broad catches no longer convert cancellation into user-visible failures or reconnect loops. - - Tests cover cancellation during refresh, paging, reconnect, and environment/server changes. - - At most one intended stream/job owner remains for each screen-level operation. - - No stale result from a canceled prior environment can overwrite current state. + - [ ] Broad catches no longer convert cancellation into user-visible failures or reconnect loops. + - [ ] Tests cover cancellation during refresh, paging, reconnect, and environment/server changes. + - [ ] At most one intended stream/job owner remains for each screen-level operation. + - [ ] No stale result from a canceled prior environment can overwrite current state. ## Phase 1: Validate destructive behavior and complete daily workflows -### PAR-101 — Validate System Prune end to end +- [ ] **PAR-101 — Validate System Prune end to end** - **Status:** Needs revalidation - **Priority:** P0 @@ -186,13 +199,13 @@ The standard checks are: prune against disposable environments with known resources; do not infer server effects from UI or unit tests. - **Acceptance criteria:** - - A real-device/emulator plus live-server matrix covers success, nothing-to-prune, partial/error, + - [ ] A real-device/emulator plus live-server matrix covers success, nothing-to-prune, partial/error, authorization failure, disconnect, cancellation, and repeated invocation. - - Before/after server state proves exactly which eligible resources were removed and retained. - - The UI reports server results accurately and cannot imply success after a failed mutation. - - Results identify tested Android, SDK, server, and API versions. + - [ ] Before/after server state proves exactly which eligible resources were removed and retained. + - [ ] The UI reports server results accurately and cannot imply success after a failed mutation. + - [ ] Results identify tested Android, SDK, server, and API versions. -### PAR-102 — Match per-environment Upgrade Arcane capability gating +- [ ] **PAR-102 — Match per-environment Upgrade Arcane capability gating** - **Status:** Needs revalidation - **Priority:** P1 @@ -201,12 +214,12 @@ The standard checks are: the environment action only from authoritative capability/version data, not duplicated UI heuristics. - **Acceptance criteria:** - - Current Arcane handler/type and both SDK contracts are compared before implementation. - - The action is visible and enabled only when the selected environment can upgrade. - - Unsupported, unauthorized, loading, error, and older-server states are explicit. - - Multi-environment tests prove gating is calculated per environment. + - [ ] Current Arcane handler/type and both SDK contracts are compared before implementation. + - [ ] The action is visible and enabled only when the selected environment can upgrade. + - [ ] Unsupported, unauthorized, loading, error, and older-server states are explicit. + - [ ] Multi-environment tests prove gating is calculated per environment. -### PAR-103 — Build the existing-project file workspace +- [ ] **PAR-103 — Build the existing-project file workspace** - **Status:** Ready - **Priority:** P1 @@ -215,13 +228,13 @@ The standard checks are: and text editing; save/create; rename/move/delete; variable-resolution preview; and resolved YAML. Keep archived and GitOps projects read-only where required. - **Acceptance criteria:** - - Users can inspect and perform every supported file mutation with clear dirty/conflict state. - - Destructive actions identify the project/environment and require confirmation. - - Reload, save failure, concurrent server change, unsupported/binary file, and archived/GitOps + - [ ] Users can inspect and perform every supported file mutation with clear dirty/conflict state. + - [ ] Destructive actions identify the project/environment and require confirmation. + - [ ] Reload, save failure, concurrent server change, unsupported/binary file, and archived/GitOps states preserve data and explain why an action is unavailable. - - Typed SDK calls are used directly and mapping/state logic has focused tests. + - [ ] Typed SDK calls are used directly and mapping/state logic has focused tests. -### PAR-104 — Add signed-in account/profile management +- [ ] **PAR-104 — Add signed-in account/profile management** - **Status:** Ready - **Priority:** P1 @@ -230,12 +243,12 @@ The standard checks are: changing password, displaying avatar/Gravatar behavior, signing out, and changing server using existing SDK support. - **Acceptance criteria:** - - Profile editing and password change validate inputs and report server errors without losing data. - - The route is clearly distinct from administrator user management. - - Updated identity propagates to current-user state and authorization-dependent UI. - - Sign-out and change-server paths satisfy PAR-002's invalidation rules. + - [ ] Profile editing and password change validate inputs and report server errors without losing data. + - [ ] The route is clearly distinct from administrator user management. + - [ ] Updated identity propagates to current-user state and authorization-dependent UI. + - [ ] Sign-out and change-server paths satisfy PAR-002's invalidation rules. -### PAR-105 — Add image attestation workflows +- [ ] **PAR-105 — Add image attestation workflows** - **Status:** Ready - **Priority:** P1 @@ -243,12 +256,12 @@ The standard checks are: - **Scope:** Use existing Kotlin SDK support to provide attestation list, filter, detail, and safe statement copy for an image. - **Acceptance criteria:** - - Empty, malformed/unknown, loading, error, unauthorized, and unsupported-server states are clear. - - Selection remains tied to the correct image digest and environment. - - Copied/exported data is complete and intentionally labeled. - - DTO/serialization coverage remains in the SDK; Android adds state and presentation tests. + - [ ] Empty, malformed/unknown, loading, error, unauthorized, and unsupported-server states are clear. + - [ ] Selection remains tied to the correct image digest and environment. + - [ ] Copied/exported data is complete and intentionally labeled. + - [ ] DTO/serialization coverage remains in the SDK; Android adds state and presentation tests. -### PAR-106 — Complete container lifecycle and detail actions +- [ ] **PAR-106 — Complete container lifecycle and detail actions** - **Status:** Ready - **Priority:** P1 @@ -256,12 +269,12 @@ The standard checks are: - **Scope:** Compare current Android actions with supported server/SDK operations and add high-value omissions such as pause and kill where appropriate, without copying unsupported iOS behavior. - **Acceptance criteria:** - - An action inventory records parity, intentional omission, permission gate, and server gate. - - Added actions use resource/environment-specific confirmation and accurate result/error feedback. - - State refreshes after success without losing selection or showing stale controls. - - Device/live-server validation covers each destructive lifecycle action added. + - [ ] An action inventory records parity, intentional omission, permission gate, and server gate. + - [ ] Added actions use resource/environment-specific confirmation and accurate result/error feedback. + - [ ] State refreshes after success without losing selection or showing stale controls. + - [ ] Device/live-server validation covers each destructive lifecycle action added. -### PAR-107 — Add log and terminal copy/share/export continuity +- [ ] **PAR-107 — Add log and terminal copy/share/export continuity** - **Status:** Ready - **Priority:** P1 @@ -270,12 +283,12 @@ The standard checks are: and project logs, plus consistent search, copy, pause/resume, timestamp, ANSI, retention, and terminal copy/clear behavior. - **Acceptance criteria:** - - Users can copy selected content and share/export a clearly scoped log without truncation surprises. - - Large streams use bounded memory and cancellation; secrets receive an explicit product review. - - Export failure, permission/canceled picker, reconnect, and environment changes are safe. - - Shared formatting/state logic has focused tests and device sharing is exercised. + - [ ] Users can copy selected content and share/export a clearly scoped log without truncation surprises. + - [ ] Large streams use bounded memory and cancellation; secrets receive an explicit product review. + - [ ] Export failure, permission/canceled picker, reconnect, and environment changes are safe. + - [ ] Shared formatting/state logic has focused tests and device sharing is exercised. -### PAR-108 — Add lifecycle-aware live event refresh +- [ ] **PAR-108 — Add lifecycle-aware live event refresh** - **Status:** Ready - **Priority:** P1 @@ -283,12 +296,12 @@ The standard checks are: - **Scope:** Provide live-enough Events behavior via a server-supported stream or bounded, lifecycle-aware polling. Do not invent an app-local protocol. - **Acceptance criteria:** - - The chosen mechanism and interval/backoff are based on the current Arcane/SDK contract. - - Events update while visible, stop when no longer owned, and do not duplicate or reorder entries. - - Refresh, reconnect, partial failure, environment change, and stale-state UI are covered. - - Battery/network impact is bounded and documented. + - [ ] The chosen mechanism and interval/backoff are based on the current Arcane/SDK contract. + - [ ] Events update while visible, stop when no longer owned, and do not duplicate or reorder entries. + - [ ] Refresh, reconnect, partial failure, environment change, and stale-state UI are covered. + - [ ] Battery/network impact is bounded and documented. -### PAR-109 — Add Activity Center terminal-failure retry +- [ ] **PAR-109 — Add Activity Center terminal-failure retry** - **Status:** Ready - **Priority:** P1 @@ -296,14 +309,14 @@ The standard checks are: - **Scope:** Add an explicit recovery path when live or paginated activity loading terminates, while preserving healthy data from other environments. - **Acceptance criteria:** - - Users can identify which environment/source failed and retry it without discarding healthy results. - - Repeated retry is bounded, cancellation-aware, and does not duplicate activities. - - Tests cover terminal stream error, heartbeat timeout, one-environment failure, full failure, and + - [ ] Users can identify which environment/source failed and retry it without discarding healthy results. + - [ ] Repeated retry is bounded, cancellation-aware, and does not duplicate activities. + - [ ] Tests cover terminal stream error, heartbeat timeout, one-environment failure, full failure, and successful recovery. ## Phase 2: Own long-running operations before adding system surfaces -### PAR-201 — Specify the app-level operation store +- [ ] **PAR-201 — Specify the app-level operation store** - **Status:** Ready - **Priority:** P1 @@ -313,15 +326,15 @@ The standard checks are: cancellation, bounded logs, concurrency, process death, server/user/environment scoping, and v1/v2 behavior. - **Acceptance criteria:** - - The specification includes state transitions, persistence schema, invalidation, recovery, + - [ ] The specification includes state transitions, persistence schema, invalidation, recovery, retention, concurrency policy, and security boundaries. - - It identifies which operations can reattach server-side and which can only preserve a terminal + - [ ] It identifies which operations can reattach server-side and which can only preserve a terminal or unknown state after process death. - - It assigns one source of truth and explicitly prevents screens, services, and notifications from + - [ ] It assigns one source of truth and explicitly prevents screens, services, and notifications from becoming competing operation owners. - - Test strategy and migration/rollout plan are included before implementation begins. + - [ ] Test strategy and migration/rollout plan are included before implementation begins. -### PAR-202 — Implement the app-level operation store and in-app surface +- [ ] **PAR-202 — Implement the app-level operation store and in-app surface** - **Status:** Deferred - **Priority:** P1 @@ -329,13 +342,13 @@ The standard checks are: - **Scope:** Implement the approved store and an in-app operation center/floating progress surface. Migrate one representative operation first, then the remaining approved operation types. - **Acceptance criteria:** - - Operations survive screen changes and expose progress, bounded logs, reconnect, cancel, success, + - [ ] Operations survive screen changes and expose progress, bounded logs, reconnect, cancel, success, failure, and indeterminate/unknown states from one owner. - - Server, account, and environment changes cannot cross-contaminate operation state. - - Process-death recovery follows the spec and never fabricates successful completion. - - State-machine, persistence, concurrent-operation, cancellation, and migration tests pass. + - [ ] Server, account, and environment changes cannot cross-contaminate operation state. + - [ ] Process-death recovery follows the spec and never fabricates successful completion. + - [ ] State-machine, persistence, concurrent-operation, cancellation, and migration tests pass. -### PAR-203 — Add Android ongoing operation notifications +- [ ] **PAR-203 — Add Android ongoing operation notifications** - **Status:** Deferred - **Priority:** P2 @@ -343,17 +356,17 @@ The standard checks are: - **Scope:** Project operation-store state into Android notifications. Use foreground execution only for eligible user-initiated work that Android policy requires to continue beyond the screen. - **Acceptance criteria:** - - Notifications are projections of PAR-202 state and never own or duplicate the operation. - - Progress, cancel/open actions, completion, failure, permission denial, and notification-disabled + - [ ] Notifications are projections of PAR-202 state and never own or duplicate the operation. + - [ ] Progress, cancel/open actions, completion, failure, permission denial, and notification-disabled behavior are correct. - - Foreground-service types, lifecycle, disclosure, and recent Android background restrictions are + - [ ] Foreground-service types, lifecycle, disclosure, and recent Android background restrictions are satisfied. - - Device tests cover backgrounding, rotation, process pressure/recreation, multiple operations, + - [ ] Device tests cover backgrounding, rotation, process pressure/recreation, multiple operations, server change, and notification taps. ## Phase 3: Resilient reads and Android-native continuity -### PAR-301 — Design and implement a scoped API response cache +- [ ] **PAR-301 — Design and implement a scoped API response cache** - **Status:** Ready - **Priority:** P2 @@ -362,13 +375,13 @@ The standard checks are: Scope entries by normalized server, user, environment, request identity, and relevant permissions. Do not queue mutations. - **Acceptance criteria:** - - The design defines expiry, LRU/size bounds, request coalescing, invalidation, schema migration, + - [ ] The design defines expiry, LRU/size bounds, request coalescing, invalidation, schema migration, stale markers, and sensitive-data treatment. - - Initial screens render last-known data offline and visibly distinguish stale from current state. - - Auth/server/environment changes and successful destructive mutations invalidate affected entries. - - Corrupt cache, permission change, refresh race, no-network, and storage-bound tests pass. + - [ ] Initial screens render last-known data offline and visibly distinguish stale from current state. + - [ ] Auth/server/environment changes and successful destructive mutations invalidate affected entries. + - [ ] Corrupt cache, permission change, refresh race, no-network, and storage-bound tests pass. -### PAR-302 — Establish a durable sanitized snapshot pipeline +- [ ] **PAR-302 — Establish a durable sanitized snapshot pipeline** - **Status:** Deferred - **Priority:** P2 @@ -376,14 +389,14 @@ The standard checks are: - **Scope:** Derive small, versioned, credential-free snapshots for external surfaces from the authoritative app/cache state. Keep the snapshot writer separate from widget presentation. - **Acceptance criteria:** - - The schema contains only reviewed at-a-glance fields and no tokens, cookies, secrets, raw logs, + - [ ] The schema contains only reviewed at-a-glance fields and no tokens, cookies, secrets, raw logs, or mutation capability. - - Snapshots are atomically written, size-bounded, versioned, scoped, and invalidated on logout or + - [ ] Snapshots are atomically written, size-bounded, versioned, scoped, and invalidated on logout or server/account change. - - Freshness and error metadata let consumers avoid implying live status. - - Process-death, corrupt/old schema, account switch, and offline update tests pass. + - [ ] Freshness and error metadata let consumers avoid implying live status. + - [ ] Process-death, corrupt/old schema, account switch, and offline update tests pass. -### PAR-303 — Add privacy-reviewed Glance widgets +- [ ] **PAR-303 — Add privacy-reviewed Glance widgets** - **Status:** Deferred - **Priority:** P2 @@ -391,12 +404,12 @@ The standard checks are: - **Scope:** Add one or two focused Android widgets for outcomes such as fleet status or environments, backed only by the snapshot pipeline. - **Acceptance criteria:** - - Widgets never instantiate a second authenticated API client or expose secrets. - - Stale, signed-out, unavailable, and loading states are explicit. - - Taps use authenticated internal routes and cannot open the wrong server/environment. - - Widget resize, refresh limits, reboot, logout, and process-death behavior is device-tested. + - [ ] Widgets never instantiate a second authenticated API client or expose secrets. + - [ ] Stale, signed-out, unavailable, and loading states are explicit. + - [ ] Taps use authenticated internal routes and cannot open the wrong server/environment. + - [ ] Widget resize, refresh limits, reboot, logout, and process-death behavior is device-tested. -### PAR-304 — Add adaptive navigation and list-detail layouts +- [ ] **PAR-304 — Add adaptive navigation and list-detail layouts** - **Status:** Ready - **Priority:** P2 @@ -404,12 +417,12 @@ The standard checks are: - **Scope:** Map iOS sidebar outcomes to Android's adaptive rail/drawer/list-detail patterns while preserving configurable tabs, back behavior, and compact-phone usability. - **Acceptance criteria:** - - Compact, medium, and expanded widths have deliberate navigation behavior. - - Tab selection and independent route state survive resizing, rotation, and process recreation. - - Large screens do not merely stretch phone layouts where list-detail presentation is appropriate. - - Foldable/tablet emulator tests and accessibility navigation checks are recorded. + - [ ] Compact, medium, and expanded widths have deliberate navigation behavior. + - [ ] Tab selection and independent route state survive resizing, rotation, and process recreation. + - [ ] Large screens do not merely stretch phone layouts where list-detail presentation is appropriate. + - [ ] Foldable/tablet emulator tests and accessibility navigation checks are recorded. -### PAR-305 — Define authenticated resource routes and Android shortcuts +- [ ] **PAR-305 — Define authenticated resource routes and Android shortcuts** - **Status:** Ready - **Priority:** P2 @@ -418,15 +431,15 @@ The standard checks are: a small set of static/dynamic app shortcuts. This is the Android-native counterpart to iOS deep links, quick actions, and selected App Intents—not a promise of Siri-equivalent behavior. - **Acceptance criteria:** - - Route identity includes server/environment/resource context and validates authentication, + - [ ] Route identity includes server/environment/resource context and validates authentication, authorization, existence, and unsupported destinations. - - Cold start, warm start, login-required, stale shortcut, and wrong-server paths fail safely. - - Shortcut publication removes stale or unauthorized entities. - - Navigation and device tests cover external intents and back-stack construction. + - [ ] Cold start, warm start, login-required, stale shortcut, and wrong-server paths fail safely. + - [ ] Shortcut publication removes stale or unauthorized entities. + - [ ] Navigation and device tests cover external intents and back-stack construction. ## Phase 4: Quality, accessibility, localization, and distribution -### PAR-401 — Establish an incremental localization path +- [ ] **PAR-401 — Establish an incremental localization path** - **Status:** Ready - **Priority:** P3 @@ -435,13 +448,13 @@ The standard checks are: traffic and accessibility-critical screens. iOS is also English-only, so this is product maturity rather than a literal missing iOS parity item. - **Acceptance criteria:** - - New user-visible text is resource-backed with plural, formatting, and accessibility conventions. - - A scoped first migration covers authentication, navigation, destructive confirmations, and + - [ ] New user-visible text is resource-backed with plural, formatting, and accessibility conventions. + - [ ] A scoped first migration covers authentication, navigation, destructive confirmations, and operation status without combining all app text into one risky change. - - Pseudolocale checks find no clipping in the migrated flows. - - Formatting does not concatenate grammar-sensitive fragments. + - [ ] Pseudolocale checks find no clipping in the migrated flows. + - [ ] Formatting does not concatenate grammar-sensitive fragments. -### PAR-402 — Run a cross-cutting accessibility and interaction audit +- [ ] **PAR-402 — Run a cross-cutting accessibility and interaction audit** - **Status:** Ready - **Priority:** P2 @@ -449,13 +462,13 @@ The standard checks are: - **Scope:** Audit TalkBack semantics, focus order, touch targets, contrast, font scaling, reduced motion, progress announcements, destructive confirmations, and useful haptic feedback. - **Acceptance criteria:** - - Core auth, navigation, dashboard, container action, project operation, and Settings flows pass a + - [ ] Core auth, navigation, dashboard, container action, project operation, and Settings flows pass a documented manual accessibility checklist. - - Automated Compose accessibility checks cover representative screens. - - At 200% font scale, critical actions and status remain reachable and understandable. - - Motion/haptics convey state without becoming the only signal. + - [ ] Automated Compose accessibility checks cover representative screens. + - [ ] At 200% font scale, critical actions and status remain reachable and understandable. + - [ ] Motion/haptics convey state without becoming the only signal. -### PAR-403 — Add focused UI and live-server test foundations +- [ ] **PAR-403 — Add focused UI and live-server test foundations** - **Status:** Ready - **Priority:** P2 @@ -464,13 +477,13 @@ The standard checks are: routing, configurable admin tabs, destructive confirmation, and environment switching. Define a disposable live-server harness for destructive/streaming validation. - **Acceptance criteria:** - - Tests are deterministic, use controlled fixtures/fakes where appropriate, and run on a documented + - [ ] Tests are deterministic, use controlled fixtures/fakes where appropriate, and run on a documented emulator API level. - - CI runs the selected instrumentation suite or clearly separates a scheduled/manual device lane. - - Live-server tests cannot target an unapproved production server and clean up disposable state. - - Unit, instrumented, and live-server claims remain separately reported. + - [ ] CI runs the selected instrumentation suite or clearly separates a scheduled/manual device lane. + - [ ] Live-server tests cannot target an unapproved production server and clean up disposable state. + - [ ] Unit, instrumented, and live-server claims remain separately reported. -### PAR-404 — Add incremental static-quality and security gates +- [ ] **PAR-404 — Add incremental static-quality and security gates** - **Status:** Ready - **Priority:** P3 @@ -478,13 +491,13 @@ The standard checks are: - **Scope:** Add Android lint first, then evaluate focused formatting/static analysis and dependency or secret scanning without introducing a noisy all-at-once migration. - **Acceptance criteria:** - - Each enabled gate has a documented baseline and fails only on actionable new violations. - - Security-sensitive manifest, backup, exported-component, cleartext, and dependency findings are + - [ ] Each enabled gate has a documented baseline and fails only on actionable new violations. + - [ ] Security-sensitive manifest, backup, exported-component, cleartext, and dependency findings are triaged rather than blanket-suppressed. - - CI runtime and local commands are documented. - - No mass reformat or unrelated cleanup is bundled with gate enablement. + - [ ] CI runtime and local commands are documented. + - [ ] No mass reformat or unrelated cleanup is bundled with gate enablement. -### PAR-405 — Prepare F-Droid packaging and metadata +- [ ] **PAR-405 — Prepare F-Droid packaging and metadata** - **Status:** Ready - **Priority:** P2 @@ -493,16 +506,16 @@ The standard checks are: including application identity, licensing, source/build recipe, changelog, icons/screenshots, network-service disclosure, and dependency eligibility. - **Acceptance criteria:** - - The build recipe succeeds from a clean checkout without proprietary build-time dependencies or + - [ ] The build recipe succeeds from a clean checkout without proprietary build-time dependencies or uncommitted machine configuration. - - Version code/name, supported SDKs, signing boundary, update metadata, and release-source tag + - [ ] Version code/name, supported SDKs, signing boundary, update metadata, and release-source tag workflow are documented. - - Metadata, fastlane assets if chosen, license, privacy/network disclosures, and anti-feature + - [ ] Metadata, fastlane assets if chosen, license, privacy/network disclosures, and anti-feature declarations pass applicable F-Droid validation. - - No signing key or release is created/published as part of this preparation task without separate + - [ ] No signing key or release is created/published as part of this preparation task without separate authorization. -### PAR-406 — Define Android alpha/beta release criteria +- [ ] **PAR-406 — Define Android alpha/beta release criteria** - **Status:** Ready - **Priority:** P3 @@ -510,16 +523,16 @@ The standard checks are: - **Scope:** Replace ambiguous “not intended for devices” messaging with explicit support, compatibility, verification, known-limitations, and release-channel criteria. - **Acceptance criteria:** - - Minimum supported Arcane/server, Android, and Kotlin SDK compatibility expectations are stated. - - Alpha/beta promotion gates cover builds, tests, device/live-server matrix, privacy, backup, + - [ ] Minimum supported Arcane/server, Android, and Kotlin SDK compatibility expectations are stated. + - [ ] Alpha/beta promotion gates cover builds, tests, device/live-server matrix, privacy, backup, upgrade, rollback, and release-note integrity. - - Distribution channels and signing/publishing responsibilities are documented without embedding + - [ ] Distribution channels and signing/publishing responsibilities are documented without embedding credentials. - - User-facing repository messaging matches the actual release state. + - [ ] User-facing repository messaging matches the actual release state. ## Hold and deferred product tracks -### PAR-501 — Arcane Updates counts and navigation +- [ ] **PAR-501 — Arcane Updates counts and navigation** - **Status:** Blocked/Hold - **Priority:** P1 after hold clears @@ -528,12 +541,12 @@ The standard checks are: When upstream work lands, restart analysis from current Arcane handlers/types, SDKs, iOS, and Android source rather than applying an old patch or assumption. - **Acceptance criteria:** - - Upstream dependency and target revisions are explicitly recorded before work begins. - - Counts are defined for pagination, permissions, unavailable environments, and server versions. - - Navigation targets use authoritative resource/environment identity. - - Multi-environment live-server tests prove counts and destination consistency. + - [ ] Upstream dependency and target revisions are explicitly recorded before work begins. + - [ ] Counts are defined for pagination, permissions, unavailable environments, and server versions. + - [ ] Navigation targets use authoritative resource/environment identity. + - [ ] Multi-environment live-server tests prove counts and destination consistency. -### PAR-502 — Multi-server profiles +- [ ] **PAR-502 — Multi-server profiles** - **Status:** Deferred - **Priority:** P3 @@ -541,13 +554,13 @@ The standard checks are: - **Scope:** Specify profiles only after single-server credential, cache, operation, and route scoping are correct. - **Acceptance criteria:** - - The design covers credentials, cookies, caches, snapshots, operations, routes, active selection, + - [ ] The design covers credentials, cookies, caches, snapshots, operations, routes, active selection, deletion, migration, and concurrent server behavior. - - Switching cannot leak data or actions between servers/users. - - Product scope distinguishes saved profiles from simultaneous fleet aggregation. - - Implementation is split into reviewable persistence, client ownership, and UI tasks. + - [ ] Switching cannot leak data or actions between servers/users. + - [ ] Product scope distinguishes saved profiles from simultaneous fleet aggregation. + - [ ] Implementation is split into reviewable persistence, client ownership, and UI tasks. -### PAR-503 — Evaluate an Android AI assistant +- [ ] **PAR-503 — Evaluate an Android AI assistant** - **Status:** Deferred - **Priority:** P3 @@ -555,12 +568,12 @@ The standard checks are: - **Scope:** Treat iOS Foundation Models as a product concept, not a portable implementation. Define provider/device support, privacy, cost, context, tool permissions, and confirmation independently. - **Acceptance criteria:** - - A product/security design establishes data boundaries and starts with read-only tools. - - Every mutation is staged, explained, scoped, and explicitly confirmed. - - Unsupported devices and offline/provider failure have a complete non-AI app path. - - No provider SDK or server dependency is added before the design is approved. + - [ ] A product/security design establishes data boundaries and starts with read-only tools. + - [ ] Every mutation is staged, explained, scoped, and explicitly confirmed. + - [ ] Unsupported devices and offline/provider failure have a complete non-AI app path. + - [ ] No provider SDK or server dependency is added before the design is approved. -### PAR-504 — Swarm workflow +- [ ] **PAR-504 — Swarm workflow** - **Status:** Deferred - **Priority:** Not an Android-parity priority @@ -568,11 +581,11 @@ The standard checks are: - **Scope:** Both clients currently expose placeholders. Do not count Swarm as an Android deficit or implement speculative client behavior. - **Acceptance criteria:** - - Shared user workflows, Arcane API contract, authorization, and server compatibility are defined. - - SDK work precedes Android UI where required. - - The gap analysis is updated from **Shared gap** only after a real product target exists. + - [ ] Shared user workflows, Arcane API contract, authorization, and server compatibility are defined. + - [ ] SDK work precedes Android UI where required. + - [ ] The gap analysis is updated from **Shared gap** only after a real product target exists. -### PAR-505 — Network topology visualization +- [ ] **PAR-505 — Network topology visualization** - **Status:** Deferred - **Priority:** Not an Android-parity priority @@ -580,16 +593,16 @@ The standard checks are: - **Scope:** Both clients present topology primarily as a list. A graph is a shared enhancement and must not copy known iOS summary stubs. - **Acceptance criteria:** - - Node, edge, grouping, scale, interaction, and accessibility requirements are defined. - - Counts and relationships come from authoritative server data. - - Large and partially unavailable environments have a usable non-graph fallback. + - [ ] Node, edge, grouping, scale, interaction, and accessibility requirements are defined. + - [ ] Counts and relationships come from authoritative server data. + - [ ] Large and partially unavailable environments have a usable non-graph fallback. ## Done/verify candidates These items appear to have progressed or landed in later workspace notes. They are not active implementation work unless current-source or runtime verification finds a regression. -### PAR-V01 — Pinned dashboard resources and context actions +- [ ] **PAR-V01 — Pinned dashboard resources and context actions** - **Status:** Done/verify - **Priority:** P1 if reopened @@ -597,22 +610,22 @@ implementation work unless current-source or runtime verification finds a regres - **Scope:** Verify pins, context actions, persistence, permission changes, and correct environment targeting on current source. - **Acceptance criteria:** - - More than one environment and process recreation preserve the intended pins. - - Unauthorized/stale resources disappear or become safely unavailable. - - Close as verified or reopen with a focused reproduction. + - [ ] More than one environment and process recreation preserve the intended pins. + - [ ] Unauthorized/stale resources disappear or become safely unavailable. + - [ ] Close as verified or reopen with a focused reproduction. -### PAR-V02 — Needs Attention action items +- [ ] **PAR-V02 — Needs Attention action items** - **Status:** Done/verify - **Priority:** P1 if reopened - **Dependencies:** PAR-004 - **Scope:** Verify counts, actions, navigation, partial failures, and authorization on current source. - **Acceptance criteria:** - - Items navigate to the correct server/environment/resource. - - Fleet pagination and partial environment failure do not create false totals. - - Close as verified or reopen with a focused reproduction. + - [ ] Items navigate to the correct server/environment/resource. + - [ ] Fleet pagination and partial environment failure do not create false totals. + - [ ] Close as verified or reopen with a focused reproduction. -### PAR-V03 — Dashboard stream foundation and live-stats recovery +- [ ] **PAR-V03 — Dashboard stream foundation and live-stats recovery** - **Status:** Done/verify - **Priority:** P1 if reopened @@ -620,11 +633,11 @@ implementation work unless current-source or runtime verification finds a regres - **Scope:** Verify reconnect, version fallback, cancellation, connection bounds, and recovery after server/environment changes. - **Acceptance criteria:** - - A current target server demonstrates recovery without duplicate streams or stale overwrites. - - Unsupported/legacy behavior is explicit. - - Close as verified or reopen with a focused reproduction. + - [ ] A current target server demonstrates recovery without duplicate streams or stale overwrites. + - [ ] Unsupported/legacy behavior is explicit. + - [ ] Close as verified or reopen with a focused reproduction. -### PAR-V04 — Update All environments +- [ ] **PAR-V04 — Update All environments** - **Status:** Done/verify - **Priority:** P1 if reopened @@ -632,11 +645,11 @@ implementation work unless current-source or runtime verification finds a regres - **Scope:** Verify complete environment coverage and result reporting, but do not change Arcane Updates counts/navigation while PAR-501 is on hold. - **Acceptance criteria:** - - More than 20 environments are included exactly once where eligible. - - Partial, unsupported, unauthorized, cancel, and error results are accurately attributed. - - Close as verified or reopen outside PAR-501 only with independent evidence. + - [ ] More than 20 environments are included exactly once where eligible. + - [ ] Partial, unsupported, unauthorized, cancel, and error results are accurately attributed. + - [ ] Close as verified or reopen outside PAR-501 only with independent evidence. -### PAR-V05 — Environment card actions +- [ ] **PAR-V05 — Environment card actions** - **Status:** Done/verify - **Priority:** P1 if reopened @@ -644,22 +657,22 @@ implementation work unless current-source or runtime verification finds a regres - **Scope:** Verify current sync, system, upgrade, prune, detail, and active-environment actions against permissions and server capabilities. - **Acceptance criteria:** - - Every visible action targets the card's environment and has an accurate enabled state. - - Upgrade behavior is tracked by PAR-102 and prune runtime behavior by PAR-101. - - Close remaining actions as verified or reopen individually. + - [ ] Every visible action targets the card's environment and has an accurate enabled state. + - [ ] Upgrade behavior is tracked by PAR-102 and prune runtime behavior by PAR-101. + - [ ] Close remaining actions as verified or reopen individually. -### PAR-V06 — Failed Activity badge +- [ ] **PAR-V06 — Failed Activity badge** - **Status:** Done/verify - **Priority:** P1 if reopened - **Dependencies:** PAR-004, PAR-109 - **Scope:** Verify count, environment attribution, clearing/retry behavior, and navigation. - **Acceptance criteria:** - - Pagination, live updates, clearing, and partial failures cannot leave a misleading badge. - - Tapping opens the relevant Activity Center context. - - Close as verified or reopen with a focused reproduction. + - [ ] Pagination, live updates, clearing, and partial failures cannot leave a misleading badge. + - [ ] Tapping opens the relevant Activity Center context. + - [ ] Close as verified or reopen with a focused reproduction. -### PAR-V07 — Black bottom inset +- [ ] **PAR-V07 — Black bottom inset** - **Status:** Done/verify - **Priority:** P2 if reopened @@ -667,13 +680,20 @@ implementation work unless current-source or runtime verification finds a regres - **Scope:** Check representative light/dark themes, gesture/three-button navigation, keyboard, rotation, and edge-to-edge screens. - **Acceptance criteria:** - - No unintended black inset appears across the checked configurations. - - Close as verified or reopen with screenshots, device/API details, and a focused reproduction. + - [ ] No unintended black inset appears across the checked configurations. + - [ ] Close as verified or reopen with screenshots, device/API details, and a focused reproduction. ## Backlog maintenance - Keep one primary task per issue; split implementation subtasks when they cross repository boundaries or cannot be reviewed independently. +- Treat this central list as canonical; do not pre-create a file for every task. +- Create `docs/tasks/-.md` only when a substantial task enters active work and needs + design or validation notes, and link that work packet from its central task entry while active. +- After completion, move durable decisions and evidence to the appropriate permanent location, then + remove the temporary task file and link when they no longer add value. +- Retain a task file only when it contains lasting architectural rationale; prefer moving that + rationale into an ADR or another permanent document. - Change **Needs revalidation** to **Ready**, **Blocked/Hold**, or **Done/verify** only with current evidence. - Move landed work to **Done/verify** until required device/live-server checks pass, then record the