224 lines
10 KiB
Markdown
224 lines
10 KiB
Markdown
# Iris extraction handoff
|
|
|
|
Operational handoff for pulling Iris out of ai-app into a standalone framework.
|
|
Not a decisions log; delete it when the extraction is done.
|
|
|
|
## Read this first
|
|
|
|
**Pull request #11 has been reviewed four times; the fourth is answered in
|
|
`29d390d` and the fifth has not arrived.** Check for one before doing anything
|
|
else:
|
|
|
|
```sh
|
|
TOKEN=$(cat ~/.config/gitea/token)
|
|
curl -s -H "Authorization: token $TOKEN" \
|
|
https://git.arirex.me/api/v1/repos/iris/iris/pulls/11/reviews
|
|
curl -s -H "Authorization: token $TOKEN" \
|
|
https://git.arirex.me/api/v1/repos/iris/iris/pulls/11/reviews/<id>/comments
|
|
curl -s -H "Authorization: token $TOKEN" \
|
|
https://git.arirex.me/api/v1/repos/iris/iris/issues/11/comments
|
|
```
|
|
|
|
Check the newest `submitted_at` rather than assuming the first result is
|
|
current. My replies are ordinary issue comments on the same PR and say what
|
|
each change was for.
|
|
|
|
**Agree a design before sending another variation of it.** The owner stopped
|
|
the fourth round with *"we should probably agree on the design here rather
|
|
than you keep submitting variations that I review"*. When a review comes back
|
|
about the shape of something rather than a defect in it, put the options and a
|
|
recommendation in front of her and implement what she picks. She chose the
|
|
per-image bind group for textures on 2026-09-13; the alternatives were
|
|
packing images into arrays like atlas pages, and a bindless `binding_array`
|
|
(ruled out by Android support).
|
|
|
|
## Stop point
|
|
|
|
- Canonical Iris: `git@git.arirex.me:iris/iris.git`, `main` at `0f6a28b`
|
|
(the squash merge of #10).
|
|
- Agent fork: `git@git.arirex.me:iris-ai/iris.git`. The bot cannot push
|
|
canonical; work in the fork and open PRs into `iris/iris:main`.
|
|
- **#11** `split/11-texture-bindings`, worktree `/home/bob/repos/iris-pr11`,
|
|
head `29d390d`, nine commits on top of `0f6a28b`. Reviewed four times, all
|
|
answered.
|
|
- **#12** `split/12-pointer-routing`, worktree `/home/bob/repos/iris-pr12`,
|
|
head `028521b`. A scroll falling through a hovered button. Not reviewed as
|
|
of the last check. Independent of #11 and can merge in either order.
|
|
- `/home/bob/repos/ai-app-2` is on `rustify`, worktree clean.
|
|
|
|
## What #11 became
|
|
|
|
It started as "draw the glyph atlas as an array texture" and four rounds of
|
|
review turned it into a rework of how primitives are drawn. Worth knowing
|
|
before reading a new review, because the earlier rounds are what produced this
|
|
shape:
|
|
|
|
- **Atlas pages are their own thing.** `GlyphAtlas` owns its page images and
|
|
emits dirty rectangles; `GpuPages` owns the array texture they upload to.
|
|
`Textures` holds standalone images only.
|
|
- **A primitive registers itself by being drawn.** The type carries its own
|
|
WGSL and `PrimitiveRegistry` keys ids by `TypeId`, so the kind comes from the
|
|
type and there are no `RECT`/`GLYPH`/`TEXTURE` constants. Built-ins are
|
|
seeded up front only so first-draw order cannot shuffle them.
|
|
- **Nothing dispatches dynamically.** Push, free, renumber, upload and draw are
|
|
identical for every primitive; only the entry size and the pipeline differ,
|
|
and those are data. `InstanceList` carries a runtime stride and its data as
|
|
bytes. Measured: 0.2ns per write over a statically typed list, against 1.6ns
|
|
for a trait object.
|
|
- **The shared group is what every pipeline gets**: window, masks, the glyph
|
|
atlas array, and the one sampler. A mask texture would go here too. A
|
|
primitive that samples an image of its own declares `Primitive::TEXTURE`,
|
|
which gives it an image bind group, a draw call per instance, and the slot
|
|
recorded at write time; no other pipeline mentions textures at all.
|
|
- **`shader.wgsl` became `shader/prelude.wgsl` plus one file per primitive**,
|
|
because one module cannot declare two types at the same binding. The prelude
|
|
carries the window, masks, atlas, sampler, vertex shader and `masked()`, and
|
|
is the one place binding numbers are written down.
|
|
- **Order within a layer means nothing** and nothing claims otherwise -- but
|
|
the widgets do rely on it today, since a `Text` over a `Rect` in one layer
|
|
only works because glyph registers after rect. Open question, raised on the
|
|
PR: text may need a layer of its own.
|
|
|
|
## Standing instructions from the owner
|
|
|
|
- Pull Iris out even if the Rust application switchover is not accepted. No
|
|
app, session, transcript, setup or server concepts in Iris; the dependency
|
|
runs one way from `app/` to Iris.
|
|
- **Small, coherent PRs.** The original extraction PR was too large to review.
|
|
A slice may be redone rather than transplanted, and need not remove every old
|
|
feature. Independent PRs may be open at once so work continues during review.
|
|
- Do not recreate an `ai` branch in canonical Iris; the fork is the boundary.
|
|
- **Never rewrite a pushed branch.** Follow review with additive commits.
|
|
- Respond to each review finding with a fix or a concise explanation. Do not
|
|
add a ceremonial comment when the changed code already answers it.
|
|
|
|
## The review gate
|
|
|
|
`~/.claude/MACHINE.md` now carries a machine-wide rule, and the procedure is
|
|
the installed **`pre-submit-review`** skill. It is not optional and not
|
|
project-specific: build clean, review the code, review the comments separately
|
|
once the code has settled, then verify the claim by running it. The fixes a
|
|
review produces are themselves unreviewed code, so the passes repeat until a
|
|
round finds nothing.
|
|
|
|
Running it on #11 found four defects that format, clippy, tests and five
|
|
headless renders had all passed — including one hidden *by* the tests passing,
|
|
where an image alone in a layer failed GPU validation because every other case
|
|
happened to have a rectangle in the same layer leaving a bind group set. That
|
|
is the shape to hunt for.
|
|
|
|
`audit.sh` in the skill directory prints every comment line a branch adds
|
|
against a base ref, for an explicit verdict each. The owner's standing
|
|
complaint is verbose agent comments; the default verdict is delete.
|
|
|
|
## Repository topology
|
|
|
|
### ai-app checkout
|
|
|
|
- `/home/bob/repos/ai-app-2`, `origin = git@git.arirex.me:iris/ai-app.git`,
|
|
branch `rustify`.
|
|
- `iris/` is a submodule pinned at `32f6ad8`, the complete extracted snapshot,
|
|
and `.gitmodules` points at the **bot fork**, not canonical Iris.
|
|
- Do not change either casually: ai-app needs the complete snapshot while
|
|
canonical Iris is only partly caught up. Reconcile when canonical contains
|
|
what ai-app needs, or when the owner accepts a temporarily non-building pin.
|
|
|
|
### standalone Iris checkout
|
|
|
|
- `/home/bob/repos/iris`, `origin` = fork, `upstream` = canonical.
|
|
- Fork `main` and `origin/archive/full-extraction` both name `32f6ad8`, the
|
|
target snapshot. `history/full` names the source-history result `a615bcd`.
|
|
- **Do not reset, overwrite or force-push fork `main`**: it is both the target
|
|
reference and the commit ai-app pins.
|
|
- Start each new branch from current `upstream/main` in its own worktree:
|
|
|
|
```sh
|
|
cd /home/bob/repos/iris && git fetch upstream
|
|
git worktree add -b split/13-name /home/bob/repos/iris-pr13 upstream/main
|
|
```
|
|
|
|
The other `/home/bob/repos/iris-pr*` worktrees hold merged branches. They are
|
|
readable references; do not build new work on them.
|
|
|
|
## Merged so far
|
|
|
|
| PR | On canonical `main` |
|
|
| --- | --- |
|
|
| #2 | Build on the current nightly (`4275314`) |
|
|
| #3 | Request a frame after resize (`936fbdd`) |
|
|
| #4 | Decouple `iris-core` from winit (`465e430`) |
|
|
| #5 | Use vsync by default (`ec2b5d4`) |
|
|
| #6 | Notify winit before presenting (`db9b0f2`) |
|
|
| #7 | Keep unsafe reference helpers internal (`0191f20`) |
|
|
| #8 | Initialize the window uniform from the surface (`6e271e8`) |
|
|
| #9 | Preserve primitive-count recursion (`b90c855`) |
|
|
| #10 | Text layout and rendering on Parley (`0f6a28b`) |
|
|
|
|
URLs are `https://git.arirex.me/iris/iris/pulls/{number}`.
|
|
|
|
## Choosing the next slice
|
|
|
|
```sh
|
|
cd /home/bob/repos/iris && git fetch upstream
|
|
git diff --stat upstream/main..archive/full-extraction
|
|
```
|
|
|
|
The archive is a reference, not a patch to apply. Recreate a change on top of
|
|
canonical `main`, leave app-specific behaviour out, and verify it independently.
|
|
Pick disjoint path sets when two PRs are open, and branch each from the latest
|
|
`upstream/main` rather than stacking.
|
|
|
|
Still in the target and not yet claimed:
|
|
|
|
- Widget draw size and measurement cleanup (source commit `6671194`).
|
|
- Retained span, scrolling and layout placement.
|
|
- Retained paints, selection, overlays and shared UI runtime state.
|
|
- Generic desktop/Android framework hosts and reusable example/APK tooling.
|
|
- Application-owned fonts and application-named font families.
|
|
- Shared resource-handle bookkeeping and replaceable glyph-atlas buckets.
|
|
- Positioned text overflow and cluster-safe ellipsis.
|
|
- **The headless rig** — `scripts/run-headless.sh`, `headless.conf` and
|
|
`rig-input` live in ai-app's iris submodule and not in canonical Iris.
|
|
Everything below depends on running them from there; extracting them is a
|
|
slice of its own.
|
|
|
|
## Verifying a framework slice
|
|
|
|
```sh
|
|
cd <iris-worktree>
|
|
cargo fmt --all --check
|
|
cargo clippy --all-targets -- -D warnings
|
|
cargo test
|
|
```
|
|
|
|
`--workspace` when the slice crosses workspace crates. A rendering claim needs
|
|
a real run, which on this machine means the headless rig in ai-app's submodule:
|
|
|
|
```sh
|
|
cd /home/bob/repos/ai-app-2/iris
|
|
./scripts/run-headless.sh tabs --dir /home/bob/repos/iris-prNN \
|
|
--shot /tmp/out.png --seconds 3
|
|
./scripts/run-headless.sh tabs --dir ... --replay /tmp/taps.touch --shot ...
|
|
```
|
|
|
|
A `.touch` file is `<ms> down|move|up <x> <y>` in the output's own pixels; the
|
|
script replays it through a virtual pointer. The `tabs` example's five tabs sit
|
|
at x = 192, 576, 960, 1344 and 1728 on a 1920x1200 output. Read the
|
|
`this-machine-graphics` skill before trusting any of it — the Vulkan device
|
|
here comes and goes, and everything silently falls back to software when it
|
|
does.
|
|
|
|
## Cautions
|
|
|
|
- Read `/home/bob/repos/ai-app-2/AGENTS.md` and the machine-wide rules first.
|
|
- Keep Iris generic: session drivers, transcripts, setup and server concepts,
|
|
app icons and product fonts stay in ai-app. Android and desktop code is Iris
|
|
work only when it is a generic host or platform integration.
|
|
- Preserve the dirty-worktree rule. All worktrees were clean at handoff;
|
|
anything found later may be the owner's or another agent's.
|
|
- Do not delete the archived snapshot or the fork `main` ai-app pins.
|
|
- A complete target branch is not permission to recreate the giant PR.
|
|
- Another agent was freeing disk on this VM and removed `target/` from the
|
|
`iris-pr*` worktrees once. Sources and git state were untouched. Tell peers
|
|
before changing shared machine tooling, and expect a cold rebuild sometimes.
|