RUST.md, IRIS.md, IRIS_TODO.md, DECISIONS.md: record I5's frame report and holddrag results

FrameReport gave a real, measured on-device number (frames=34,
janky%=61.76, p50=26.5ms p90=48.0ms p99=98.1ms worst=98.1ms) and
long-press-then-drag-to-select is now confirmed on-device (logcat plus a
screenshot of the highlighted selection). Neither closes I5's box to [x]
yet: the frame number is real but not the clean single 24-swipe loop
comparable to Compose's, because gestures against this checkout's
EMU_GPU=software emulator intermittently delivered zero touch input this
session -- a new, separately named finding (candidate cause: the
emulator's own software rasterisation measured at ~78% of a CPU core
continuously), not yet root-caused. DECISIONS.md's DEFERRED item is
updated with these numbers rather than a decision made here.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
irisandClaude Fable 5.1 committed 2026-09-05 15:00:29 -04:00
1 parent 470f8e5019
commit 1e7b1cddb7
4 files changed
+292 -89

No files matched your search

+23 -15
View File
@@ -66,18 +66,26 @@ marked **DEFERRED** are ones the agent chose not to decide alone.
pieces and I5's Android integration are all done; next is giving iris pieces and I5's Android integration are all done; next is giving iris
its own frame-timing report so item 3 below can be decided by a number. its own frame-timing report so item 3 below can be decided by a number.
- **DEFERRED — whether to commit to iris over Masonry for `ai-app`.** - **DEFERRED — whether to commit to iris over Masonry for `ai-app`.**
Updated 2026-09-05 with what's now known: iris's Android integration is Updated 2026-09-05 (later the same day) with what's now known: iris has
built and confirmed working on a real device (real server, real its own frame-timing report now (`FrameReport`) and a real number from
scrolling, real touch-drag pan, tap-by-name accessibility — RUST.md's I5 it, captured from a genuine on-device touch-drag —
box), while Masonry's own touch-scroll on Android was already found `frames=34 janky%=61.76 p50=26.5ms p90=48.0ms p99=98.1ms worst=98.1ms`
entirely absent (E2). What's still missing on **both** sides is a — plus a confirmed on-device long-press-then-drag-to-select (logcat and
render-time number — not because iris doesn't work, but because a screenshot of the highlighted selection). It is **not yet the clean,
`dumpsys gfxinfo` cannot see a `SurfaceView`'s GPU-drawn frames at all, comparable number** the recommendation wants: gestures against this
so the `transcript-bench.sh`-style comparison this recommendation wanted checkout's `EMU_GPU=software` emulator intermittently delivered zero
produced a real number for Compose (8.96% janky, 99th percentile 150ms, touch input during this session, reproducibly, for a reason named but
same emulator/session) and none at all for iris. The choice in front of not yet confirmed (the emulator's own software rasterisation measured
Iris: decide now on the structural-plus-functional case already made at ~78% of a CPU core continuously — a plausible source of input
(iris works end-to-end where Masonry's scroll gesture doesn't exist at backlog, not yet isolated with a sampler running during a failing
all on Android), or wait for iris to grow its own frame-timing gesture). The Compose figure quoted for comparison (8.96% janky, 99th
instrumentation first so the comparison can be a number rather than a percentile 150ms) is the same one already recorded earlier 2026-09-05,
qualitative one. RUST.md's "Recommendation" item 3 has the full account. not re-taken this pass, and against a different sandbox session's
content — so the two numbers share configuration, not identical data.
The choice in front of Iris, updated: decide now on the
structural-plus-functional case already made (iris works end-to-end
where Masonry's scroll gesture doesn't exist at all on Android, plus a
real if narrowly-scoped frame-timing number), or wait for the
touch-delivery investigation above so the comparison can be the single
clean 24-swipe loop rather than a number gathered around an unresolved
rig flakiness. RUST.md's "Recommendation" item 3 has the full account.
+43
View File
@@ -8,6 +8,49 @@ capability that moved. Small and trivial changes do not go here.
An entry gives the date, what changed, why, and a short before/after where An entry gives the date, what changed, why, and a short before/after where
it helps judge the change without the session that made it. Newest first. it helps judge the change without the session that made it. Newest first.
## 2026-09-05 (later the same day): `iris_core::FrameReport` (RUST.md's I5 box)
New public type, `iris_core::FrameReport` (re-exported from `iris_core`'s
`render` module alongside `FrameStats` and `JANK_THRESHOLD`). Why: `dumpsys
gfxinfo` cannot see a `SurfaceView`'s own GPU-drawn frames at all, so a
`wgpu`-rendered iris screen had no way to ask "was this smooth" the way
Compose's own in-app render report already can -- item 3 of RUST.md's
recommendation was stuck on a one-sided number for exactly this reason.
`FrameReport::record(elapsed: Duration)` is called once per frame (wired
into `android/view.rs`'s `render()`, wrapping the same span from redraw
start to after `queue.submit`+`present()` that Compose's report and
`gfxinfo` both count) and writes into a fixed 4096-entry ring -- no
allocation on the hot path. `FrameReport::report() -> Option<FrameStats>`
gives total frames, janky % (over `JANK_THRESHOLD`, the same 16.7ms 60Hz
budget `gfxinfo` uses), P50/P90/P99 and the worst; `None` if nothing has
been recorded since the last `reset()`, not a zeroed report that would
read as a real measurement. `FrameStats`'s `Display` line says plainly
that it measures up to `present()` being called, not GPU/compositor
completion, since wgpu's `present()` isn't fenced against either.
`AndroidUiState` gained a `pub frame_report: FrameReport` field --
anything with `HasAndroidUiState` can now read or reset it. Before this,
there was no way to ask iris's own render path how long a frame took at
all, on any backend.
Before/after, for a caller that already has `ui_state: &AndroidUiState`:
```rust
// before: no such question could be asked
// after:
match ui_state.frame_report.report() {
Some(stats) => log::info!("iris frame report: {stats}"),
None => log::info!("iris frame report: no frames recorded yet"),
}
ui_state.frame_report.reset(); // via android_state_mut()
```
`iris-android-app`'s transcript screen exposes this as two named,
tappable controls ("Frame report", "Reset frame report") rather than
requiring a caller to wire its own UI -- see `transcript_client.rs`'s
`frame_report_controls`.
## 2026-09-05: `Tasks::redraw_handle` (RUST.md's I5 Android integration) ## 2026-09-05: `Tasks::redraw_handle` (RUST.md's I5 Android integration)
New public method on `iris::task::Tasks`, `redraw_handle(&self) -> New public method on `iris::task::Tasks`, `redraw_handle(&self) ->
+46 -19
View File
@@ -186,25 +186,52 @@ order and what "done" looks like. Tick and date them in place.
requirement, fixed by routing through `View::post_delayed` — see requirement, fixed by routing through `View::post_delayed` — see
`IRIS.md`'s `Tasks::redraw_handle` entry). See RUST.md's I5 box, `IRIS.md`'s `Tasks::redraw_handle` entry). See RUST.md's I5 box,
"The Android integration, done 2026-09-05" for the full account. "The Android integration, done 2026-09-05" for the full account.
- [ ] **A render-time number for iris, comparable to Compose's - [x] **A render-time number for iris, comparable to Compose's
`transcript-bench.sh` report.** `dumpsys gfxinfo` cannot see a `transcript-bench.sh` report — instrumentation done and a real number
`SurfaceView`'s own GPU-drawn frames at all (confirmed: 0 frames obtained, 2026-09-05 (later the same day); the clean comparable loop
reported across a gesture loop that visibly scrolled), and a is not.** `iris_core::FrameReport` (`iris/core/src/render/
`dumpsys SurfaceFlinger --latency` fallback returned no per-frame frame_report.rs`, `IRIS.md`'s new entry) times every frame from
history either on this Android version's BLAST compositor. What's `render()`'s redraw start to after `queue.submit`+`present()`, exposed
needed is frame-timing instrumentation inside iris itself — a report as two named on-screen controls ("Frame report", "Reset frame
the way `UiRenderState::take_counters`/`AccessTree::take_rebuilds` report"). Driven against a real on-device touch-drag it read
already expose counters, extended to timing. This is the one number `frames=34 janky%=61.76 p50=26.5ms p90=48.0ms p99=98.1ms
RUST.md's recommendation (item 3) is still waiting on. worst=98.1ms` — real, not inferred, but accumulated across several
- [ ] **Long-press-then-drag-to-select was not independently driven gestures rather than one clean 24-swipe loop, because of the new
on-device.** `ui-trace`'s two gesture primitives (`tap`, `swipe X1 Y1 finding below. See RUST.md's I5 box, "Update, 2026-09-05, later the
X2 Y2 MS`) cannot produce "hold stationary for `LONG_PRESS`, then drag same day" for the full account.
without lifting" — `swipe` interpolates motion across its whole - [ ] **New, 2026-09-05: intermittent touch delivery to iris's
duration from the start. Needs either a new `ui-trace` action (a `SurfaceView` under this checkout's `EMU_GPU=software` emulator.**
genuine hold-then-drag primitive) or raw multi-step `MotionEvent` The same swipe coordinates, confirmed (by scanning a screenshot
injection. `DragArbiter`'s own unit tests already cover this exact column for the first non-black pixel) to sit over real row text,
sequence against a synthetic clock (`iris/src/sense.rs`), which is why sometimes produced 30+ real frames and a screenshot diff and
this is "not independently driven on-device" rather than "unverified." sometimes produced zero of either, across otherwise-identical
`ui-trace` invocations. Not the already-understood "already at that
scroll edge" case (reproduced with content confirmed taller than the
viewport, in both directions). Leading candidate, not yet confirmed:
this checkout's emulator was independently observed at ~78% of one
CPU core, continuously, while idle on-screen — SwiftShader's software
rasterisation is CPU-bound by design, and a synthetic touch competing
with that load for delivery is plausible but unmeasured *during* a
failing gesture (the standing rule against diagnosing from
after-the-fact measurements applies here). Needs a sampler (load,
`dumpsys input`, a `-i 0` `ui-trace` capture) running while a failing
gesture is driven, and ideally a comparison under `-gpu host` (real
Vulkan) to see whether it is specific to software rendering. This is
what blocks the clean, comparable 24-swipe loop above.
- [x] **Long-press-then-drag-to-select — confirmed on-device, 2026-09-05
(later the same day).** `ui-trace` gained a `holddrag X1 Y1 X2 Y2
HOLD_MS MOVE_MS` action (`emulator-tools`, additive, extends the same
`MotionEvent`/`injectInputEvent` mechanism `swipe` already used):
press, hold past `LONG_PRESS`, move, release, as one continuous touch.
Driven against a real row (`holddrag 300 1850 300 2050 600 300`) it
produced `iris selection: begin at row ...` then a sequence of
`iris selection: extend to row ...` log lines
(`transcript-ui/src/selection.rs`, a new small `log` dependency since
selection has no accessibility label of its own yet — see the next
item), and a screenshot taken right after shows the expected
highlighted selection spanning multiple rows. `DragArbiter`'s own
unit tests already covered this sequence against a synthetic clock;
this is the first time it has been driven by a real device touch.
- [x] **Touch-drag panning over a row's own rendered text — done, - [x] **Touch-drag panning over a row's own rendered text — done,
2026-09-05.** `row.rs` used to register `CursorSense::click_or_drag()` 2026-09-05.** `row.rs` used to register `CursorSense::click_or_drag()`
on each row's `TextEdit` for cross-row selection; `TextEdit::draw`'s on each row's `TextEdit` for cross-row selection; `TextEdit::draw`'s
+180 -55
View File
@@ -36,23 +36,35 @@ session spending an afternoon on them again.
## Where things stand (2026-09-05) ## Where things stand (2026-09-05)
- **I5's Android integration is done and measured, 2026-09-05 (still ticked - **iris now has its own frame-timing report and a confirmed on-device
`[~]`, not `[x]` -- see I5's own box for exactly why).** The transcript long-press-drag, 2026-09-05, later the same day (I5's box still `[~]`,
screen runs on-device against a real `ai-server`, with real scrolling, not `[x]` -- see I5's own box for exactly why).** `iris_core::FrameReport`
real touch-drag panning and tap-by-name accessibility all confirmed by (new) times every frame from `render()`'s redraw start to after
screenshot/log evidence on this checkout's emulator. What the `queue.submit`+`present()`, exposed as two named on-screen controls, and
recommendation still lacks is a render-time number for iris comparable a new `ui-trace holddrag` action (in `emulator-tools`) can finally
to Compose's `transcript-bench.sh` report -- not because the screen produce a real hold-then-drag touch sequence. Both were driven for
doesn't work, but because `dumpsys gfxinfo` cannot see a `SurfaceView`'s real: long-press-then-drag-to-select is confirmed on-device (logcat plus
own GPU-drawn frames at all, and iris has no frame-timing a screenshot of the highlighted selection), and `FrameReport` captured a
instrumentation of its own to ask instead. Two real, previously-unknown real number from a real touch-drag (`frames=34 janky%=61.76 p50=26.5ms
bugs were found and fixed getting here (a missing `INTERNET` permission, p90=48.0ms p99=98.1ms worst=98.1ms`). **What's still missing**: a clean,
and a background-thread redraw request that crashed the process via a single 24-swipe loop comparable to Compose's own number -- gestures
`Looper` requirement neither this box nor `Tasks::redraw_handle`'s against this checkout's `EMU_GPU=software` emulator intermittently
design had anticipated) -- both in I5's own box, both in `IRIS.md`. delivered zero touch input during this pass, for a reason named but not
Next: give iris a render-time report of its own, the one piece left yet confirmed (candidate: the emulator's own software rasterisation,
before the iris-vs-Masonry recommendation can be decided by a number measured at ~78% of a CPU core continuously, starving synthetic touch
rather than by structure alone. delivery under load). Next: a sampler running *during* a failing gesture
to confirm or rule out that candidate, then the clean comparable loop.
I5's own box, "Update, 2026-09-05, later the same day" has the full
account.
- **I5's Android integration is done and measured, 2026-09-05.** The
transcript screen runs on-device against a real `ai-server`, with real
scrolling, real touch-drag panning and tap-by-name accessibility all
confirmed by screenshot/log evidence on this checkout's emulator. Two
real, previously-unknown bugs were found and fixed getting here (a
missing `INTERNET` permission, and a background-thread redraw request
that crashed the process via a `Looper` requirement neither this box nor
`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 - **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`** at the repo root, which is the file Iris reads for
choices made without her. choices made without her.
@@ -699,12 +711,35 @@ light" has a knob inside the same stack.
programmatically (I3's benchmark plus I5's on-device screenshot programmatically (I3's benchmark plus I5's on-device screenshot
evidence) — three structural points and one functional one in iris's evidence) — three structural points and one functional one in iris's
favour, still with no opposing *or* supporting render-time measurement favour, still with no opposing *or* supporting render-time measurement
on either side. **What Iris needs to weigh this**: whether "iris works on either side.
and Masonry's Android scroll path is absent entirely" is enough to
decide without a number, or whether the frame-timing work above is **Update, 2026-09-05, later the same day: iris now has a render-time
worth doing first — a product/tradeoff call, not a technical one, so it report of its own, and a real number from it, but not yet the clean
is left to her rather than decided here (DECISIONS.md's DEFERRED comparison item 3 needs.** `iris_core::FrameReport` (new,
item). `iris/core/src/render/frame_report.rs`) is exactly the follow-on work
named above — a per-frame wall-time ring exposed as two named on-screen
controls, unit tested (6 tests over the ring/percentile math). Driven
for real against a real touch-drag on this checkout's emulator, it
read `frames=34 janky%=61.76 p50=26.5ms p90=48.0ms p99=98.1ms
worst=98.1ms` — a genuine measurement through iris's own render path,
not inferred. **It is not yet the comparable number**, for a newly
found and separately named reason (I5's own box, "Update, 2026-09-05,
later the same day"): gestures against this checkout's
`EMU_GPU=software` emulator intermittently delivered zero touch input
during this pass — reproducible, but not yet root-caused past one
candidate (the emulator's own software rasterisation measured at ~78%
of a CPU core continuously, a plausible source of input backlog, not
yet confirmed with a sampler running during a failing gesture). So
item 3 still cannot be closed by a clean number, now for a narrower and
more tractable reason than before: the instrumentation exists and
works, and what remains is making the emulator rig deliver touch input
reliably enough to run the comparable loop. **What Iris needs to
weigh, updated**: whether "iris works, Masonry's Android scroll path is
absent entirely, and iris's own frame-timing report is real and
working" is enough to decide without the final clean number, or
whether to wait for the touch-delivery investigation above — still a
product/tradeoff call, left to her (`DECISIONS.md`'s DEFERRED item,
updated with this session's numbers).
4. Then the shell (E3), the desktop window (E4) and the packaging (E5), 4. Then the shell (E3), the desktop window (E4) and the packaging (E5),
which do not depend on the choice. which do not depend on the choice.
@@ -2309,17 +2344,23 @@ silently on real hardware.
time it was hit (mid-session, after adding an unrelated temporary time it was hit (mid-session, after adding an unrelated temporary
log line forced a dev rebuild) and cost real time to separate from log line forced a dev rebuild) and cost real time to separate from
the actual touch-dispatch question being chased at the time. the actual touch-dispatch question being chased at the time.
- [~] **I5 — the transcript screen in iris (2026-09-05). The widget-tree - [~] **I5 — the transcript screen in iris (2026-09-05, updated later the
half and the Android integration are both built and confirmed same day). The widget-tree half and the Android integration are
working on-device (real server, real scrolling, real touch-drag both built and confirmed working on-device (real server, real
pan, tap-by-name); still `[~]` rather than `[x]` because the one scrolling, real touch-drag pan, tap-by-name), iris now has its own
thing the recommendation actually wants -- a render-time number for frame-timing instrumentation (`FrameReport`) and produced a real,
iris comparable to Compose's -- could not be produced on this pass, measured number from a real on-device touch-drag, and long-press-
for a reason named precisely rather than left vague: `dumpsys then-drag-to-select is now confirmed on-device too (both by logcat
gfxinfo` cannot see a `SurfaceView`'s own GPU-drawn frames at all, and by a screenshot showing the highlighted selection); still `[~]`
and iris has no frame-timing instrumentation of its own yet to ask rather than `[x]` because the frame-time number obtained is not the
instead. See "Measurements taken" and "What remains" near the end of clean, single 24-swipe loop comparable to Compose's -- gestures
this box.** against this checkout's `EMU_GPU=software` emulator intermittently
produced zero frames for reasons not yet isolated (candidate: the
emulator's own software rasterisation measured at ~78% of a CPU
core, continuously, which may be starving synthetic touch delivery
under load -- not yet confirmed with a sampler running during the
failing gesture). See "Update, 2026-09-05, later the same day" and
"What remains" near the end of this box.**
**Where it lives.** `iris/transcript-ui/` (new workspace member, **Where it lives.** `iris/transcript-ui/` (new workspace member,
`[lib]`), the same shape as `iris/tabs-ui`: generic over `Rsc: `[lib]`), the same shape as `iris/tabs-ui`: generic over `Rsc:
@@ -2699,15 +2740,99 @@ silently on real hardware.
a synthetic clock, which is why the mechanism is trusted enough to a synthetic clock, which is why the mechanism is trusted enough to
call "not independently driven on-device" rather than "unverified." call "not independently driven on-device" rather than "unverified."
**Update, 2026-09-05, later the same day: (b) has a real iris number
now, and (c) is confirmed on-device.** Both needed new tooling built
this pass, recorded in `DECISIONS.md`: `iris_core::FrameReport`
(`iris/core/src/render/frame_report.rs`) times each frame from
`render()`'s redraw start to after `queue.submit`+`present()` into a
fixed 4096-entry ring, exposed as two named controls on the
transcript screen ("Frame report", "Reset frame report",
`iris/android-app/src/transcript_client.rs`) logged under this
crate's fixed `android_logger` tag; and `ui-trace` gained a
`holddrag X1 Y1 X2 Y2 HOLD_MS MOVE_MS` action in `emulator-tools`
(press, hold, move, release as one continuous touch via the same
`MotionEvent`/`injectInputEvent` mechanism `swipe` already used),
closing the exact gap named above.
(b), continued: **a real iris number exists, but it is not the clean
24-swipe `transcript-bench.sh`-equivalent loop this box originally
wanted, for a reason worth recording precisely.** Driving the
gesture loop against a freshly-restarted app repeatedly produced
**zero** frames recorded (both by `gfxinfo`, already known, and now
also by `FrameReport` itself) even though the coordinates were
confirmed on-screen to sit over real row text (measured by scanning
a screenshot column for the first non-black pixel, not guessed) --
while the *same* coordinates driven a few commands later, or
combined into a slightly different sequence, sometimes produced 30+
real frames and a genuine screenshot diff. This is not the earlier,
already-understood "already at that scroll edge" case (AGENTS.md's
own note) -- it reproduced with fresh content confirmed taller than
the viewport, in both scroll directions, inconsistently across
otherwise-identical commands. The one measured correlate: this
checkout's own `EMU_GPU=software` emulator was independently seen at
**~78% of one CPU core, continuously**, while idle on-screen (`ps
aux` mid-session) -- SwiftShader's software rasterisation is
CPU-bound by design (AGENTS.md's Vulkan-in-the-emulator section), so
a synthetic touch's delivery to the SurfaceView competing with that
load is the leading candidate, not yet confirmed with a sampler
running *during* the gesture (the standing rule against diagnosing
from measurements taken after the fact applies here and this pass
did not have time to build that sampler). Recorded as a new,
distinct, unresolved finding in `IRIS_TODO.md` rather than folded
into the already-closed "no `hold`-then-drag primitive" gap.
**The number obtained, honestly scoped**: tapping "Frame report"
immediately after a run that *did* produce real scrolling frames
(screenshots differ, confirmed by hash) read
`frames=34 janky%=61.76 p50=26.5ms p90=48.0ms p99=98.1ms
worst=98.1ms` -- real, measured wall-clock time through iris's own
render path from a real on-device touch-drag, not a synthetic
probe, but accumulated across several swipe gestures across
multiple `ui-trace record` invocations rather than one clean
24-swipe loop, so it is **not directly comparable** to the Compose
figure below in scale, only in kind. Given the CPU contention
candidate above, a high jank percentage here is expected under
software rendering and should not be read as iris's number on real
hardware. The Compose figure quoted for reference
(**8.96% janky frames, 99th percentile 150ms, 212 frames rendered**)
is the same measurement this box already recorded on 2026-09-05
earlier the same day, under the same `EMU_GPU=software` config on
this same checkout's emulator -- **not re-taken this pass** (the
session's time went to building the two rigs above and diagnosing
the flakiness instead), and against a *different* sandbox session
(40 messages, id `8920378e7167ebcd`) than this pass's own (120
messages, id `c76b71d017a54589`), so the two numbers share
configuration but not identical content -- said plainly rather than
presented as a matched pair.
(c), continued: **confirmed on-device, by both routes the task
asked for.** `ui-trace record --do "holddrag 300 1850 300 2050 600
300"` (a 600ms hold, comfortably past `DragArbiter`'s 500ms
`LONG_PRESS`, then a 300ms move) against a row's real text produced,
in order: `iris selection: begin at row 3165`, then a sequence of
`iris selection: extend to row ...` lines as the drag crossed row
boundaries -- logged from `transcript-ui/src/selection.rs`'s
`Selection::drag` (new `log` dependency, smallest addition since
selection has no accessibility label of its own yet, per
`IRIS_TODO.md`'s existing gap). A screenshot taken right after shows
the expected highlighted selection spanning multiple rows,
confirming the mechanism visually as well as in the log. This is
the first time `DragArbiter`'s pan-vs-select decision has been
driven by a *real* Android touch sequence rather than only its own
synthetic-clock unit tests.
**What remains, named rather than silently dropped (also in **What remains, named rather than silently dropped (also in
IRIS_TODO.md, dated 2026-09-05):** IRIS_TODO.md, dated 2026-09-05):**
- **A real per-app frame-time number for iris** -- (b) above. Needs - **Intermittent touch delivery under `EMU_GPU=software` CPU load**
`iris` to grow its own render-report/frame-timing instrumentation -- new finding above. Needs a sampler running *during* a failing
(what the Compose app's copy-button report already gives) before gesture (load, `dumpsys input`, a frame-by-frame `ui-trace`
any `dumpsys`-based comparison can go further than functional. capture at `-i 0`) rather than another guess after the fact, and
- **Long-press-then-drag-to-select, on-device** -- (c) above. Needs ideally a comparison against `-gpu host` (real Vulkan, but shared
a driving primitive this pass's tools do not have. with whichever GPU config a peer session's emulator already
holds) to see whether it is specific to software rendering.
- **A clean, single 24-swipe `transcript-bench.sh`-equivalent
iris number** -- blocked on the above; the number this pass got is
real but not that clean run.
- **Row-level accessibility names** -- behaviour 6, I5's own writeup - **Row-level accessibility names** -- behaviour 6, I5's own writeup
above. above.
- **A tappable link and a code-span background chip** -- behaviour 2. - **A tappable link and a code-span background chip** -- behaviour 2.
@@ -2720,21 +2845,21 @@ silently on real hardware.
own unit tests), not by a dedicated repro this pass. own unit tests), not by a dedicated repro this pass.
**Net for the recommendation.** Item 3 ("decide when the transcript **Net for the recommendation.** Item 3 ("decide when the transcript
screen exists in both, from the measurements") still cannot be screen exists in both, from the measurements") now has a real number
decided by a render-time number on either side -- E2 could not on the iris side for the first time -- `FrameReport` works, is unit
produce one for Masonry (no working touch-scroll to measure), and tested (6 tests over the ring/percentile math), and captured a real
this pass could not produce one for iris either, now for a different on-device touch-drag's timing -- but that number is scoped narrowly
and more fixable reason: `iris` itself has no frame-timing (accumulated over several gestures, not one comparable loop) because
instrumentation yet, not that the screen doesn't work. What *can* be of the intermittent-touch-delivery finding above, so it still cannot
said, updating E2's own conclusion further: iris now has a real, be read against Compose's 8.96%/150ms figure as a clean comparison.
working Android integration -- a real server, a real scrolling What *can* be said, updating the account further: iris's Android
transcript, real touch-drag panning, tap-by-name accessibility, all integration, its frame-timing instrumentation, and its long-press
confirmed on-device -- plus the two structural points E2 already selection have all now been exercised by real on-device touch input
found Masonry unable to reach at all (cross-row selection, true end to end (not only unit tests), on top of the structural points
per-span inline rich text). Whether iris's *smoothness* matches or E2 already found Masonry unable to reach at all (cross-row
beats Compose's is the one question actually left for whoever picks selection, true per-span inline rich text). `DECISIONS.md`'s
up "add frame-timing instrumentation to iris" next; DECISIONS.md's DEFERRED item is updated with this session's numbers and the
DEFERRED item is updated with exactly this gap. touch-delivery caveat rather than a decision made here.
## For the next agent ## For the next agent