6.4 KiB
Unwired Scenario label field experiment
This experiment starts from c4a2cf63f11818cf7fc766acf3a2779768a2a658. Initial extraction is commit c3ad6f130ba6dda271fe8417db46df29e4033ad8; the follow-up strengthens its evaluators. Neither version wires scenario_label into production. No renderer, App, navigation, source language, or model behavior is adopted here.
The implementation lives in crates/oa-desktop/src/behavior/scenario_label.rs, with focused evaluators in scenario_label/field_tests.rs. It preserves the winning shaped buffer's cluster advance rectangles and exact scalar source mapping. Returned covered, truncated, and unresolved ranges are distinct; partial retention and shared clusters are explicit. Synthetic ellipsis never represents source text. Missing glyphs, controls/default-ignorables, and absent advance geometry cannot establish affirmative coverage. These are advance/hit rectangles, not ink bounds or proof of actual viewport visibility.
Follow-up evaluator corrections
The original mixed bidi fixture is Latin-leading. Its glyph embedding levels are mixed, but LayoutRun::rtl is false, so it cannot exercise Iced's RTL paragraph alignment branch. Two added cases require a genuinely RTL-leading full and ellipsized paragraph and assert run.rtl == true. Their geometry oracle builds a separate Iced Paragraph using the actual displayed string and compares the complete rectangle set, rejecting omissions, extras and duplicate output boxes. Explicit source word spans are clipped only against the literal displayed prefix before ellipsis; no candidate retained-source map or cluster snapshot supplies the expected answer. The existing mixed-direction case now uses the same complete-set comparison in addition to its visual-gap checks.
The relevant pinned sources are iced_graphics 0.14.0/src/text.rs:202–256 (measurement and RTL alignment), src/text/cache.rs (winning buffer), and cosmic-text 0.15.0/src/buffer.rs/layout.rs (actual layout runs and clusters). iced_widget is 0.14.2; the graphics package is 0.14.0. Reproduce package inputs through the base commit's Cargo.lock.
Font and execution limitations
At source 11c605f917, the isolated harness compiled and its default-test diagnostic reported 21 passed, two failed and two ignored. The intended first listing accidentally executed tests; a later literal listing reported all 25. A separate serial normal run reproduced the same two failures before either reached field_layout: the host font did not meet the tests' exact ffi-cluster preconditions. No actual face identity was captured for those failed cases, so the failure must not be attributed to a guessed family. Parent-owned closed runner receipts are the execution authority; this note does not turn the failed diagnostic into a passing gate.
The correction uses an unmodified, byte-pinned Noto Sans fixture from cosmic-text 0.15.0 for exactly those two tests; see fixture source, hashes and license. Standard liga contains the required ffi substitution. Each test verifies the actual Paragraph face bytes and retains its positive nonzero ffi-cluster precondition. The partial-field case compares the complete shared rectangle; the Auto case also requires three initial Basic clusters followed by the actual Advanced final-buffer rectangle set. Neither infers successful geometry merely from a shaping enum.
The two fixture-loading tests are ignored by default because their isolated setup replaces the global font database. Run each as the sole exact test in a fresh process: --ignored --exact --nocapture --test-threads=1. Do not run all ignored tests together. This prevents ordinary/default parallel test execution from invalidating render sessions. Their leaf names are advanced_ligature_partial_field_uses_whole_shared_cluster_not_fraction and auto_ascii_to_ellipsis_advanced_transition_uses_final_buffer. The existing font-load invalidation test remains separately isolated.
Other cases retain installed system-font selection and explicit font/cluster/coverage preconditions. RTL font IDs, PostScript names and family records are diagnostic metadata, not portable content hashes. No new dependency or production font policy is introduced. A missing precondition remains an evaluator/environment finding, not a geometry pass.
After this correction the field module contains ten normal tests and three ignored tests (two isolated ligature cases plus the lookup diagnostic). Across the parent label module the intended inventory remains 25, now 21 normal and four ignored. The corrected source is UNEXECUTED at handoff. The parent module remains unwired; ordinary desktop listing does not include it without the isolated evaluator harness. Source review is not compilation or execution evidence.
Optional bounded lookup diagnostic
Ignored leaf name: field_lookup_4096_scalars_and_combining_heavy_full_coverage. Run only this exact test, once an isolated compiled harness exists, with --ignored --exact <actual-listed-name> --nocapture --test-threads=1; obtain the qualified name from its real listing. Set SCENARIO_LABEL_FIELDS_SOURCE_PIN to the tested commit and separately bind the executable, source and toolchain in the runner receipt.
It measures one resolver call and three full-field lookups for each of two cases: 4,096 ordinary scalars/graphemes, and 4,096 scalars arranged as 1,024 combining-heavy graphemes. Both remain within the existing 64-KiB source/4,096-grapheme experiment budgets. An independent Paragraph warms the font machinery before timing, checks glyph coverage and supplies the complete expected rectangle set. Every lookup must cover the full original source, retain no unresolved/truncated ranges, and match that set exactly; its invariants are checked outside the timed interval.
On success it prints FIELD_LOOKUP_TIMING_JSON= with schema scenario_label_field_lookup_v1, per-case counts/font identities/resolver nanoseconds/three lookup samples, profile/OS/architecture, optional runner pin, and an explicit passed invariant status. It has no latency threshold and makes no native responsiveness claim. No optimization has been attempted before measurement. The combining case stresses clustered source mapping, while the plain case reaches the existing grapheme budget; neither claims exhaustive worst-case performance over every permitted 64-KiB input.