Skip to contentWolf-Rayet

Decision records

ADR-0053 A route's header may hold what the shell's may not

Accepted2026-09-05Phase 4, reopened

#Context

ADR-0040 refuses a demand that is present in the markup and absent from the frame: *a screen may not become compliant by closing a panel over its second alarm.* Scene 41 is the must-fail case and salience — hidden is the check.

Its remedy names a component this system did not have. The record's own words:

Lift the demand to something on the screen — a disclosure header carries a summary for exactly this — or leave the panel open.

There was no such header on the roster. shell-header is the only header in the set and ADR-0046 forbids it a demand, so the sentence resolved to *leave the panel open*, which is the option the operator has already declined by collapsing it. A rule whose remedy names nothing the system ships is a rule the reader cannot follow, and the check that enforces it becomes a check people work around.

There is a second gap and it is the same gap read from the other side. ADR-0046 states its rule on a property rather than on a list:

a component that remains rendered across a change of route declares level 1 and no other, and may not hold a demand

That was deliberate — it is why shell-left-panel and shell-right-panel inherited the rule by being persistent rather than by being named. A rule stated that way has a complement, and nothing had ever stood in it. Every Scope in the set either persists across routes, in which case ADR-0046 governs it, or disappears with the element that summoned it — modal, data-table. None of them is a Scope that belongs to one route and is present for the whole of it.

#Decision

page-header is a Scope that belongs to one route, and its subtree may hold the View's demand.

#The claim is about the subtree, never about the declaration

The header's own chrome declares Ambient, and it could declare nothing else. §3: a Scope *owns a budget and distributes it* — it holds no allocation of its own, so there is no rung for it to raise. That is the same number the shell Scopes declare and it is reached from the opposite direction, which is the thing about this component most likely to be misread:

shell-headerpage-header
LayerScopeScope
Declared rung11
Why that runga ceiling — ADR-0046 forbids a persistent surface anything loudera floor — §3 leaves a Scope no allocation to raise
Subtree may hold a demandno (ADR-0046)yes
Stackingraisedbase

The last two rows are the whole component. The first three are why it needs a record rather than a row: two components with identical declarations that differ in what they may contain is exactly the shape a reader resolves wrongly by reading the declarations.

PAGE_HEADER_MAY_HOLD_A_DEMAND is published on the contract and asserted in test/page-header-violations.tsx, and scene 51 is where the engine sees it on a rendered frame.

#Two regions, because they are two places and not a rank

The header has a summary and a bar, and they are named rather than being one row with an order. A Scope gives its children somewhere to be (§3); a component that put a lifted demand beside a control set in one undifferentiated row would be *ranking* them, and ranking is what an Arbiter does. Two regions is the Scope saying *these are different places* without saying which is more important.

#The summary draws nothing, and that is the load-bearing rule

No ground, no perimeter, no ink of its own — layout and nothing else.

What is lifted into it arrives with its own allocation, up to and including the View's single demand. A container that painted around it would be spending emission on a child's behalf while that child's emission is the thing being rationed. It is the same laundering shape ADR-0009 refuses at the content boundary, arriving one layer up and in the opposite direction: there a region tried to make its pixels somebody else's, here a container would add pixels to somebody else's claim.

It is also why the region is not rendered at all when nothing has been lifted, rather than rendered empty. A reserved space for a demand that has not happened makes the calm screen pay for the loud one, and this budget is computed over the frame.

#base, not raised

ADR-0013 makes raised a *bounded* context — a full perimeter border. A shell header earns it because content begins below it: it is the thing the route is measured against. A page header is not measured against its route; it is the top of it. A complete perimeter here would put a box inside a box and leave the reader deciding which of two edges meant something. So it draws one rule on its trailing edge, grounds on the theme substrate, and adds no ground of its own.

#Scene 51, and its pair ten scenes earlier

51-page-header-lifted-demand passes with one demand against a cap of one. It is 41-accordion-hidden-demand's legal counterpart and the two are the record: same live condition, same collapsed section, same readings inside it. The only difference is where the demand is.

The collapsed section's children are at Marked and no higher, and that is what the scene turns on. A closed region's detail is detail — the reader said they did not need it on screen — and the system's answer to a condition inside one is not to shout through the panel. If any of them were at Demanded this scene would *be* 41.

No new must-fail scene is written, and that is not an omission. 41 is the must-fail scene for this rule and it is committed; a second one would fail the same check for the same reason, and what was missing was never a way to break the rule but a way to keep it.

One finding arrived from a check while the scene was being written, and then arrived a second time from this record. The first draft's readings carried a temperature with a degree sign — U+00B0 — and tokens:verify refused the scene: that codepoint is outside ADR-0035's shipped subset, so none of the four faces can render it. The copy became Head 2 at 214, ceiling 188, a reading beside the number it is measured against, which is better copy than a reading beside a unit.

Then this paragraph was written with the character in it, and the same check refused *the record*. Both refusals are correct and the second is the more interesting one: the subset scan reads what the repository's content renders, and a record that shows a codepoint is content that renders it. The alternative in both cases was to add one codepoint to the subset for one string, which is precisely the unconsidered expansion ADR-0035 exists to prevent — so the character is named here and not shown.

#Rejected options

Let the shell header carry the lift. The cheapest option and the one ADR-0046 refuses in terms. A persistent surface holding a demand occupies the View's only slot for as long as it is rendered, which is the same failure ADR-0050 found in acknowledgement arriving from a different direction; and at a route transition the identical rendered element would change which cap it counted against without re-rendering.

Make the summary a string the header draws. Then a page header would hold an allocation, which §3 says a Scope cannot do, and the lifted demand would stop being the child's claim and become the container's. It would also make the lift a *different* assertion from the one it replaced: what ADR-0040 asks for is that the demand be on the screen, not that a summary of it be.

Give the summary a ground or a border so a reader can find it. Refused above. The demand is already the loudest thing in its Scope by construction — that is what level 4 means — and a container that added emission around it would be paying for legibility the ladder already bought.

Build it as an Arbiter. Tempting, because the header does end up with a demand in it and an Arbiter is the layer that resolves competition. It fails §3's authority question: an Arbiter *ranks* what it holds, and this header ranks nothing — the summary and the bar are two places and the demand's precedence comes from its own rung, not from where it was put. A header that ranked its regions would make the same claim twice, once in the ladder and once in the layout, and the two could disagree.

No record — just a roster row. The precedent exists: a component pass has shipped with zero ADRs when no new rule was needed, and that was correctly reported as the finding. It does not apply here. Two components with identical declared layer, identical rung and nearly identical parts, differing only in what their subtrees may contain, is a distinction that lives nowhere a reader looks unless a record says so.

#Consequences

ADR-0046's complement is occupied for the first time. That record's rule stays exactly as written; what changes is that the set now contains something it does not reach, which is what a rule stated on a property is supposed to allow.

ADR-0040's remedy names a component that exists. The sentence *"a disclosure header carries a summary for exactly this"* was written eleven records before the header did, and scene 51 is the first time it can be followed.

Nothing in the engine changes. No new check, no new attribute, no new failure. The rule this record adds is a type and a contract, and the thing that verifies it on a rendered frame is salience — view counting to one — which it already did.

#Measured

  • The twenty-sixth component and the sixth Scope. Roster 26 built of 57.
  • 14 component tier tokens, every alias resolving in 4 themes and 2 densities; 8 non-text APCA checks, all met, worst |Lc| 20.00 against a floor of 15 in field-night.
  • Scene 51: 1 demand against a cap of 1, 0 hidden, four Scopes measured, every one under the field-night ceiling of 0.128641. Engine roster 47 → 48 unthemed.
  • Cascade audit 2923 → 2948 scene-state pairs across 182 → 183 scenes, every declared state carried by the frame.
  • Eight registries at 26 of 26; 149 identity positions across 26 components; 5 counted claims matching the set, one of which — *"one of the seventeen that do not"* — was moved by this component arriving.