ADR-0011 Emission ceiling: value and shape
#Context
ADR-004 fixed the emission formula and deliberately left the ceiling open, at a provisional 0.200, because "a ceiling calibrated against fixtures whose brightness nothing has yet disciplined would encode the fixtures rather than the system." The ramps now discipline it. Two questions were left: what the number is, and whether it is one number or one per theme.
The derivation is spec §9, run against the four Phase 0 scenes composed on generated semantic tokens, one variant per theme — sixteen renders. The rule is measured rather than chosen: the calm scene sets the baseline, and the ceiling is that baseline plus the cost of one level-4 demand, taken from the escalation fixture rather than guessed, with a 1.35 safety factor so a component a few pixels larger than the fixture's still fits.
ceiling = worst(01-calm) + (worst(02-one-demand) − worst(01-calm)) × 1.35
| Theme | calm | +1 demand | demand cost | ceiling |
|---|---|---|---|---|
interior-light | 0.05425 | 0.09454 | 0.04030 | 0.10865 |
interior-dark | 0.06543 | 0.10990 | 0.04447 | 0.12547 |
field-day | 0.07886 | 0.10962 | 0.03076 | 0.12039 |
field-night | 0.05829 | 0.09305 | 0.03476 | 0.10522 |
field-night comes out lowest, which spec §9 step 5 requires of a correct configuration rather than hopes for. It did not on the first run: interior-light was lower, because its rows resolved to L 0.952 against a 0.950 page — invisible, and therefore nearly free. That was a design fault the derivation exposed, and correcting it moved the ordering. Worth recording that the check earned its place on its first use.
#Decision
One ceiling per theme, at the values in the table above. The provisional 0.200 is retired.
The spread is 1.19× between the highest and lowest theme, and it is not noise: it is the environments differing in what they can afford. field-day must shout to be legible in sun and is charged for it; field-night must not, and is held to the tightest budget in the system. A ceiling that could not express that difference would be measuring the same design against four different environments and calling the result one number.
The ceiling is a property of the theme, alongside the substrate and the ramps, and moves with them. Regenerating the ramps re-derives it, and the receipt records both.
#Rejected options
Keep the provisional 0.200. No work, and every fixture passes. Rejected on measurement: it sits 44% to 90% above the derived ceilings, so nothing in the system could reach it without first failing salience. A gate nothing can trip is not a gate, and shipping one would make the emission check decorative while looking rigorous — the precise failure the receipts exist to prevent.
A single ceiling for all four themes. One number to state, one to remember, and the theme-completeness check stays a pure token diff. It would have to be the highest theme's, 0.12547, since a lower one fails interior-dark on a legitimate render.
This is the closest of the alternatives, and it got closer during implementation. On the first derivation the spread was 1.32× and a single ceiling was more than 25% loose for two themes, which looked decisive. Correcting field-day's chrome (see Consequences) dropped the spread to 1.19×, and at that spread no theme is more than 25% loose. The quantitative case for per-theme is therefore weaker than it first appeared, and the decision rests on the structural argument rather than the numbers.
That argument: the ceiling is derived from the ramps, so it is a property of the theme in the same way the substrate and the headroom are, and it moves when they move. A single ceiling would have to be re-justified by hand every time any one theme's ramps changed, and it would hand field-night 19% more budget than its own render says it needs — in the theme whose entire purpose is the tightest budget in the system. A number that is correct for interior-dark and inherited by the other three by accident is a number nobody can defend per theme, which is where it will be argued about.
Derive from the calm scene alone, with a fixed percentage margin. Simpler, and independent of the escalation fixture. Rejected because the margin is the whole question. A percentage is a guess about what a demand costs; the escalation render is a measurement of it, and the two differ per theme — 0.03004 in field-day against 0.04447 in interior-dark. A fixed percentage would have understated the margin in the theme with the most headroom and overstated it in the one with least.
Set the ceiling above 03-violations so it keeps failing on salience alone. Preserves a Phase 0 property: that scene failed on salience only, which was the evidence the two checks are separable. Rejected because that evidence was a property of a ceiling *chosen* to sit above it. 03-violations carries several concurrent demands; a ceiling sized to admit one and still passing a scene carrying several would admit exactly what the system exists to prevent. Under the derived ceilings it now exceeds emission by 37% to 46% as well as failing salience, and that is the ceiling working. Separability is still demonstrated — by 02-one-demand, which passes both, and by the Phase 0 fixtures, which are unchanged.
Per-Scope ceilings rather than per-theme. The finest grain, and arguably the honest one: a sidebar and a main panel do not have the same right to emit. Rejected as premature, not wrong. Four scenes cannot derive per-Scope budgets without encoding these four layouts, which is the fault ADR-004 named. Scope-level budgets are a composition concern and belong to Phase 3, where computed-tier tokens let a Scope declare its own ceiling against the theme's as a maximum.
#Consequences
EMISSION_CEILING in the budget engine's config becomes a per-theme lookup, and a scene must declare which theme it is rendering so the engine knows which ceiling applies. That declaration does not exist yet: the Phase 0 fixtures are hard-coded and themeless, and they remain gated at the provisional 0.200 as an explicitly legacy path until they are retired, so baseline.json and ADR-004's cross-platform evidence stay valid.
The themed variants of 03-violations now fail on two checks rather than one. Their receipts should say so, and the docs site should publish both, because a must-fail scene failing for two independent reasons is stronger evidence than one failing for a single reason.
Ceiling derivation joins the generated artefacts: receipts/ceiling-derivation.json is committed and republished whenever the ramps move, and a ceiling that drifts without a config change is a build failure on the same terms as a drifted token file.
field-day moved during implementation. Wiring the per-theme ceiling in surfaced that field-day failed the substrate-floor check on every Scope: its card surface sat 0.0511 from its page, against 0.031–0.044 in every other theme, and the tolerance is 0.05. The check found a design inconsistency rather than a numerical one — field-day is the theme whose premise is that chrome should read as one uniform bright field and contrast should be spent on marks, and its chrome was the furthest from its page of any theme. Raising its L_max from 0.94 to 0.96 closed the gap, and its calm load fell from 0.09878 to 0.07886 as a result. The ceiling table above is post-correction. This is the second design fault the derivation has caught, after interior-light's invisible rows.
A limitation this exposed, not closed here. The substrate-floor check cannot presently tell a legitimate raised surface from a dishonest substrate declaration: it compares the declared substrate against the modal lightness of the Scope's governed pixels, and a Scope with its own card surface will always differ from the page by roughly the elevation step. Every theme now sits at 0.031–0.045 against a 0.05 tolerance, which is not much room. The real fix is for a Scope to declare the ground it actually sits on, which is a layer-model change and belongs with the composition work in Phase 3. Recorded here so the next person to trip it finds this note rather than rediscovering it.
The 1.35 safety factor is the one judgement in the derivation that is not measured. It is named in the tool, in the receipt and here, so that a later argument about it is an argument about a visible number rather than an archaeology exercise.