Skip to content

Search is only available in production builds. Try building and previewing the site to test it out locally.

The frame-rate budgets are the most-cited numbers in the corpus and no ADR owns them

Источник: dev/fera-research/docs/oc1/008-frame-budgets-unowned-unfalsifiable-governor-loops-the-bench.md (read-only; сгенерировано scripts/sync-docs.mjs)

The frame-rate budgets are the most-cited numbers in the corpus and no ADR owns them

Section titled “The frame-rate budgets are the most-cited numbers in the corpus and no ADR owns them”
  • kind: risk
  • area: perf / ui
  • evidence:
    • The budgets 24 / 45 / 60–75 fps appear in five documents: RFC.md:138-139, TECHSPEC.md:289-292, QA.md:116-118, PREDICT.md:54, RESEARCH-OQ-003.md:102-103.
    • They appear in zero ADRs. grep -n "fps" ADR.md returns exactly one hit — ADR.md:764, an unrelated game-engine aside (“per frame, under 16 ms whole-frame budgets”). So five docs load-bearing the numbers, no decision record producing them.
    • PREDICT.md:54 labels their origin explicitly: “Budgets [author]: UI 24, message updates 45, stickers/animation 60–75 fps” — i.e. author-supplied, not measured, not derived.
    • PREDICT.md:54 then assigns them to a runtime control loop: the “frame-budget governor … Adapts decode-ahead ring K, sticker raster 256/512, concurrent animation count from measured frame times.”
    • QA.md:116-119 gates on them: “each path (UI ~24 fps, message updates ~45 fps, stickers 60–75 fps) meets its own budget” and “a saturated sticker path [does not degrade] the others”.
    • RESEARCH-OQ-003.md:380-384 freezes bench metric M3 at “50 concurrent, 60 and 75 fps ticks … zero budget misses at 60 fps”.
    • Scene freeze: OQ.md:130-131 “parameters below are FROZEN as fera-scene-v0”; sticker count OQ.md:147 = 50 concurrently animating stickers.
    • Substrate: ADR.md:971 — “Vello + Parley + winit + AccessKit”.
  • severity: mid

Four separate defects in one number set:

  1. No owner. Every other architectural choice in this corpus traces to an ADR (README.md:41-45). These five numbers do not. If someone later decides the chrome path should be 60 fps, there is no record to amend — and QA’s gate silently inverts. An ADR (or an explicit “performance budgets” section in TECHSPEC with a rationale) is the missing artifact.

  2. The gate is not falsifiable as written. QA.md:117-118 gives “~24 fps”, “~45 fps” (tildes = no target) and “60–75 fps” (a range, with no statement of which end is the pass condition and which is the stretch goal). “Meets its own budget” therefore has no defined pass criterion. A budget that cannot fail is not a gate.

  3. “Never share one frame loop” is probably not implementable as written. TECHSPEC.md:291-292: “Each path is scheduled and measured against its own budget; paths with different budgets never share one frame loop.” With Vello + Parley + winit (ADR-028), the process has one EventLoop, one window, one wgpu device and one present path. Three independent frame loops means three windows or three present paths, which contradicts the single-renderer design (ADR.md:980-982: “Only lists, scrolling, and message rendering are implemented on the project’s own engine”) and the Native-axis ownership rules (ADR.md:934-939). What is implementable is per-path scheduling and budget accounting inside one frame loop — e.g. per-path dirty tracking, per-path deadline meters, and a policy for which paths share a tick. The spec asks for the harder thing; the engine substrate forbids it.

  4. The governor invalidates the benchmark that validates the governor. PREDICT.md:54’s governor adapts “concurrent animation count” from measured frame times; RESEARCH-OQ-003.md:380 freezes M3 at exactly 50 concurrent stickers, and OQ.md:147 bakes 50 into the frozen scene. A closed loop that reduces the sticker count on slow frames will meet its budget by changing the scene, and the bench will report a pass for a system that is silently dropping animations. That is the classic feedback-loop-measures-itself failure, and it sits directly on top of the sticker research that was carefully pre-registered.

Also worth flagging while it is open: 24 fps for UI chrome is 41.6 ms per frame. That is either a deliberate power-saving posture — plausible, this corpus is power-obsessed (PREDICT.md:243-249 §10 Energy) — or a missing digit (120/240). Nothing in the corpus says which, and QA gates on it either way. If it is deliberate, the number needs its rationale recorded; if it is a typo, three QA gates and a research doc’s conclusions are anchored to a number nobody meant.

Варианты решения (tradeoffs)

Section titled “Варианты решения (tradeoffs)”
  • (A) ADR-032 “Performance budgets and the frame governor”. Records the three numbers with rationale, defines the pass condition per path (min fps, p99 frame time, budget-miss rate), and scopes the governor’s authority: it may adapt K/raster, but not the benchmark’s concurrency parameter.
  • (B) Reword TECHSPEC:291-292 from “never share one frame loop” to “never share a budget; scheduling is per-path within one frame loop”, and add a note that three loops would require three surfaces.
  • (C) Separate surfaces (offscreen render targets per content class, composited by the Engine) — genuinely three independent loops, but adds a compositor, extra GPU memory and cross-path sync; way out of proportion for a chat client.
  • (D) Drop the per-path budgets, keep one 60 fps target plus per-path p99 frame-time meters. Simplest, loses the deliberate power-saving posture.

(A) + (B) together.

  1. New ADR-032 owning the budgets, with per-path pass conditions in the QA-friendly form: target fps + p99 frame time + budget-miss rate over the frozen scene. Write down whether 24 fps is intentional (power) or a typo — one line, but it is the line everything hangs on.
  2. Reword TECHSPEC.md:291-292 per (B): one frame loop, per-path budgets and dirty-tracking. The current sentence promises an architecture the chosen substrate does not allow, and an implementer will either fail it or silently ignore it.
  3. In the ADR, bound the governor (PREDICT §3 row 1): it may adapt decode ring K and sticker raster; it may not adapt concurrency when a benchmark scene is active, and it must expose a “bench mode” that pins scene parameters. Otherwise M3 and the frozen scene are unfalsifiable.
  4. QA: replace QA.md:116-119 with the concrete pass conditions from the ADR, and drop the tildes/ranges.
  5. File one new OQ: what is the budget when the window is occluded or on a 30 Hz display? A hard 24 fps chrome budget interacts badly with vsync-driven loops, and nothing in the corpus mentions refresh-rate variance at all.