Skip to contentWolf-Rayet

Decision records

ADR-0093 A meter's state is a shape, and there is no exemption

Accepted2026-09-16Phase 4, reopened

#Context

Standing item 13 recorded that Rule B (ADR-0039) reads component CSS as text and so cannot see a state carried by some other mechanism, which is why $stateEncodingExemption exists and why meter held one. Its stated channel was length: *"a meter's variant is a threshold reading and the fill's length is what states it."* The item asked what a declared channel must prove before the exemption is granted.

Reading Meter to answer that found the exemption did not hold:

  • The variant is not derived from the length. Meter takes variant and

value as independent props, so variant="critical" with a short fill renders and the length says nothing about the state.

  • Length cannot separate two adverse states. Two of the three exempted pairs

are attention/critical and ok/critical. One threshold divides a track into two regions, and three variants do not fit in two.

With the exemption removed and nothing else changed, tokens:verify reports three pairs told apart by hue alone in all four themes — ok/attention, ok/critical and attention/critical at level 2, each pair resolving to one lightness. That is a use-of-colour failure in every theme, not only in the hue-less one, and it shipped under a declaration that said otherwise.

Two other components declared the key — pagination and presence — and in both the declared pair resolves to the same role, so Rule B never consulted it.

#Decision

meter draws its state as a shape. An adverse reading draws the shared vocabulary's own mark beside the number — the triangle for attention, the octagon for critical — in the fill's mark colour, and ok draws nothing, which is how the status indicator, the alert and the tag already read good news. The polygons are the vocabulary's, vertex for vertex; the discipline suite asserts them against every other component that draws them. The mark's extent is a new fixed token, glyph-size, for the reason input-field's chevron is fixed.

The exemption is retired, not narrowed. tokens:verify fails any component that declares $stateEncodingExemption, and that refusal was seen firing on a planted key before it was trusted. pagination's and presence's notes keep their text under $variantEncodingNote, which claims nothing a check reads. Item 13's question — *what must a declared channel prove* — is answered by removing the declaration: a channel Rule B cannot read is a channel no check can confirm, and the one use of it was wrong.

The meter gains the platform's meter semantics, found missing while reading: role="meter", aria-valuenow from the clamped fraction, the product's reading as aria-valuetext, and the governed label as its name.

#Consequences

Nine scenes move, and they are the nine that contain a meter: 13, 14, 15, 16, 18, 19, 33, 34 and 35, with their 27 themed siblings. Every move is an increase of about 1e-4 in the Scope holding the meter — the glyph's own light — and one Scope that holds no meter, #scope-log in 15 and 16, moved by −2e-6 because the reading's line box changed. Every scene keeps its declared verdict. darwin-arm64 is re-recorded for 11 unthemed and 33 themed values with linux-x64 untouched, so linux-x64 fails on exactly those values until its run is read and merged.

#Rejected

  • Narrow the exemption to the pairs length can carry. None of the three is

one, because the variant does not follow the value.

  • Derive variant from value and threshold. It would make length carry

ok against an adverse state and still leave attention/critical inseparable, and it would take a product decision — what is critical — out of the product's hands.

  • Move the variants' mark roles apart in lightness. ADR-0039 recorded why a

shared lightness at one rung is the ladder rather than a defect; the ladder is not bent to rescue one component.

  • A private shape for the meter. An adverse meter says what an adverse status

indicator says, and ADR-0028 puts a shared meaning in the shared vocabulary.