Rewrite the extraction handoff as current state
Incremental edits had spliced the opening section into two half-sentences and left it saying main was at the commit before last. It is now written as where things are: two open PRs, the harness as the next slice, the renderer's invariants rather than the story of how they arrived, and the three render checks described rather than pointed at a script in /tmp. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c2b1c07895
commit
d0606f46ec
1 file changed
+190
-199
+190
-199
@@ -3,106 +3,70 @@
|
||||
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
|
||||
## Where things stand
|
||||
|
||||
**#11 is merged** (`b234497` on canonical `main`, 2026-09-13). Open now are
|
||||
#12 (pointer routing, never reviewed) and #13 (wgpu 30). Check for a review
|
||||
on either before starting anything new:
|
||||
Canonical `main` is **`00d2230`** (#13, wgpu 30). Eleven slices are in; two
|
||||
pull requests are open and both are waiting on the owner, not on me:
|
||||
|
||||
- **#12** `split/12-pointer-routing`, worktree `/home/bob/repos/iris-pr12`,
|
||||
head `71ba372`. A widget takes only the input it answers to, and only where
|
||||
the cursor is. Self-reviewed under the process below, which found two
|
||||
defects: consumption decided once a frame rather than per input kind, and a
|
||||
press firing on a widget the cursor had just left. Six tests across layers;
|
||||
three of them fail on `main`.
|
||||
- **#14** `split/14-setsize`, worktree `/home/bob/repos/iris-pr14`, head
|
||||
`f312db6`. The `Sized` widget becomes `SetSize`, so the prelude stops
|
||||
shadowing the marker trait and `?Sized` resolves again in any crate that
|
||||
imports it. `tests/prelude_bounds.rs` fails to compile if that comes back.
|
||||
|
||||
Check for a review before starting anything, and read the newest
|
||||
`submitted_at` rather than the first result:
|
||||
|
||||
```sh
|
||||
TOKEN=$(cat ~/.config/gitea/token)
|
||||
N=12
|
||||
curl -s -H "Authorization: token $TOKEN" \
|
||||
https://git.arirex.me/api/v1/repos/iris/iris/pulls/13/reviews
|
||||
``` Check for one before doing anything
|
||||
else:
|
||||
|
||||
```sh
|
||||
TOKEN=$(cat ~/.config/gitea/token)
|
||||
https://git.arirex.me/api/v1/repos/iris/iris/pulls/$N/reviews
|
||||
curl -s -H "Authorization: token $TOKEN" \
|
||||
https://git.arirex.me/api/v1/repos/iris/iris/pulls/11/reviews
|
||||
https://git.arirex.me/api/v1/repos/iris/iris/pulls/$N/reviews/<id>/comments
|
||||
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
|
||||
https://git.arirex.me/api/v1/repos/iris/iris/issues/$N/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.
|
||||
My replies are ordinary issue comments on the same PR and say what each change
|
||||
was for. `/home/bob/repos/ai-app-2` is on `rustify`, worktree clean.
|
||||
|
||||
## How the work is sequenced
|
||||
|
||||
**Most fundamental first**, from the owner on 2026-09-13: *"please do more
|
||||
fundamental changes first, such as library updates and core framework changes,
|
||||
so that code only has to be written once"*, and *"should probably start adding
|
||||
tests early on rather than later, so you don't have to make separate test
|
||||
scripts and stuff. This might involve making the harness eventually, depends
|
||||
on what needs tested."*
|
||||
|
||||
So slices are ordered by how much depends on them, not by what is nearest
|
||||
ready, and a slice arrives with tests rather than with a script in `/tmp`.
|
||||
|
||||
**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).
|
||||
the fourth round of #11 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.
|
||||
|
||||
## Stop point
|
||||
**Nothing is submitted without a separate review pass** — the installed
|
||||
`pre-submit-review` skill: build clean, review the code, review the comments on
|
||||
their own 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. It has earned its place repeatedly: four defects
|
||||
on #11 that format, clippy, tests and five headless renders had all passed, and
|
||||
on #12 a regression introduced by the review's own first draft. `audit.sh` in
|
||||
the skill directory prints every comment line a branch adds against a base ref;
|
||||
the owner's standing complaint is verbose agent comments, and the default
|
||||
verdict is delete. **Machine-specific notes do not belong in the repository** —
|
||||
they live in `~/.claude/MACHINE.md` or a `this-machine-*` skill.
|
||||
|
||||
- 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`.
|
||||
- Canonical `main` is `00d2230` (#13, wgpu 30). `/home/bob/repos/iris-pr13`
|
||||
is a merged branch now; do not build new work on it.
|
||||
- **#14** `split/14-setsize`, worktree `/home/bob/repos/iris-pr14`, head
|
||||
`f312db6`, one commit on `00d2230`. The `Sized` widget becomes `SetSize`,
|
||||
which stops the prelude shadowing the marker trait. Not reviewed yet.
|
||||
- **#12** `split/12-pointer-routing`, worktree `/home/bob/repos/iris-pr12`,
|
||||
head `71ba372`, current `main` merged in. A widget takes only the input it
|
||||
answers to, and only where the cursor is. Self-reviewed under the new
|
||||
process, which found two defects: consumption decided once a frame rather
|
||||
than per kind, and a press firing on a widget the cursor had just left.
|
||||
Six tests across layers; three fail on `main`. Waiting on the owner.
|
||||
- `/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. Nothing is seeded,
|
||||
so an id depends on what a ui drew first and a ui pays only for what it uses.
|
||||
- **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**: the window and the masks.
|
||||
A mask texture would go here too.
|
||||
- **Each primitive records its own draws.** `Primitive::render` makes a
|
||||
`PrimitiveRender` that states the layout its shader reads, uploads what it
|
||||
owns, and records its draws: `GlyphRender` owns the atlas and binds it once
|
||||
per list, `ImageRender` owns the images and binds one per instance, the
|
||||
default owns nothing. The renderer knows nothing about textures.
|
||||
**Measured**, because dispatch per list was the objection: 6 instructions
|
||||
per list, 0.1% of a frame at 256 and at 1024 layers, against the ~5,400
|
||||
wgpu spends recording one. `tests/draw_cost.rs` is that measurement.
|
||||
- **`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 only what every primitive uses -- window, masks, vertex shader,
|
||||
`masked()` -- and its header is where binding numbers are written down; what
|
||||
a shader samples is declared by that shader.
|
||||
- **A texture handle is drawn like anything else.** `Painter::primitive` takes
|
||||
`impl PrimitiveLike`: a primitive, or something that yields one and does what
|
||||
else drawing it needs -- a `&TextureHandle` retains its share on the way
|
||||
through. The blanket impl and the one for `&TextureHandle` do not collide,
|
||||
because `Primitive` is ours and no crate can add the overlapping impl.
|
||||
- **Order within a layer means nothing**, and the widgets do not rely on it:
|
||||
`Stack` gives each child its own layer and `TextEdit` draws its view in a
|
||||
child layer above the selection rectangles. Verified with a ui that
|
||||
registers glyph before rect.
|
||||
|
||||
## Standing instructions from the owner
|
||||
Other 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
|
||||
@@ -111,28 +75,94 @@ shape:
|
||||
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.
|
||||
- **Never rewrite a pushed branch.** Follow review with additive commits, and
|
||||
merge `upstream/main` in rather than rebasing when a branch falls behind.
|
||||
- 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
|
||||
## The next slice
|
||||
|
||||
`~/.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.
|
||||
**The headless rig and the test harness.** `scripts/run-headless.sh`,
|
||||
`headless.conf`, `rig-input` and `iris::harness` live in ai-app's iris
|
||||
submodule and not in canonical Iris. Until they are extracted, Iris can only
|
||||
be tested by what runs without a window, and every rendering claim is verified
|
||||
by hand from another checkout. Extracting them is what lets later slices
|
||||
arrive with tests instead of screenshots. Nothing else is claimed.
|
||||
|
||||
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.
|
||||
Still in the target, roughly in dependency order:
|
||||
|
||||
`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.
|
||||
- **The input restructure** — `src/default/sense.rs` becomes `src/rsc/sense.rs`
|
||||
(308 lines to 2313), plus `core/src/event/controller.rs`, `desktop/input.rs`,
|
||||
`android/input.rs` and `sense_tests.rs`: pointer capture, drag slop and axis,
|
||||
platform cancellation, mask-aware hit testing, event timestamps. It replaces
|
||||
the file #12 fixes, and **the archived copy carries the same per-frame
|
||||
consumption defect #12 removes** — extracting it as-is brings the bug back,
|
||||
so `tests/pointer_routing.rs` is the acceptance criterion for that slice.
|
||||
- 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.
|
||||
|
||||
Dependencies are current apart from `winit`, which stays on 0.30.12 until
|
||||
0.31 leaves prerelease. `parley` 0.11.1 and `image` 0.25.10 are latest.
|
||||
|
||||
```sh
|
||||
cd /home/bob/repos/iris && git fetch upstream
|
||||
git diff --stat upstream/main..origin/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 — unless the slice fixes
|
||||
code another open branch replaces, in which case say so and stack deliberately.
|
||||
|
||||
## How the renderer works now
|
||||
|
||||
Current invariants, not history. Worth reading before touching `core/render`.
|
||||
|
||||
- **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. Nothing is
|
||||
seeded, so an id depends on what a ui drew first and a ui pays only for the
|
||||
pipelines it uses.
|
||||
- **Each primitive records its own draws.** `Primitive::render` makes a
|
||||
`PrimitiveRender` that states the layout its shader reads, uploads whatever
|
||||
it owns, and records its draws. `GlyphRender` owns the atlas and binds it
|
||||
once per list; `ImageRender` owns the images and binds one per instance; the
|
||||
default owns nothing and draws every instance in one call. The renderer sets
|
||||
the pipeline, the shared group, the list's data and its vertex buffer, and
|
||||
knows nothing else. Dispatch per list was measured at 6 instructions, 0.1% of
|
||||
a frame at 256 and at 1024 layers, against the ~5,400 wgpu spends recording
|
||||
one list; `tests/draw_cost.rs` is that measurement.
|
||||
- **The shared bind group is the window and the masks**, given to every draw.
|
||||
A mask texture would go here too. What a primitive samples is its own group,
|
||||
and a primitive that samples nothing has no such group in its pipeline.
|
||||
- **Every binding size is stated.** A `None` minimum puts the binding on
|
||||
wgpu-core's late-sized list, which `is_ready` scans on every draw.
|
||||
- **`shader/prelude.wgsl` plus one file per primitive**, because one module
|
||||
cannot declare two types at the same binding. The prelude carries only what
|
||||
every primitive uses — window, masks, vertex shader, `masked()` — and its
|
||||
header is where binding numbers are written down; what a shader samples is
|
||||
declared by that shader.
|
||||
- **A texture handle is drawn like anything else.** `Painter::primitive` takes
|
||||
`impl PrimitiveLike`: a primitive, or something that yields one and does
|
||||
whatever else drawing it needs — a `&TextureHandle` retains its share on the
|
||||
way through, which a `Pod` primitive cannot.
|
||||
- **Order within a layer means nothing**, and the widgets do not rely on it:
|
||||
`Stack` gives each child its own layer and `TextEdit` draws its view in a
|
||||
child layer above the selection rectangles.
|
||||
- **Images are one texture and one bind group each**, so each drawn image is a
|
||||
draw call. The owner chose that on 2026-09-13 over packing images into
|
||||
arrays like atlas pages; a bindless `binding_array` was ruled out by Android
|
||||
support. Revisit only with her.
|
||||
- **Layers are never freed** (`TODO` in `primitive/layer.rs`), so every layer a
|
||||
session creates is walked every frame thereafter. Measured at ~2ns per empty
|
||||
layer per frame, which is why it is the TODO's problem and not a bug of its
|
||||
own.
|
||||
|
||||
## Repository topology
|
||||
|
||||
@@ -157,11 +187,65 @@ complaint is verbose agent comments; the default verdict is delete.
|
||||
|
||||
```sh
|
||||
cd /home/bob/repos/iris && git fetch upstream
|
||||
git worktree add -b split/13-name /home/bob/repos/iris-pr13 upstream/main
|
||||
git worktree add -b split/15-name /home/bob/repos/iris-pr15 upstream/main
|
||||
```
|
||||
|
||||
The other `/home/bob/repos/iris-pr*` worktrees hold merged branches. They are
|
||||
readable references; do not build new work on them.
|
||||
Every other `/home/bob/repos/iris-pr*` worktree holds a merged branch. They
|
||||
are readable references; do not build new work on them.
|
||||
|
||||
## Verifying a 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 until the rig is extracted means driving it from 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
|
||||
`tabs` example's five tabs sit at x = 192, 576, 960, 1344 and 1728 on a
|
||||
1920x1200 output; tapping the third and then the bottom-right button twice
|
||||
adds two images.
|
||||
|
||||
Three renders cover the drawing paths, and each needs a different ui, so two
|
||||
of them are throwaway examples written into the worktree and deleted after:
|
||||
|
||||
1. `tabs` with that replay — rects, glyphs and images together.
|
||||
2. An image alone in a layer, which is the case that failed GPU validation
|
||||
when every other test happened to have a rectangle in the same layer.
|
||||
3. Six lines of 400px text, which forces the atlas to four pages and proves
|
||||
the array grew and its group was rebuilt.
|
||||
|
||||
Those three become ordinary tests with the harness slice, which is the
|
||||
argument for doing it next.
|
||||
|
||||
## Cautions
|
||||
|
||||
- Read `/home/bob/repos/ai-app-2/AGENTS.md` and the machine-wide rules first.
|
||||
Anything about this machine — the GPU that comes and goes, measuring a small
|
||||
performance difference, the emulator — is in `~/.claude/MACHINE.md` and the
|
||||
`this-machine-*` skills, and belongs there rather than here.
|
||||
- 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.
|
||||
|
||||
## Merged so far
|
||||
|
||||
@@ -180,96 +264,3 @@ readable references; do not build new work on them.
|
||||
| #13 | Build on wgpu 30 (`00d2230`) |
|
||||
|
||||
URLs are `https://git.arirex.me/iris/iris/pulls/{number}`.
|
||||
|
||||
## Choosing the next slice
|
||||
|
||||
**Most fundamental first**, from the owner on 2026-09-13: *"please do more
|
||||
fundamental changes first, such as library updates and core framework changes,
|
||||
so that code only has to be written once"*, and *"should probably start adding
|
||||
tests early on rather than later, so you don't have to make separate test
|
||||
scripts and stuff. This might involve making the harness eventually, depends
|
||||
on what needs tested."*
|
||||
|
||||
So the order is by how much else depends on a thing, not by what is nearest
|
||||
ready, and a slice lands with tests rather than with a script in `/tmp`.
|
||||
|
||||
1. **wgpu 28.0.0 -> 30.0.1.** Done, open as #13.
|
||||
`winit` stays on 0.30.12 until 0.31 is out of prerelease; `parley` 0.11.1
|
||||
is current. The API changes were: the instance takes the display handle it
|
||||
presents on (GLES on Wayland needs it), `get_current_texture` returns a
|
||||
status enum rather than a `Result`, presenting moved to the queue, and
|
||||
bind group and vertex buffer layouts became sparse.
|
||||
2. **Next: the headless rig and the test harness** -- `scripts/run-headless.sh`,
|
||||
`headless.conf`, `rig-input` and `iris::harness` live in ai-app's iris
|
||||
submodule, not in canonical Iris. Until they are extracted, canonical Iris
|
||||
can only be tested by the four `tests/text_edit.rs` tests, and anything
|
||||
about rendering is verified by hand from another checkout. Extracting them
|
||||
is what lets every later slice arrive with tests.
|
||||
3. Everything below, once those two are in.
|
||||
|
||||
Still in the target and not yet claimed:
|
||||
|
||||
- **The input restructure** -- `src/default/sense.rs` becomes `src/rsc/sense.rs`
|
||||
(308 lines to 2313), plus `core/src/event/controller.rs`, `desktop/input.rs`,
|
||||
`android/input.rs` and `sense_tests.rs`: pointer capture, drag slop and axis,
|
||||
platform cancellation, mask-aware hit testing, event timestamps. It replaces
|
||||
the file #12 fixes, and **the archived copy carries the same per-frame
|
||||
consumption defect #12 removes** -- extracting it as-is brings the bug back,
|
||||
so `tests/pointer_routing.rs` is the acceptance criterion for that slice.
|
||||
- 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.
|
||||
|
||||
```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.
|
||||
|
||||
## 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.
|
||||
Reference in new issue
Block a user