oficina / home Public

Frontend: the right rule had a reason that stopped being true

This file said to write class="rst-*" because "the shipped ui/tokens.css
has zero bare rst-* attribute selectors against ~528 .rst- class selector
occurrences". At v0.22.0 — the version go.mod pins — tokens.css contains
130 distinct bare rst-* attributes, each paired with its class twin.

The rule is still right. Its stated reason is not, and a false reason in
a binding file is worse than no reason: it is the thing the next person
checks, finds wrong, and uses to overturn a rule that was correct.

tokens.css states the real position in its own header, and it is more
interesting than either spelling winning: "TWO SPELLINGS, ON PURPOSE,
FOR ONE RELEASE. Every component rule below names its class and its
attribute twin ... The attribute spelling is the vocabulary this library
is moving to (design spec §6-v3); the class spelling is what every app
and every shipped partial writes today." Both ship, paired, so the move
is non-breaking in both directions.

So: write classes because that is what the shipped partials we render
alongside write, not because the attribute grammar is unreleased. It is
released.

This is a different failure class from the three retractions earlier on
this branch, and worth naming. Those were the file lagging the spec. This
is a claim about a DEPENDENCY that rotted when the dependency was bumped
— commit 0d0262a moved the pin to v0.22.0 without re-checking the
sentences that cited the old one. The note now says to re-check on every
pin move. The design spec's §11 carries the same stale claim and the same
"verified at origin/main, 2026-08-30" dating; that file has uncommitted
changes in the main checkout and is not mine to edit, so it is filed as a
task instead.

Docs only. All four .amadan/ci.d gates green.

🤖 Generated with Claude Opus 5, at the direction of Paul Campbell.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SfmrCe9McDH9dnqkuEMrjF
Paul Campbell pushed by paul@keymail.dev 4d054bd6918dc98b20ab7f7aacd6f4057fdbdd97 parent ea72533
1 file changed, +13 −5
  • AGENTS.md +13 −5
diff --git a/AGENTS.md b/AGENTS.md
index 8325786..fa21a69 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -161,11 +161,19 @@ quietly ignored).
cannot grep.
**Frontend**
-- Write `class="rst-*"`. The bare-attribute grammar is ruled but not
- released — the shipped `ui/tokens.css` has zero **bare `rst-*`** attribute
- selectors against ~528 `.rst-` class selector occurrences. (It does carry
- `[data-tone=]`, `[aria-*]` and `[type=]`; "zero attribute selectors" would
- not survive being checked.)
+- Write `class="rst-*"` — but **not for the reason this file used to
+ give**. The claim was that the shipped `ui/tokens.css` has zero bare
+ `rst-*` attribute selectors. At v0.22.0, the version `go.mod` pins, it has
+ **130 distinct ones**, deliberately. tokens.css says why in its own header:
+ "TWO SPELLINGS, ON PURPOSE, FOR ONE RELEASE. Every component rule below
+ names its class and its attribute twin: `.rst-btn, [rst-btn]` … The
+ attribute spelling is the vocabulary this library is moving to (design spec
+ §6-v3); the class spelling is what every app and every shipped partial
+ writes today." So the rule stands and the justification does not: write
+ classes because that is what the partials we render alongside write, not
+ because the attribute grammar is unreleased. **Re-check this when the pin
+ moves** — it is a claim about a dependency, and bumping the dependency is
+ what falsified the last one.
- **Re-copy `static/tokens.css` on every rastrillo upgrade.** It is frozen
at scaffold time while partials upgrade with the module. Adopt
`rastrillo doctor` the day it lands and delete this step.