Tag the colour-independent status that was already built and unrecorded

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) <noreply@anthropic.com>
This commit is contained in:
2026-08-30 10:19:48 +02:00
co-authored by Claude Opus 5
parent 62e585844a
commit e22945a62d
5 changed files with 23 additions and 4 deletions
+3
View File
@@ -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();
+1
View File
@@ -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
+2
View File
@@ -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:
+1 -1
View File
@@ -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: