docs(rules): document the token-gap marker

Companion to da790de. The previous wording said 'report the gap and
stop', which agents read as 'report the gap and substitute'. Name the
near-miss substitution explicitly and point at the marker instead.
This commit is contained in:
Marcos Paulo
2026-09-05 07:17:37 +00:00
parent da790de20d
commit 723abeafb5
2 changed files with 31 additions and 11 deletions
+5 -3
View File
@@ -28,9 +28,11 @@ You may not edit `tokens.css`, `verify.mjs`, `astro.config.mjs`, or
- No raw hex, no px font sizes, no ad-hoc breakpoints. Tokens only. - No raw hex, no px font sizes, no ad-hoc breakpoints. Tokens only.
- **Never reshape CSS to slip past `check-tokens.mjs`** — e.g. the `font:` - **Never reshape CSS to slip past `check-tokens.mjs`** — e.g. the `font:`
shorthand to hide a px size it would catch as `font-size:`. If the token you shorthand to hide a px size it would catch as `font-size:` — and never point a
need does not exist, report the gap and stop; you may not add it yourself. See legacy value at the nearest token that happens to exist. Both are silent
`.agents/rules/gates.md`. redesigns. Keep the true value and mark it
`/* token-gap: <reason>; owner design-system-keeper */`, which waives the
finding and queues it. You may not add tokens. See `.agents/rules/gates.md`.
- No `client:*` unless genuinely interactive, with written justification. - No `client:*` unless genuinely interactive, with written justification.
- Every ARIA attribute from the markup you replace survives. `verify.mjs` - Every ARIA attribute from the markup you replace survives. `verify.mjs`
asserts several by name. asserts several by name.
+26 -8
View File
@@ -66,16 +66,34 @@ worse than failing, because failure is visible and this is not.
`font:` shorthand passes it. Task 07 did exactly that, in **two** components, `font:` shorthand passes it. Task 07 did exactly that, in **two** components,
with a comment saying so. Both hardcoded values survived into a "green" branch. with a comment saying so. Both hardcoded values survived into a "green" branch.
When a token you need does not exist: ### Do not substitute a near-miss token either
1. Stop. Do not invent a value, and do not reshape the syntax to hide one. The second way to break this is subtler, and both tasks 10 and 11 did it: keep
2. Write the gap in your task report: the selector, the legacy value(s) it comes the gate happy by pointing a legacy value at the closest token that already
from, and which file owns the token. exists. `#e5eeeb` became `var(--paper)`. Diff-**added** green became
3. If your task cannot proceed without it, say so and stop. A blocked task is a `var(--accent)` — purple. `12px` and `14px` both became `var(--step-1)`, 15px.
finding. A silently-passing one is a defect that ships.
`tokens.css` has a single owner (`design-system-keeper`) precisely so that "add That is a silent redesign, and it is _worse_ than leaving the raw value in,
a token" is a decision, not a side effect. because a raw hex is at least honest about being unresolved.
### What to do instead: mark the gap
`tokens.css` has one owner (`design-system-keeper`) so that "add a token" is a
decision, not a side effect. You may not add one. You **can** keep the true
value and stay green — mark it:
```css
/* token-gap: no --step-* covers 12px; owner design-system-keeper */
font-size: 12px;
```
The marker waives that one finding. It needs a real reason after the colon; a
bare `token-gap:` is rejected. Every marked value is listed on each run, so the
debt stays visible rather than disappearing.
Write it in your task report as well: selector, legacy value, owning file.
Marking a gap is not resolving it — it keeps the site truthful until whoever
owns the token layer decides.
## Parallelism ## Parallelism