ADR-0127 A loop is granted off the ladder, and floored rather than capped
Amends playbook §2 and §5. Answers the question ADR-0107 reserved and ADR-0125 deferred.
#Context
ADR-0107 removed sustained motion from the system and was right to. Four components animated an edge on an infinite loop for as long as a condition lasted, and the argument against it is the system's own: a thing that never stops moving is not a signal, it is a condition of the room. Someone working a shift beside a pulsing alert stops seeing it within minutes while it goes on costing them for hours. A demand still breathing twenty minutes later has become furniture, and the ladder has no rung above level 4 to escalate to.
That record left one door open and named it: a future record wanting a bounded sustained behaviour would have to rebuild the machinery to say so.
ADR-0125 walked into the doorway. Reading the shipped stylesheets found three loops alive in the grouped set: the spinner, the skeleton shimmer, the indeterminate progress bar. They were not a contradiction of ADR-0107, they were outside the roster its test walked. That record put them on a period scale and gave them reduced-motion handling, and deliberately stopped there: it made a loop's values sayable and said nothing about whether a loop may exist.
So the system currently ships three loops that no grant covers. They are checked for rate and for collapse by a rule with no grant behind it, which is a floor with nothing to stand on.
The question is not whether ADR-0107 was wrong. It was right about the case it examined and its reasoning does not reach this one. What it removed was motion bounded by a condition a person must clear. A spinner is bounded by an operation the system is running. The first kind ends when someone acts, and if nobody acts it never ends. The second ends when the work ends, whether anyone looks or not.
§2's level-4 row already names the distinction and then does not use it: *the only level permitted sustained motion, and only while the demand is live*. The word carrying the rule is demand. A spinner makes none.
#Decision
A loop is granted, and the grant is not a rung.
operative joins the motion classes, outside the ladder. It has no level, because a loop that reports the system working makes no bid for attention, and a thing that makes no bid has nothing to ration. The ladder is the wrong instrument rather than a rung short: granting a spinner level 4 would ration it one per Scope, and a table with three loading rows would be a build failure.
It is floored, not capped. This is the substantive half. A transition is capped above, because the hazard is that it lasts too long. A loop is floored below, because the hazard is rate: peripheral vision is built to catch fast repetition, and a slow shimmer is calm where a strobe is not. A ceiling on a thing with no end is a number that reads as rigour and measures nothing.
The floor is a step on the period scale ADR-0125 added: 800ms, step 0. The permitted easings are linear and standard. The arrival curves mean nothing on a repeat, and a loop that accelerates and decelerates each cycle asks to be watched, which is the one thing an operative loop must not do.
The collapse is a second floor rather than a resolution. Under prefers-reduced-motion a loop stops, or repeats no faster than 3075ms, step 4. Both are honoured and neither is optional. A generator error refuses a reduced floor below the nominal one, because reduced motion slows a loop or stops it and never speeds one up.
boundedBy: 'operation-live' is on the grant, and it is the property ADR-0107 was actually about. It is checked at the token source rather than left as prose: a grant that arrives bounded by anything else fails the build, and a bound of demand-live is the furniture that record removed.
The boundary is the other half of the grant. A component holding a token record still may not loop, which is ADR-0107 unchanged, now enforced structurally by ADR-0125's third rule rather than by a roster of 37 names. The operative grant is what everything outside the attention model takes instead. The two rules are one sentence read from either end: being inside the budget costs you the right to loop, and being outside it costs you the right to bid.
#Consequences
The three channels now each have a grant and a reader. Light is measured in rendered pixels, language is scanned in shipped strings, and motion is read in the shipped cascade against grants that cover every kind of motion the package contains rather than every kind the ladder anticipated.
react:cascade grows from four checks to six. A loop is now measured rather than counted: it names a step at or above the floor, takes an easing the grant permits, and stops or slows past the reduced floor. All three shipped loops pass as they stand, which is the outcome to be suspicious of, so the numbers are printed by the suite rather than written here.
No token value moves and no fixture moves. The operative grant adds two custom properties, --wr-motion-operative-min-period at :root and its reduced value inside the existing media query, so the collapse sits in the cascade exactly where the level caps' does and a stylesheet reads one name without knowing the rule exists. measure.js screenshots with animations: 'disabled', so no settled capture can see a period.
core carries the grant for ADR-0107's reason: that record kept sustained in MOTION_GRANTS so the rule stayed statable rather than merely unused. OPERATIVE_GRANT is transcribed and checked against the receipt the same way, and two assertions hold the halves apart: the operative grant borrows no ladder class and no level, and no ladder grant names an operative class.
#Rejected
Leave the loops ungranted, as ADR-0125 left them. Defensible for one record and not for two. A rate floor and a collapse rule were already being enforced against three loops with nothing behind them, which is a check that has decided an answer without writing it down. The choice was to write the grant or to delete the loops, and a spinner that does not spin is a broken affordance rather than a stricter system.
Give operative motion a rung of its own, a level 5 or a level 0.5. It would make the ladder carry two different questions. Every rung answers how loud a thing is allowed to be, and the answer for a loop is that it is not bidding at all. A sixth rung would also break the claim §2 rests on, that a component's visual, verbal and kinetic weight cannot drift apart, because there is no colour and no wording at level 5.
Cap the period instead of flooring it, so every grant has the same shape. Uniformity bought at the price of measuring the wrong end. The cap would pass all three current loops and constrain nothing that matters.
Ration loops per Scope, as level 4 is rationed. The obvious symmetry, and it fails on the real case: a skeleton grid shimmers forty rows at once and reads as one texture rather than forty bids. A ration on a thing that composes into a single perceived surface would forbid the layout the component exists for.
Let a component holding a token record take the operative grant too. It reopens ADR-0107 through a side door. A component inside the budget has a level, and a level is a bid; the question of whether it is bidding has already been answered for it. Nothing in the twenty has asked, and if one ever does, that is its own record.