Say which state NFR-P11 forbids losing, since one kind is dropped on purpose

NFR-P11's criterion was "no dropped frames, no state loss" across a layout
class transition. Read literally, the interface already fails it, and fails it
by design: `apply_layout_class` clears the user's panel open/closed choices
whenever the class changes, and `PanelChoices` documents why — a choice made in
landscape answers a different question from the one portrait asks, and carrying
it across leaves a 232 px sidebar on a screen with no room for it.

A requirement that the code deliberately contradicts is worse than no
requirement, because the next person to read it either "fixes" the behaviour or
learns to discount the register.

So the criterion now names what must survive — the open image and version, the
selection, scroll position, the in-progress edit and its undo history, the
current mode — and states the exemption with the reasoning attached. Panel
disclosure is a default re-derived per class, not state; the user's
disagreement with it is remembered within the class where it was expressed.

The intent is unchanged: a resize must not cost the photographer anything they
did. It is now possible to write a test for that.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-30 10:21:32 +02:00
co-authored by Claude Opus 5
parent 99f9b5b7c5
commit 11e515a295
+13 -1
View File
@@ -1330,13 +1330,25 @@ These are targets to design against and measure, on the reference desktop
| **NFR-P14** | Focus peaking overlay ready | < 100 ms after preview | < 150 ms |
| **NFR-P15** | Drawn mask stroke → visible (ARCH §6.11) | < 16 ms, no cursor lag | < 16 ms |
| **NFR-P10** | Touch gesture → visual response | < 16 ms | < 16 ms |
| **NFR-P11** | Layout class transition (window resize) | No dropped frames, no state loss | n/a |
| **NFR-P11** | Layout class transition (window resize) | No dropped frames. No loss of *photographic* state: the open image and version, the selection, scroll position, the in-progress edit and its undo history, and the current mode. Panel disclosure is explicitly exempt — see below | n/a |
| **NFR-P12** | Warm-start shader pipeline setup (cached) | < 100 ms | < 100 ms |
Every target above requires a stated measurement method, workload, and pass threshold before it is
testable. NFR-P8 in particular must state whether it measures RSS inclusive or exclusive of GPU
allocations, and whether it holds after SQLite's page cache warms on a 50k catalog.
**On what NFR-P11 means by state.** It said "no state loss", which the implementation contradicts on
purpose, so the requirement has been made specific rather than left to be read as forbidding
something it should not. `apply_layout_class` discards the user's panel open/closed choices when the
class changes, and the argument for that is sound: a choice made in landscape answers a different
question from the one portrait asks, and carrying it across is how a photographer ends up with a
232 px sidebar on a screen with no room for it and no memory of having asked for it. Panel
disclosure is a *default*, re-derived per class, with the user's disagreement remembered only within
the class where it was expressed.
Everything the photographer produced or navigated to is a different matter, and none of it may be
touched by a resize. That is the list in the criterion, and it is the testable half.
**Performance regressions fail the build.** §9's benchmark suite runs per-commit; a regression
beyond a stated tolerance is a build failure, not a notification. Performance work rots otherwise.