docs: publish Scenario font lifetime prerequisites

This commit is contained in:
2026-09-13 02:33:29 -07:00
parent 6595a8ad1b
commit 4dacb6f430
2 changed files with 26 additions and 0 deletions
@@ -0,0 +1,24 @@
# Scenario label font lifetime: bounded source investigation
Source-only review, 2026-09-13. Application pin: `c4a2cf63f11818cf7fc766acf3a2779768a2a658`, branch `codex/scenario-spacing-ytr83r-20260913`; working tree observed clean. No compilation, tests, renderer execution, or production edits. Repository references below resolve at that commit. Dependency references identify the exact published Cargo package and its relative source path, reproducible from the commit's `Cargo.lock` checksums without another machine's local directories. The lockfile pins **iced_widget 0.14.2**, but **iced, iced_core, iced_graphics, iced_wgpu, iced_winit and iced_program 0.14.0**, cosmic-text 0.15.0 and fontdb 0.23.0; describing all of these as Iced 0.14.2 would be imprecise. Package archives are available from crates.io, e.g. [iced_graphics 0.14.0](https://crates.io/crates/iced_graphics/0.14.0), [cosmic-text 0.15.0](https://crates.io/crates/cosmic-text/0.15.0), and [fontdb 0.23.0](https://crates.io/crates/fontdb/0.23.0).
## Verified startup sequence
1. Repository `crates/oa-desktop/src/main.rs:38–61` passes `App::new` to `iced::application`, then configures title/theme/subscription/window and runs. It supplies neither `.font(...)` nor custom font settings. `iced-0.14.0/src/application.rs:163` uses default settings; `iced_core-0.14.0/src/settings.rs:45–54` initializes `fonts` to an empty vector.
2. `iced_winit-0.14.0/src/lib.rs:105` constructs `program::Instance` before window/compositor setup. `iced_program-0.14.0/src/lib.rs:673–676` calls the boot function there. Repository `crates/oa-desktop/src/app.rs:556–566,642` constructs `text_editor::Content::with_text` during `App::new -> with_project`. `iced_widget-0.14.2/src/text_editor.rs:400–407` delegates to the renderer Editor; WGPU uses graphics `Editor` (`iced_wgpu-0.14.0/src/lib.rs:70,720`). `iced_graphics-0.14.0/src/text/editor.rs:89–110` synchronously acquires the shared font system and sets/shapes the source text.
3. `iced_graphics-0.14.0/src/text.rs:115–133` initializes that shared system through `OnceLock`, using Cosmic's font database, embedded Iced Icons, and feature-conditional Fira Sans. It records `Version::default()` after construction. Cosmic `src/font/system.rs:144–163,396–403` synchronously creates the database, scans system fonts, then loads supplied embedded fonts. Thus the database and its initial version exist **before App::new returns**, not necessarily before entry to App::new. They exist before the first normal App view or draw.
4. `iced_winit-0.14.0/src/lib.rs:590–603` creates the compositor and loads settings fonts (empty in this application). `src/window.rs:51–68` then creates the renderer. Only afterward does `lib.rs:683–692,1279–1290` build the first UI and call `program.view`. WGPU `src/lib.rs:99–117` starts new text state; `src/text.rs:305–318` gives it an initially empty buffer cache/storage.
## What lazy fallback does, and what Version covers
Cosmic `src/font/system.rs:255–274` lazily obtains fonts for already indexed face IDs, populates its font cache, and calls `fontdb::Database::make_shared_face_data`. This can map a font file and replace its existing source with shared data (`fontdb-0.23.0/src/lib.rs:742–775`). It does not call Iced's font-loading wrapper or increment Iced's Version. “Settled fonts” can therefore mean a fixed indexed font set; it must not mean all fallback glyphs/files are eagerly loaded.
Iced's `FontSystem::load_font` is the tracked mutation boundary (`iced_graphics/src/text.rs:152–170`). It changes the database and increments Version, apart from its duplicate borrowed-pointer early return. Runtime `Action::LoadFont` reaches this through `iced_winit/src/lib.rs:1776–1782` and `iced_graphics/src/compositor.rs:69–73`. A production-source search found no application call to `font::load`, `load_font`, `db_mut`, or any other direct global font mutation; the only explicit loading is in the **unwired** scenario-label experiment tests. Existing font choices such as MONOSPACE select a font; they do not load another font set. Opening documents, rebuilding the source editor, changing zoom, and normal fallback shaping therefore do not themselves advance Version.
Version is not a universal font-content fingerprint. The exposed `FontSystem::raw()` would permit a future caller to mutate Cosmic's database without that increment. Fontdb scans predefined Windows system/user font directories once (`src/lib.rs:390–422`); this is not a live OS font watcher. Its mapped-file safety contract explicitly allows externally changed file bytes to become visible (`src/lib.rs:728–739`). Stable installed font files during the run remain an assumption, not a guarantee supplied by Version.
## Smallest truthful production boundary
For this fixed-font normal desktop startup, capture and retain one render session on the first measured-label use reached through the normal `App::view` path, after initial renderer creation. Initial creation satisfies the fresh-renderer requirement; no extra reset, fallback warm-up, or asynchronous font-loading wait is justified by current production source. Capturing the existing `after_fonts_settled_and_renderer_reset` attestation **inside App::new** would be too early because the renderer has not been created yet. A headless/direct-view evaluator must establish its own renderer/session ordering rather than inherit the desktop proof.
The session can remain valid across ordinary Scene/document rebuilds while the font set stays fixed. Keep the existing zoom/session/version consumer guards. If later work adds runtime font loading, invalidate label artifacts and establish a genuinely fresh renderer/text-cache lifecycle before taking a replacement session; simply recapturing the version is insufficient. WGPU `src/text.rs:455–504` uses graphics Cache, whose key (`iced_graphics/src/text/cache.rs:104–130`) omits font-system Version and whose existing entries are reused (`:30–43`). This report does not establish dynamic-font support, raster ink bounds, placement policy, or native measured-label parity.
@@ -4,6 +4,8 @@ Source-only review of c4a2cf63f11818cf7fc766acf3a2779768a2a658, 2026-09-13. **Re
The prior [published measured-label integration boundary](http://217.177.34.108:3000/sorokin.oleg.edu/ARCADIA-Studio/src/commit/bcc15ee2259f4d852ade7986829e7eab88f758f9/harness/experiments/scenario-workspace-preparation-20260913/measured-label-integration.md) remains historical evidence. This note does not modify its archive or adopt the unwired measurement/corridor helpers. Review criteria are truthful operation-field membership matching actual paint, responsive multi-view lookup on large models, explicit Saved identity and camera expectations, and simple maintainable lifetimes.
The [font-lifetime source investigation](scenario-label-font-lifetime-20260913.md) records the startup and cache prerequisites for this experiment. It is source-only evidence; no measured-label implementation or runtime font policy is adopted.
## Comparison and falsifiers
| Candidate | Advantage | Concrete failure probe |