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 fpsappear 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.mdreturns 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:54labels 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:54then 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-119gates 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-384freezes 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 asfera-scene-v0”; sticker countOQ.md:147= 50 concurrently animating stickers. - Substrate:
ADR.md:971— “Vello + Parley + winit + AccessKit”.
- The budgets
- severity: mid
Суть / Substance
Section titled “Суть / Substance”Four separate defects in one number set:
-
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. -
The gate is not falsifiable as written.
QA.md:117-118gives “~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. -
“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 oneEventLoop, 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. -
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:380freezes M3 at exactly 50 concurrent stickers, andOQ.md:147bakes 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.
Предлагаемое решение
Section titled “Предлагаемое решение”(A) + (B) together.
- 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.
- Reword
TECHSPEC.md:291-292per (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. - 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.
- QA: replace
QA.md:116-119with the concrete pass conditions from the ADR, and drop the tildes/ranges. - 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.