Files
ARCADIA-Studio/harness/experiments/scenario-label-measurement-20260913/attempt2/README.md
T

88 lines
5.0 KiB
Markdown

# Scenario label measurement: preserved candidate and source correction
This is an **unwired, uncompiled experiment**, not an accepted renderer policy.
Source base: `208268c8aa7f6bc3c2bab6a3c0657358f3f7dc23`.
Parent's docs-only worktree HEAD: `75cb09dade2cf4b9a176b5e6159f43e2345d196e`.
Only the two new `crates/oa-desktop/src/behavior/scenario_label` module/test
paths and this evidence directory belong to this correction.
## Preserved attempt 1
`attempt1/scenario_label.rs` and `attempt1/tests.rs` are the exact raw files
reviewed before correction. Both SHA256 values were checked before copying and
again after copying; [manifest](attempt1/manifest.json) records source paths and
hashes. They remain historical evidence, not alternate compiler inputs.
Independent static review identified:
1. A retained Label Arc lacked its font epoch and zoom. Cached dimensions could
be reused by painting/hit/navigation after their measurement context changed.
2. Iced's WGPU text cache omits font Version; remeasuring only this module cannot
establish dynamic-font parity with an already-populated renderer cache.
3. The font-epoch test had already evicted its original entry with three variants
in a capacity-two cache. Different Arc identity did not prove invalidation.
4. Finite scaled metrics could overflow when converted back to world units.
Concrete example: size 2, Relative(MAX) line height, zoom 0.5.
These were source findings. Neither the old candidate nor the correction was
compiled or executed by this worker; no failure/pass count is inferred.
## Corrected experimental seam
`RenderSession::after_fonts_settled_and_renderer_reset()` explicitly records a
caller-established settled-font rendering lifetime. It does not reset or inspect
the renderer. The caller must finish font loading and create a fresh renderer
cache, then prohibit font changes between resolution, guarded consumption and
draw. A changed global font Version rejects the old session; a new local cache
alone is not a repair for WGPU's old glyph buffers.
Labels record that session identity/font Version and measured zoom. Displayed
text, retained-source bytes, bounds, field retention and canvas Text construction
use checked accessors. Another session, another zoom or a detected font change
rejects a retained artifact. Returned raw Text/bounds must be consumed in that
checked context: holding those values across context changes bypasses the guard.
This is an explicit limited contract, not atomic protection against a concurrent
font load or an incorrect renderer transform supplied by the caller.
Finite world line metrics are checked before shaping. Actual measured dimensions
are checked again after division by zoom. The existing 64KiB source and 4096
grapheme budgets remain explicit experiment errors, not adopted product limits.
Ten test candidates now include separate resident-entry font-epoch invalidation,
fresh-session invalidation, stale artifact rejection for every consumer, and
the overflow counterexample. The invalidation assertions require a still-resident
entry, positive prior measurement count and an increased count afterward.
These tests do not mutate the global font database or claim dynamic-font rendering
acceptance. The existing actual Paragraph comparisons remain layout-metric
oracles, not raster-ink/Scene collision evidence.
## Pinned primary APIs and remaining evaluator
Cargo.lock pins iced_graphics/iced_wgpu 0.14.0 and iced_widget 0.14.2. Relevant
local registry sources: `iced_wgpu-0.14.0/src/geometry.rs` (`fill_text`, scaled
font metrics), `iced_wgpu-0.14.0/src/text.rs` (`Text::Cached` allocation),
`iced_graphics-0.14.0/src/text/cache.rs` (Key/hash lacks Version), and
`iced_graphics-0.14.0/src/text.rs` (FontSystem::load_font/version).
Independent reviewer confirmed `geometry.rs:306-360`, WGPU `text.rs:443-500`
and its retained BufferCache at line 304 (trim at 435 only evicts unused
entries), graphics `text/cache.rs:109-146`, and graphics `compositor.rs:69`.
The compositor's font-load path changes the global FontSystem, not the WGPU
buffer cache. A check immediately before canvas_text is therefore not atomic
with the later WGPU prepare; fonts must remain unchanged for the entire session.
The module remains undeclared in behavior.rs. Parent may separately add test-only
`#[cfg(test)] mod scenario_label;` and run:
```
cargo test -p oa-desktop --locked --offline behavior::scenario_label::tests:: -- --test-threads=1
```
Expected selection is exactly ten tests, not a claim they pass. Corridors remain
external; ordinary/reversed and self-message positioning is not selected here.
The bounded prefix search guarantees measured fit, not a globally maximal prefix
for all contextual shaping. No wrapping, row-height change, public schema or
production gesture is introduced. Real WGPU label ink, activation shoulders,
clipping, viewport transforms, and actual navigation integration remain required
before adopting the seam. Original fixed 32-grapheme/225-unit rendering is still
unchanged for baseline comparison.