Skip to contentWolf-Rayet

Decision records

ADR-0075 A container retracts its own claim, and a Scope's retraction has one half

Accepted2026-09-06Phase 4, reopened

#Context

ADR-0073 kept live-feed when it removed timeline beside it, on vouches — *"its own claim is that it is live, and if the source stops, a quiet period and a dead connection render identically inside it."* It named two questions it could not answer and left them for the build:

A Scope at level 1 is already at its floor, so ADR-0048's descent is a no-op and only the mark half of the retraction does work; and nothing in that record addresses whether a container's withdrawal says anything about its subtree.

This is the build. Both are answered, and it found a third the record had not asked.

#The component

Scope, [1], interactive: false, vouches: true, persists: true, two governed parts. The thirty-sixth component and the eighth Scope; the tenth of thirty-six that vouches and the fourth that persists.

Its copy obligation differs from region's, which ADR-0073 did not predict. That component states *how many are in it*, because a set whose size is not stated makes "0 of 0" and "0 of 18" the same screen (ADR-0058). A feed is open at the recent end and has no total to state, so what it owes instead is what span these arrived in — three events in a minute and three in a day are the two screens here, and a count alone makes them one. So D4 separates it from region as well as D6 does, and the row was kept on the narrower of the two grounds.

It is the first component to inherit ADR-0046 by declaring the property, which is what that record asked for when it stated its rule on persistence rather than on three names. Until ADR-0074 made persists an axis there was no way to say so: region, page-header and data-table declare the same [1] for §3's entirely different reason.

#The first question: the descent is a no-op, and that is the mechanism arriving rather than failing

For an Emitter a retraction has two halves — the mark re-points, and the declaration descends to the component's own floor — and ADR-0048's load-bearing half is the descent, because an unsupported claim may not spend the View's ration.

A Scope holds no ration. §3: it owns a budget and distributes it. So there is nothing for the descent to give back, and the floor is where the component already stands. The rule is *withdraw to your own floor* and this component obeys it by standing still.

That is visible in the frame and it is the opposite of every case before it: the withdrawn feed serializes the same data-wr-level="1" it declared, and the retraction lives entirely in the perimeter. Half of ADR-0048's mechanism is inert here by construction, and the remaining half is the whole of what a Scope's retraction can be.

#The second question: it retracts its own claim and not its entries

The tempting reading is that a container's withdrawal covers its subtree — if nobody is telling us anything, surely everything in here is suspect.

It is the wrong reading, and ADR-0048 is what refuses it. The entries in a feed are *arrivals*: each was true at the moment it arrived and stays true afterwards, exactly as a timeline's entries do — which is why ADR-0073 made that row region and this one a component. A container that retracted them would be withdrawing facts nothing has put in doubt, and that record exists to stop a claim asserting past its support, not to make supported claims stop asserting.

What withdraws is narrow: that this is what is arriving. When the channel dies, that is exactly the claim that stops being true, and nothing else on the screen changes.

The mechanism agrees without being asked, which is the part worth keeping: each child carries its own data-wr-vouched, the engine reads declarations rather than inheriting them, and a Scope's declaration is about a Scope. Scene 62 is that on a rendered frame — the feed at vouched="false" with a broken perimeter, and three entries inside it still at vouched="true".

It is stated as a constant rather than left in an absence. LIVE_FEED_WITHDRAWAL_COVERS_SUBTREE is false and the violation fixture asserts it, because a decision that lives in the absence of a CSS rule is a decision no check can see — ADR-0041's shape. The stylesheet says the same thing in a comment where the rule would have gone.

#The third thing, which the record had not asked: its subtree may not hold the demand

ADR-0053 tabulated shell-header against page-header: identical layer, identical declared rung, opposite answers on what the subtree may contain. The shell's 1 is a ceiling ADR-0046 imposes and its subtree may hold no demand; the page header's is a floor §3 leaves and its subtree may hold one.

A feed takes the shell's answer, and it is the first component that is not a shell to do so. The argument is ADR-0046's own, one level down from where that record made it: a persistent surface's slot is taken forever, so a demand inside a feed that never leaves would occupy the route's only rationed slot across every route the operator visits afterwards. That is the option ADR-0046 rejected, arriving through a container instead of through a badge.

And it is why a feed is not where alarms live. What arrives here is a report that something happened; a live condition is alert's and belongs to the route the operator is working in. ADR-0042 reached the same place for toast from the other direction — an event may not carry the demand rung — and this is that argument at the container.

Scene 62 is the composition: the demand is in the route's Region at level 4, and the feed beside it is calm at 0 of cap 1.

#The retraction costs no pixels, and that is a consequence of ADR-0013

Every vouching component before this one adds an outline to carry the break, because its mark is a glyph and two of this system's glyphs are cut with clip-path, which clips a border along with everything else.

A Scope has a real perimeter already. ADR-0013 requires a raised context to draw a full border; ADR-0048 requires a withdrawn claim to break its continuity. The two rules meet on one line, so the withdrawal is a change of border-style on a line that was already there.

That matters more here than it would anywhere else: this is the largest surface in the system that can withdraw, and an outline around a whole region would have been the loudest retraction in the set for the quietest kind of claim.

#Rejected options

Let the withdrawal reach the subtree — dim, grey or dash the entries. The intuitive design, and the one most systems would ship. Rejected because it retracts claims that are not in doubt: an arrival is a fact with a timestamp, and it does not become less true because the channel carrying later ones died. It would also make the feed the only place in this system where one component's declaration silently changed how another's rendered, which the whole layer model is arranged to prevent.

Give the withdrawn feed a rung of its own so the retraction has somewhere to descend to. It would have made ADR-0048's two halves both do work. Rejected because a Scope has no allocation to move — §3 — and inventing one so a mechanism could look symmetric is the tail wagging the dog. The asymmetry is information: it says this component never held a ration.

Take region's count instead of a window. Simpler, and it would have made the two components differ on one dimension instead of two. Rejected because a feed has no total and the count would have to be of what is *shown*, which is a fact about the viewport rather than about the subject — and "3 events" without a span makes a minute and a day the same screen.

Add a lastSeen or connected prop beside vouched. Products will want it. Rejected as two ways to say one thing: whether the channel is alive is vouched, and how long it has been dead is staleness's claim — an Emitter that may demand, which this container may not. ADR-0055 refuses two components saying one thing with two allocations, and this would have been one component doing it to itself.

#Consequences

Roster 49, built 35 → 36. Section F is complete: all four of its rows are built. Thirteen remain — §C form 6, §D navigation 3, §E surfaces 2, §G 2.

ADR-0053's table has a third shape in it, and the row that decides it is persists rather than a component name. A future Scope answers *may my subtree demand* by declaring whether it outlives the route.

An open question, named rather than owed. Subtree permissions are declared on the contract and demonstrated in a scene; no check enforces them, because the engine reads a frame and has no way to know which component a Scope is. Making may hold a demand machine-enforced would need the frame to carry it, which is a change to the serialization surface and its own record. page-header has had the same gap since ADR-0053 and this is the second component to have it — worth saying out loud rather than leaving for a third.

A scene, four receipts and two baselines. Scene 62 and its three themed siblings on darwin-arm64; linux-x64 is owed and standing item 12 opens with this commit.

#Measured

  • COMPONENT_LAYERS — 36 components, 8 Scopes, LiveFeed the eighth *(disk, this pass)*.
  • component.config.json — 36 entries; 10 vouch, 4 persist. The ten $interactiveNote entries counting non-interactive components moved twenty-five → twenty-six.
  • tokens:verify — live-feed: 15 tokens, 4 themes / 2 densities; 8 non-text APCA checks, worst arriving/1 on surface-raised in field-night at |Lc| 20.00 against a floor of 15. Tier totals 782 tokens, 2,196 checks. VERIFY OK.
  • react:test — the vouching set at 10, LiveFeed=1, derived from the tier.
  • Scene 62 — #scope-alarms 1 demand of cap 1 at #alarm-press L4; #scope-feed 0 of cap 1, calm, all three entries at L1. The feed serializes level="1" while vouched="false"; every entry serializes vouched="true". Reproducibility exact over 2 renders.
  • Themed siblings — field-day 0.06482 / 0.14320, interior-dark 0.08145 / 0.15292, interior-light 0.06714 / 0.15134.
  • pnpm battery — the verdict this pass is measured by.