ADR-0048 A claim has an age, and a screen that cannot vouch may not look calm
#Context
ADR-0044 decided that quiet is what "fine" looks like. All 37 rows that may keep a level 1 resolve through emitter-ambient, 186 nominal marks went quiet, and 208 of 221 moved Scope values got quieter. That decision was correct and this record does not reopen it.
It has a consequence nobody wrote down. Once "fine" is quiet, "not reporting" looks exactly like it.
A StatusIndicator at level 1 with variant ok says *this unit is nominal*. It says that because something told the product so, and the product told the component. If that something stopped talking four minutes ago, the component keeps saying it. Nothing in this system knows the difference, and nothing on the screen shows one: the mark resolves through emitter-ambient either way, the budget prices it identically, and every check in the repository is green.
This is not a minor gap in a monitoring design system. It is the failure mode. The way a supervision screen actually hurts someone is not a missed alarm — an alarm that fires and is ignored leaves a trail, and the operator saw it. It is a screen that looks calm for twenty minutes because the feed died and eighteen green marks kept asserting a state they were told about before it did. The operator is not negligent in that scenario; they are being lied to by an interface that is working exactly as specified.
§11's ninety-second demo is *"a live screen renders, calm"*. The word doing the work is live, and until this record nothing in the system enforced it.
Two facts make this urgent rather than theoretical.
The system's own budget rewards silence. Emission is deviation from the substrate. A stale screen emits *less* than a live one, because withdrawn data tends toward nothing changing. A dead feed is the cheapest screen this system can render, and every check would call it exemplary.
Every r136-native component on the roster depends on the answer. live-feed, sla-countdown, timeline and presence are all components whose content is a claim about a moment. Deciding staleness per component is deciding it four more times with four chances to disagree — the mistake ADR-0046 avoided for the shell Scopes by stating its rule on the property rather than the component.
#Decision
A component that renders a claim about an external condition declares whether it can vouch for that claim. A component that cannot vouch may not render as though it can.
Three parts, and the second is the one that makes this different from every other design system's treatment of the same problem.
#1. Vouching is declared, not inferred
A component whose mark reports a condition the product observes — status-indicator, meter, queue-item, table-row, inline-loading, and the r136-native set below — declares vouches: true in the component tier. Components whose content is their own — button, tag, modal, the shell Scopes — declare vouches: false and are outside this record.
Declared rather than inferred, for ADR-0045's reason and checked the same way in both directions: a component declaring it must accept a freshness input, and a component accepting one must declare it. A treatment that appeared without a declaration and a declaration with no treatment are the same thing on disk.
An adverse variant is not the same as an unvouchable claim, and the roster proves it rather than the record asserting it. Eight components declare adverseVariants under ADR-0044, and they split cleanly in two. Four — status-indicator, meter, tag, inline-loading — name a condition in the world, which is knowable only by being told and therefore can go stale. Four — input-field, text-area, select, number-input — name invalid, which is a fact about what the operator just typed. The product knows that synchronously, from the same interaction that caused it; there is no source to lose contact with. The form controls declare vouches: false and this record does not touch them, which is the distinction that keeps vouches from collapsing into "has a bad state".
#2. The unvouched treatment is a retraction, not an escalation
This is the part every other system gets wrong, and the reason is that both obvious answers are wrong.
Louder is wrong. Staleness is usually mundane — a reconnect, a redeploy, three seconds of nothing. A system that escalated on every gap would manufacture urgency continuously, which §11 forbids in the same sentence it forbids competing urgency, and would teach the operator to ignore the one signal this record exists to create. ADR-0044 measured what happens when a channel is spent on the ordinary case: the sea of green stops being read. A sea of amber would stop being read faster.
Quieter is wrong, and is the bug. Quiet means fine. That is now a decided property of this system and it may not be overloaded.
So the treatment is neither. The mark stops asserting. The variant's shape is kept, because the reader must still know what kind of thing has gone quiet; the variant's colour is dropped, because colour is what carries the claim; and the mark resolves through a single emitter-unvouched role that is neither the ambient rung nor a status role. The component does not get louder or quieter. It visibly stops speaking, which is the honest rendering of a component that has nothing current to say.
A reader scanning a screen sees *shape without assertion* and reads it correctly on first encounter, without a legend, because a withdrawn claim looks like a withdrawn claim.
#3. An unvouched claim is pinned to Ambient, and the source takes the demand
A component that cannot vouch declares its own floor and no other, for the whole time it cannot. This is ADR-0046's rule arriving from the other direction: there, a surface that never leaves may not demand; here, a claim that cannot be supported may not spend the ration.
Amended by implementation. This clause said *"declares level 1 and no other"* until it was built. Seven of the eight vouching components can obey that.alertcannot: its legal levels are 2, 3 and 4, because an alert with nothing to say does not exist, so it has no Ambient form to withdraw to. The rule as written was unsatisfiable for one component in eight and nobody would have noticed until the eighth was wired. The half that is load-bearing survives unchanged, and it is the half worth stating: an unvouched claim may not spend the View's ration. No component's floor is Demanded, so pinning to the floor protects the cap exactly as pinning to Ambient would have, and it does so for a component that has no Ambient. Each component derives its withdrawn rung fromX_LEVELS[0]rather than spelling a number, so a component whose floor moves brings this with it.
The consequence matters more than the rule. When a source dies, its readings do not each start demanding — twelve stale readings competing for a cap of one is precisely the arbitration failure ADR-0010 exists to refuse, and it would fail the build. Instead:
The readings withdraw. The staleness takes the claim.
A staleness Emitter reports the *source* — "no contact with the seal press for 4m" — and it may reach Demanded, because that is one live condition, it is actionable, and it is true. The screen goes from twelve confident green marks to twelve withdrawn marks and one demand that names the actual problem. The demand count is 1, by construction, and it was 1 before the feed died. The cap is not strained by the honest rendering; it is satisfied by it.
That is the whole argument for building this on top of a demand cap rather than beside one. A system without ADR-0010 could not make this decision, because it would have no reason to prefer one true demand to twelve.
#The check
salience — vouched, in the budget engine, reading declarations and no pixels for ADR-0040's reason — the verdict may not move with the theme.
A scene fails when a component declares itself unvouched and either resolves a variant mark or declares a level above Ambient. And, two-sided per ADR-0041, it fails when a Scope contains unvouched components and no staleness Emitter naming the source: a screen that withdraws every claim and says nothing about why has replaced a lie with a silence, which is not an improvement.
#Rejected options
A timestamp beside each reading. This is what most monitoring products ship, and it fails for a measurable reason: it moves the work to the operator. Eighteen timestamps require eighteen subtractions against a clock, per scan, and the answer the operator needs — *can I trust this screen* — is not any one of them. It is also invisible in field-night, where the whole point is that fine detail is unavailable.
A global "last updated" in the shell. Correct and insufficient, and the shell may not carry it anyway: ADR-0046 pins shell chrome to Ambient, so a header could not demand when the feed died. It also answers at the wrong granularity — one source can die while five are healthy, and a single global figure reports the freshest or the stalest, both of which are wrong.
Fade the stale component out. Reduces emission, which is exactly backwards: this system prices deviation, so fading makes a screen that cannot be trusted *cheaper* than one that can. It is also the treatment for disabled, and a stale reading is not disabled — nothing about it is unavailable to the operator, and one of them may be the most important thing on the screen.
Let each component decide. The mistake ADR-0046 declined to make four times over. Freshness is a property of a claim, not of a component, and four components inventing four treatments would be four ways to look calm while lying.
#Consequences
A screen can now be wrong in a way the system detects. Before this record, the only screens that failed were loud ones. A screen that had stopped being told anything passed every check with the best emission numbers in the set. That inversion is closed.
emitter-unvouched is a new semantic role, and measuring it changed this record's own design. See *Measured* below: the role is bound to the same ramp step as emitter-ambient in all four themes, which was not the intent when this record was drafted and is better than the intent was.
Six r136-native components join the roster under this record, listed in ADR-0021 section F. The roster moves from 47 to 53 — 24 built, 29 to build. That figure is stated here, in ADR-0021, and in docs/STATUS.md, and it is the kind of counted claim ADR-0047 exists to keep honest.
A cost worth naming. Every component declaring vouches: true gains an input the product must supply, and a product that supplies it wrongly — hardcoding fresh, defaulting to fresh — gets the old behaviour back with a new false confidence. The system cannot check that; nothing in a design system can check what a product tells it. What it can do is make the default the safe one: freshness is not optional and has no default. A component that vouches and is given nothing does not render fresh. It renders withdrawn, and the screen says so.
#Measured
The role exists and Rule A rewrote its binding. This record was drafted assuming emitter-unvouched would take a step of its own — visible, neutral, distinct from resting. It cannot, and the reason is structural rather than a shortage: **every ramp resolves step *N* to one lightness across every ramp**, which is the property ADR-0043 discovered, so a level-1 mark placed on the step adjacent to ambient collides with all four level-2 roles at once. The first attempt did exactly that and Rule A reported four failures in interior-light — emitter-unvouched at neutral/3 against emitter-marked, status-positive, status-caution and status-critical, all at lightness 0.6195.
The steps that remain are a surface's, or they are quieter than resting — and quieter is the bug this record exists to close.
So the role binds to ambient's own step, and that is the right answer rather than the available one. A withdrawn claim may not encode what it *would* have said, because the system cannot support that either. A withdrawn critical and a withdrawn ok must therefore be indistinguishable, and resolving both to resting neutral is exactly what achieves it. Had a free step existed, taking it would have shipped a subtler version of the bug: a stale reading still whispering which way it had been leaning.
What separates unvouched from ambient is not colour but continuity — a broken perimeter against a whole one. That channel is available to every mark this system has, glyph or track: a status indicator's shape, a meter's fill, a table row's edge. It survives field-night, where one locked hue means geometry is all there is. And Rule B already checks exactly this shape of separation — a same-level pair sharing a lightness, separated by a non-hue declaration — so the mechanism the design needs was in the system before this record wanted it.
Measured at the commit that adds the role *(darwin-arm64)*:
- 16 semantic roles, up from 15, resolving in all four themes.
- Rule A: 84 cross-level pair-theme checks over 8 declared mark roles, up from 60 over 7. No two rungs share a lightness.
- Rule B: 37 same-level pairs, unchanged, every one separated by a non-hue declaration.
- 613 custom properties across 33 stylesheets, each declared by exactly one tier.
Rule A's unused-rung note reads 1 declared mark role referenced by no component — emitter-unvouched, and that is correct and expected at this commit. It is the note ADR-0043 added after an unused role went unchecked for the length of the project, and it clears when the first component consumes the role. The role is nonetheless *checked* while unused, which is precisely what ADR-0043 changed: Rule A builds its pair set from declared roles rather than from referenced ones, so this one was separated against 84 pairs before anything drew it.
#The treatment, and where clip-path moved it
8 components declare vouches: true — status-indicator, meter, queue-item, table-row, alert, tag, inline-loading, loading — and 16 declare false. The split is wider than the four with adverse variants, because a component can report an external condition without having an adverse variant to report it *with*: a queue-item whose queue has stopped moving is the case, and a loading block whose operation died is the classic one.
The retraction is drawn on the component's box, not on its mark, and that is this unit's finding rather than the record's intent. The drafted design dashed the mark's own perimeter. Two of this system's four mark shapes are cut with clip-path — attention's triangle and critical's octagon, at the vertices ADR-0028 fixed — and clip-path clips a border along with everything else, so a dashed mark would have rendered one way on a disc and another on an octagon. It would also have had nothing to dash on a meter's fill or a table row's edge, which are marks with no glyph at all.
Moving it to the block fixes all three at once and is better semantically: staleness is a property of the whole reading rather than of the shape drawn inside it. outline rather than border, because an outline takes no part in layout — a reading that withdraws must not move its neighbours.
So the two halves live in two files, and the check reads each where it actually is: the colour in the component source, since this roster selects every mark token in the inline style, and the continuity in the stylesheet, since a broken perimeter is a declaration rather than a value. A component that re-points its alias and draws no break fails; so does one that breaks its perimeter without re-pointing.
#Measured at the implementing commit *(darwin-arm64)*
- Rule A's unused-rung note reads 0 — 84 cross-level pair-theme checks over 8 declared mark roles, all 8 now referenced by the component tier. Making that true exposed a fourth instance of a check reading an input set narrower than its subject: Rule A built its reference set from the
marktable alone, and the unvouched token is emitted fromvouches, so the role read as drawn by nothing while eight components drew it. - 180 call sites gained the prop — 101 in the must-fail fixtures, 79 across the stories and the docs registry — plus 64 construction sites in the budget generators.
- Zero measured movement. 43 unthemed comparisons and 137 themed, every one identical to six decimals, zero first records. Zero elements render withdrawn in any of the 175 committed scenes: the capability exists and costs nothing until something uses it, which is what it should cost.
- 6 must-fail fixtures assert the requirement.
vouchedis required rather than optional, and an omitted one is a compile error rather than a silent default — the record's own reasoning, since an optional prop would have handed every forgetful call site exactly the confident mark it cannot support.
#The structural half, which the first implementation missed
The commit that drew the retraction changed what a withdrawn component *looks like* and not what it *declares*. An unvouched critical still rendered data-wr-level="4", so it still counted against the View's demand cap while showing a mark that said it could not support the claim. The paint was honest and the declaration was not, and the engine reads the declaration.
That is the defect this record exists to close, reproduced inside the record's own implementation one commit after it was written. It is worth leaving in the history rather than tidying away: the visible half is the easy half, and a system that checks only what it can see would have called that commit correct.
Fixed by pinning the declared rung, the level class and the geometry together — a withdrawn reading rendered at level-4 size while declaring its floor would have been the same inconsistency wearing different clothes.
#Measured at the pinning commit *(darwin-arm64)*
- 8 vouching components declare a withdrawn rung:
StatusIndicator=1, Alert=2, Meter=1, QueueItem=1, TableRow=1, Tag=1, InlineLoading=1, Loading=1. - Each rung is its own component's floor — 7 at Ambient and 1 above it — derived from
X_LEVELS[0]rather than spelled. - No withdrawn rung is Demanded, 8 checked against level 4. That is the assertion the record actually needs, and it is two-sided: a set that quietly emptied would satisfy "none of them demands" by having none of them, so the count is asserted first.
- Zero fixture files changed. The pinning is a no-op while everything vouches, which is what a capability should cost before anything uses it.
#The receipt
data-wr-vouched joins core's serialization surface, written by every vouching component in both states rather than only the withdrawn one — "absent" and "false" must not read alike, or a component that stopped emitting it would look vouched to every check, which is this record's own defect wearing the serialization surface's clothes. Core's two-sided attribute check refused the addition until a fixture wrote it, which is what that check is for.
Two scenes, and the pair is the argument.
**Scene 47 — a source dies, and the screen says so *(must pass)*. The first scene in this set that measures a screen which would be wrong by being calm**; every scene before it measures one wrong by being loud. Line 3 stops reporting, its six readings withdraw, one Alert names the source. The receipt reads:
View div#view-supervisor: 1 concurrent demand(s) / cap 1— the demand being#source-lost
The count is 1 before the line died and 1 after. That is the whole claim. ADR-0010's cap is not strained by the honest rendering; it is satisfied by it, and a system without that cap would have had no reason to prefer one true demand to six.
Two of the six withdrawn readings were reporting attention and critical when the line went quiet, and they are now indistinguishable from the four that were nominal. That is the hardest part of this record to accept and it is the correct behaviour: the system cannot support *"this was about to fail"* either.
**Scene 48 — a withdrawn claim still demanding *(must fail)*. Fails on salience — vouched and on nothing else**: the View holds exactly one demand, so salience — view passes, and three units on other lines are still reporting, so salience — unexplained is satisfied rather than dragged in. One scene, one rule — a must-fail scene that fails two rules cannot tell you which one has teeth.
One element in 48 is hand-written, and that is a finding rather than a shortcut. The React component cannot produce the state: vouched={false} pins the declared rung to the component's own floor, so a caller has no way to ask for a withdrawn demand. The illegal state is unrepresentable in the type and in the render. The markup is therefore written by hand, carrying only the two attributes the engine reads, to ask the one question the type system cannot answer — does the engine refuse it too. A rule enforced in one layer and untested in the other is a rule with one witness.
Measured *(darwin-arm64)*: 45 unthemed scenes and 140 themed, the five new ones recorded as first records and every one of the 43 and 137 pre-existing values carried through unchanged. Cascade audit 2,900 scene-state pairs across 180 scenes. Playbook §10 goes to 22 checks.
Still to build: staleness itself. Scene 47 uses an Alert to name the source, which is honest — an alert reports a condition and this is one — but the roster's own answer is a component whose subject is the source rather than the reading, and which is the one component in the system that cannot itself go stale, because its input is the local clock rather than the feed.
The figures available at the time of writing are the shape of the hole rather than its size. 24 components built. 8 declare an adverse variant under ADR-0044, splitting 4 conditions-in-the-world against 4 facts-about-typing. The exact set that will declare vouches: true is a decision the implementing unit makes and counts — it is wider than those 4, because a component can report an external condition without having an adverse variant to report it *with*, which is exactly the case of a queue-item whose queue has stopped moving.
That last case is the one to build first, because it is the one where the current system is most confidently wrong: a queue with nothing arriving and a queue that is empty are the same screen today.