Skip to main content

max / makenotwork

Record the hyperscript refusal in the design-system charter Nothing in the tree uses _hyperscript, so this closes the question rather than reversing a choice. Written down because the next reader who notices MNW is an htmx site will have the idea again, and the reason it is refused is not obvious from the outside: behaviour in markup is behaviour no description can see, which is the same test that refused Node::Html. Also states the two idioms that do carry behaviour here, since the refusal only makes sense against them.
Co-Authored-By
Claude Opus 5 (1M context) <noreply@anthropic.com>
Author: Max Johnson <me@maxj.phd> · 2026-08-10 14:10 UTC
Signed with PGP, not checked
Commit: 0921b6224551dbb7fdaafb4724c294335bed1f21
Parent: 264b9bb
1 file changed, +25 insertions, -0 deletions
@@ -197,6 +197,31 @@
197 197 14. **Button class is `.btn-primary` / `.btn-secondary` / `.btn-danger`.** Works on both `<button>` and `<a>` (the `<a><button>` antipattern is banned. Use `<a class="btn-primary">…</a>`). The bare `button.primary` shorthand has been retired.
198 198 15. **Class names use kebab-case only.** No BEM `__` separator (retired 2026-05-20, was 112 sites across 20 prefixes, now flattened to single-dash). Modifier `--` (e.g. `.card--bordered`) is still allowed.
199 199
200 + ## Interaction idioms, and the one that is refused
201 +
202 + Two idioms carry every behaviour on this site. htmx moves markup over the wire. The
203 + delegated dispatcher in `frontend/src/core/dispatch.ts` names behaviour with `data-action`
204 + and friends, resolved against a typed registry. Both are installed once, at the document
205 + level, and neither puts logic in an attribute value.
206 +
207 + **`_hyperscript` is declined, permanently.** It appears in zero files today, so this
208 + records a closed question rather than a reversal. Four reasons, heaviest first:
209 +
210 + 1. **It fails the renderer-honesty test that refused `Node::Html`.** Hyperscript is
211 + behaviour written into markup: behaviour no description can see, and that no TUI or
212 + egui renderer could ever honour. The description layer exists so a behaviour is named
213 + once and emitted per host. An idiom that only one host can read defeats it.
214 + 2. **It would be a third interaction idiom** beside the two above, in a codebase that is
215 + converging on one.
216 + 3. **It reverses the CSP posture.** `script-src 'self'` with no `unsafe-inline` was earned
217 + by moving every inline `on*` and `hx-on::` handler out to delegated listeners
218 + (`src/lib.rs:765`). Logic in attributes undoes that even where `_hyperscript` parses
219 + without `eval`.
220 + 4. **Nothing needs it.** The ground it would cover is the dispatcher's, which quasi's own
221 + stack table credits as "htmx 2 + GO's delegated dispatcher, proven on MNW".
222 +
223 + Decided 2026-08-09. Wiki note `look-wave-2`, decision 6.
224 +
200 225 ## How to extend
201 226
202 227 When a screen genuinely needs something not in this charter: