From e22945a62d80ec4643b750cb581f49f7505fd6cf Mon Sep 17 00:00:00 2001 From: Duncan Tourolle Date: Sun, 30 Aug 2026 10:19:48 +0200 Subject: [PATCH] Tag the colour-independent status that was already built and unrecorded MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NFR-A11Y-3 — no status conveyed by hue alone — read as untagged, and outstanding.md said "no compliance work found". Both were wrong. Five places already implement it, and four of them name the requirement in a comment explaining the design; what none of them had was a TRACES line. - `histogram.rs::percentage` states clipping as a figure and keeps `<0.1%` distinct from `0%`, so the text cannot say "none" while the marker beside it is lit. - `histogram.slint`'s ClipReadout is the other half: a marker that appears and disappears rather than changing tint, and the figure next to it. Either alone reads. - `library.slint`'s star strip is a solid star against an outline, differing in shape and luminance, over an achromatic palette. - `library.slint`'s FlagMark is a tick against a cross, and a reject also dims its whole cell. - `peaking.slint`'s colour chips say "Red" and "Cyan". A control for choosing between hues, presented only as hues, is unusable by exactly the person most likely to need it. The tag is honest about being wider than the evidence, and outstanding.md now records both gaps. Only the clipping clause has a test that would fail if the behaviour were removed; the three Slint components are argued rather than asserted. And the requirement's first named example — catalog colour labels — has no interface at all: `label` is a nullable column nothing writes or shows. That clause is untestable rather than satisfied, and closes when the label UI is built with a shape from the start. Co-Authored-By: Claude Opus 5 (1M context) --- docs/outstanding.md | 19 ++++++++++++++++--- ui/dr-ui/src/histogram.rs | 3 +++ ui/dr-ui/ui/histogram.slint | 1 + ui/dr-ui/ui/library.slint | 2 ++ ui/dr-ui/ui/peaking.slint | 2 +- 5 files changed, 23 insertions(+), 4 deletions(-) diff --git a/docs/outstanding.md b/docs/outstanding.md index 5959231..465bf31 100644 --- a/docs/outstanding.md +++ b/docs/outstanding.md @@ -260,9 +260,22 @@ on one control — the parameter slider in `adjust.slint` — and nothing is set all. Everything else in eighteen Slint files is unnamed to AT-SPI and TalkBack. The requirement's own caveat, that Slint's Android accessibility needs verifying, is spike S13, which has not run. -**NFR-A11Y-3 — Colour-independent status.** No compliance work found. This is cheap to satisfy while -a control is being written and expensive to retrofit across forty of them, which is an argument for -doing it as part of the NFR-A11Y-2 pass rather than after it. +**NFR-A11Y-3 — Colour-independent status.** Built where a control exists, and now tagged: the +clipping readout pairs a marker that appears or disappears with a figure in words, the rating strip +is a solid star against an outline in an achromatic palette, the pick/reject mark is a tick against +a cross, and the focus-peaking colour chips say "Red" and "Cyan" rather than showing swatches. Each +of those already carried the reasoning in a comment naming this requirement and simply had no +`TRACES` line. + +Two caveats, because the tag now says more than the evidence does. **Only the clipping clause has a +test** — `a_clipping_figure_distinguishes_none_from_nearly_none`, which pins `<0.1%` apart from `0%` +so the figure cannot contradict the lit marker beside it. The three Slint components are +inspected-and-argued, not asserted, and nothing would fail if a future edit made a star differ only +in tint. **And the requirement's first named example has no interface at all**: catalog colour +labels are a nullable `label INTEGER` column on the versions table and are set and shown nowhere, so +the clause about them is untestable rather than satisfied. That clause closes when the label UI is +built, not before, and it should be built with a shape from the outset — which is the same argument +as below, for doing this alongside NFR-A11Y-2 rather than after it. --- diff --git a/ui/dr-ui/src/histogram.rs b/ui/dr-ui/src/histogram.rs index efd27ad..59c601e 100644 --- a/ui/dr-ui/src/histogram.rs +++ b/ui/dr-ui/src/histogram.rs @@ -353,6 +353,7 @@ fn fraction(clipped: u32, pixels: u32) -> f32 { } } +/// TRACES: NFR-A11Y-3 /// How much of the frame is gone, as a figure rather than a colour. /// /// NFR-A11Y-3 asks that no status be carried by hue alone, and this is the @@ -364,6 +365,8 @@ fn fraction(clipped: u32, pixels: u32) -> f32 { /// Distinguishes "none" from "not none but under a tenth of a percent": those /// are different answers, and rounding the second to `0.0%` would tell a /// photographer their highlights were safe when the indicator beside it is lit. +/// `a_clipping_figure_distinguishes_none_from_nearly_none` is the test that +/// would fail if this became a colour again. fn percentage(clipped: u32, pixels: u32) -> String { if pixels == 0 || clipped == 0 { return "0%".into(); diff --git a/ui/dr-ui/ui/histogram.slint b/ui/dr-ui/ui/histogram.slint index ee92358..b5f80b9 100644 --- a/ui/dr-ui/ui/histogram.slint +++ b/ui/dr-ui/ui/histogram.slint @@ -134,6 +134,7 @@ component Trace inherits Rectangle { } } +// TRACES: NFR-A11Y-3 // A clipping readout: a lit marker and a figure. // // **Two affordances for one fact, and NFR-A11Y-3 is why.** No status in this diff --git a/ui/dr-ui/ui/library.slint b/ui/dr-ui/ui/library.slint index 57df578..1aca122 100644 --- a/ui/dr-ui/ui/library.slint +++ b/ui/dr-ui/ui/library.slint @@ -649,6 +649,7 @@ export component PhotoRoll inherits Rectangle { } } +// TRACES: NFR-A11Y-3 // A row of five stars, readable at a glance and clickable to set a rating. // // **Filled versus empty carries the meaning, not colour.** NFR-A11Y-3 forbids @@ -796,6 +797,7 @@ export component StarStrip inherits Rectangle { } } +// TRACES: NFR-A11Y-3 // The pick/reject mark. // // A shape rather than a colour, for the same NFR-A11Y-3 reason as the stars: diff --git a/ui/dr-ui/ui/peaking.slint b/ui/dr-ui/ui/peaking.slint index e9b7e51..59d45bb 100644 --- a/ui/dr-ui/ui/peaking.slint +++ b/ui/dr-ui/ui/peaking.slint @@ -1,4 +1,4 @@ -// TRACES: FR-CULL-3 +// TRACES: FR-CULL-3 | NFR-A11Y-3 // The focus-peaking switch, and the two choices it exposes. // // **An instrument, not an operation**, exactly as the histogram above it is: