Make the Rust client the sole app

This commit is contained in:
iris committed 2026-09-11 01:18:24 -04:00
1 parent a8602c1626
commit d8bb1699a8
230 files changed
+762 -27300

No files matched your search

+11 -14
View File
@@ -6,8 +6,8 @@ need a front end at all, and owning the client means fixing what the official
app gets wrong (it won't deliver a typed message until the turn fully
finishes, where the TUI injects it at the next tool boundary).
Same shape as `../dev-updater`: a Rust (Axum) backend on the desktop, a
Kotlin/Compose Android app, pinned self-signed TLS between them.
Same shape as `../dev-updater`: a Rust/Axum backend on the desktop and a
shared Rust client for Android and desktop, with pinned self-signed TLS.
This file records decisions with their date, their rationale, and what was
rejected. Update it in place when one changes; `AGENTS.md` is the working
@@ -23,7 +23,7 @@ screens). SSH falls out of the same shape: a remote session is the identical
command wrapped in `ssh host …`, and the driver never learns which it got.
```
Android app (Compose)
Android or desktop app (Rust/iris)
│ HTTPS (pinned CA) — REST for actions, SSE for live events
backend (Rust/Axum, desktop)
@@ -702,15 +702,10 @@ ssh case are one implementation.
a hardcoded IP. The CA is created once and left alone; the leaf is reissued
every start, so covering a new address is a restart. **Regenerating the CA
strands the installed app** — the one-way door.
- Unlike dev-updater, the pinned CA is **not a constant in the source**:
the build reads `$XDG_CONFIG_HOME/ai-app/certs/ca.pem` from the machine
doing the build and generates the constant (`generatePinnedCert` in
`app/androidApp/build.gradle.kts`; `AI_APP_CA` overrides). That does
three things at once — the trust anchor follows the build machine, so an
APK built in the dev VM is only good for its emulator; there is no second
anchor to add for development and forget to remove; and regenerating a CA
needs a rebuild rather than a paste, so a stale constant cannot quietly
disagree with the server.
- The enrollment link carries the CA certificate. `app/src/client/config.rs`
decodes it and the transport pins it for every connection. A malformed or
absent CA refuses enrollment rather than silently weakening TLS. This lets
one APK enroll against either the host or an isolated development server.
- **The dev VM is untrusted** (2026-08-25): not malicious, but it could
become so. The repo is a read-write mount shared between the VM and the
backend host, so everything in it — source, binaries, and the shell scripts
@@ -797,8 +792,10 @@ ssh case are one implementation.
## App (`app/`)
Kotlin + Compose Multiplatform, single `:androidApp` module, same versions as
dev-updater (Kotlin 2.4.x, CMP 1.11.x, JDK 21).
One Rust crate owns platform-free client logic and Iris widget trees. Android
and desktop entry points contain only their host integration. Android is
packaged by a thin Java activity under `android-project/`; it does not contain
a second UI implementation.
1. **Session list** — kind icon, title, setup, model, status, last activity.
Sessions awaiting an answer sort to the top: the "your turn" inbox.