iris is the framework alone; the app is one crate in app-rust/

Iris: "the organization of the rust rewrite is a mess right now... there
shouldn't be anything related to the app inside of iris. Iris is supposed
to be the UI framework alone." And, on the crate count: "I'm confused why
the app only code needs more than one crate though."

Nine cargo workspaces become three, and the port's project code -- which
sat in five places, four of them inside the framework -- becomes one crate,
`ai-app`, in `app-rust/`:

  client-core                -> app-rust/src/client
  iris/transcript-ui         -> app-rust/src/ui
  iris/transcript-fixture    -> app-rust/src/ui/fixture.rs + tests/ + touch/
  iris/desktop-app           -> app-rust/src/desktop + src/bin_desktop.rs
  iris/android-app           -> app-rust/src/android + android-project/
  android-shell              -> app-rust/src/shell

iris/ keeps core, macro, the iris crate, tabs-ui and rig-input, and now
mentions no session, transcript, setup or server anywhere.

Only two of the old splits had a reason that survived reading. event-model
stays a crate at the repo root because server/ depends on it too, so a
crate is what makes the backend and the app agree by construction. The two
Android .so names looked like a hard constraint -- a package produces one
library artifact -- until P2 turned out to already plan merging those two
Android apps into one; both faces now come out of libai_app.so, picked
apart by features so `--no-default-features --features shell` keeps wgpu,
parley and iris out of the Compose app's APK. docs/RUST.md's "One app
crate" has the rest, including what each remaining feature is for.

DECISIONS.md and SUBAGENTS.md move into docs/ with everything else.

Verified: ./run-tests.sh and `cd iris && cargo test` green, clippy and fmt
clean in all five workspaces, `cargo ndk -t x86_64` links libai_app.so,
build-apk.sh produces an APK that installs and launches on this checkout's
emulator (Gl ... virgl, as expected), and the phone-sized headless
screenshot renders the transcript unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
irisandClaude Opus 5 committed 2026-09-08 23:36:38 -04:00
1 parent e9a6562dc6
commit 6d5a231f5c
100 files changed
+924 -3295

No files matched your search

+108 -1
View File
@@ -2089,7 +2089,7 @@ column above.
`Tasks::redraw_handle`'s design had anticipated) -- both in I5's own box,
both in `IRIS.md`.
- **Design choices for the two pieces before this are summarised in
`DECISIONS.md`** at the repo root, which is the file Iris reads for
`DECISIONS.md`** in `docs/`, which is the file Iris reads for
choices made without her.
- **E4 done, 2026-09-05.** `iris/desktop-app`: a winit window with a
session list beside `transcript-ui`'s screen (`build_tree`), against a
@@ -8394,3 +8394,110 @@ again `--features iris/force-gles` on virgl, identical output. Layer 3:
`build-apk.sh release` (arm64) builds, and the x86_64 debug bench ran a
full fling/stream/type/keyboard cycle on the emulator's GLES adapter with
no crash.
## One app crate, 2026-09-08 (the repository reorganised)
Iris, reading the tree: *"the organization of the rust rewrite is a mess
right now… there shouldn't be anything related to the app inside of iris.
Iris is supposed to be the UI framework alone."* Then, on the crate count:
*"I'm confused why the app only code needs more than one crate though."*
### What it was
Nine cargo workspaces, each with its own `Cargo.lock` and `target/`, and
the port's project code in five places — `iris/transcript-ui`,
`iris/transcript-fixture`, `iris/desktop-app`, `iris/android-app` (all
*inside* the framework), plus `client-core` and `android-shell` at the
root. Two root markdown files (`DECISIONS.md`, `SUBAGENTS.md`) sat outside
`docs/`.
### What it is
**One crate, `ai-app`, in `app-rust/`.** Modules, not crates:
| was | is |
|----------------------------------------|-----------------------------------|
| `client-core` | `src/client` |
| `iris/transcript-ui` | `src/ui` |
| `iris/transcript-fixture` | `src/ui/fixture.rs` + `tests/`, `touch/` |
| `iris/desktop-app` | `src/desktop` + `src/bin_desktop.rs` |
| `iris/android-app` | `src/android` + `android-project/` |
| `android-shell` | `src/shell` |
`iris/` now holds `core`, `macro`, the `iris` crate, `tabs-ui` and
`rig-input` — framework only, with no mention of a session, a transcript,
a setup or a server anywhere in it.
### Why one crate really is enough
Each split had a stated reason at the time; on inspection only two
survived, and one of those is not in `app-rust` at all.
- **`client-core` separate from the UI** was "pure logic with no framework
dependency". That property is worth keeping and does not need a crate:
`iris` is behind the `screens` feature and `src/client/` may not reach
it. An invariant on a module instead of on a manifest, stated in
docs/CLIENT_CORE.md.
- **`transcript-fixture` separate from `transcript-ui`** was so the
headless harness and a desktop window opened the same bytes. Both are
now the same crate, so it is `src/ui/fixture.rs` behind a `fixture`
feature (1.9 MB of `include_str!` must not reach a phone build) with the
six harness suites in `tests/`.
- **Two Android `.so` names**, `libmain.so` for the iris app and
`libandroid_shell.so` for the Kotlin shell's JNI bridge, looked like the
one hard constraint: a package produces exactly one library artifact.
It dissolves because **P2 already plans to merge those two Android apps
into one**. So both faces come out of one package as `libai_app.so`,
picked apart by features (`--no-default-features --features shell` keeps
wgpu, parley and iris out of the Compose app's APK), which is the
direction of travel rather than a workaround. `xtask apk` and
`app/shellApp`'s `System.loadLibrary` were updated to match.
- **A desktop binary and an Android cdylib in one package** is not a
problem: `iris` itself already target-gates winit against android-view
in one manifest, and the same table does it here. `build-apk.sh` passes
`--lib` so `cargo ndk` never tries to build the desktop binary.
- **`event-model` stays a crate**, and is the one split that was never
optional: `server/` depends on it too, so a crate is what makes the
backend and the app agree by construction. Iris chose to leave it at the
repo root rather than inside `app-rust/`, since it is the contract
between the two rather than app code.
So: three workspaces where there were nine — `event-model`, `server`,
`app-rust` — plus `iris` and `xtask`.
### Things that moved with it, worth knowing
- **The toolchain pin is per directory.** `app-rust/rust-toolchain.toml` is
a copy of `iris/`'s, because `client-core` used to build on stable and
now shares iris's dated nightly. Two consequences appeared immediately:
two `needless_range_loop` warnings in the markdown highlighter (fixed),
and four `AtomicBool::fetch_update` deprecations from inside `jni`
0.22's `native_method!` macro. The last are not ours to migrate — the
fix is a `jni` release — so `src/lib.rs` carries an `#[allow(deprecated)]`
scoped to `mod shell` with that reason written at it.
- **The Android release profile is `android-release`, not `release`.** The
aggressive settings `iris/android-app` had (`panic = "abort"`,
`opt-level = "s"`, fat LTO) would otherwise apply to the desktop build
too, which is a testing surface. `build-apk.sh` passes
`--profile android-release` / `--profile android-dev`.
- **`iris/run-headless.sh` grew `--dir DIR`**, defaulting to `iris/`. The
rig belongs to the framework; the examples it usually runs no longer do.
`replay-touch` is still built from `iris/`.
- **The log target changed** from `client_core` to `ai_app`
(`src/client/log_ring.rs`'s `is_own_target`).
- **Not renamed, deliberately:** the Android application id and Java
package are still `dev.iris.android.demo` and the label is still "iris
android-view demo", both now misleading. Changing them changes the app's
identity on Iris's phone (a side-by-side install rather than an upgrade)
and the `DevLogProvider` authority Dev Updater reads, so it is hers to
decide rather than a tidy-up to make quietly.
### Verified
`./run-tests.sh` (event-model, server, app-rust) and `cd iris && cargo
test` green; `cargo clippy --all-targets` and `cargo fmt` clean in every
workspace. `cargo ndk -t x86_64` links `libai_app.so`; `./build-apk.sh
debug --abi x86_64` produces an installable APK; installed and launched on
this checkout's emulator, drawing through `Gl … virgl` as expected. The
phone-sized headless screenshot (`run-headless.sh phone --phone --dir
../app-rust --shot …`) renders the transcript unchanged.