1# 1. HTMX 4 owns the discrete state23- **Date:** 2026-08-024- **Status:** accepted5- **Where it is written down:** issue #5 §1, §4, §10 decision 2; [app.md](../app.md)67## Context89The reference implementation is a client application: hash routing, discrete10state held in browser JavaScript, and the display logic that decides what a11legend shows — legend algebra, AND-across/OR-within filtering, label ladders,12reading the semantic conventions — living in the frontend beside the code that13draws pixels. Every one of those decisions had to be re-derived on the client14because the server had never made it.1516## Decision1718The application is server-driven hypermedia over HTMX 4.0, and the state19placement rule is the axis everything else hangs on: **discrete application20state lives on the server and in URLs; continuous interaction state lives in21the seam.** One per-volume session record holds volume/world/lens, hidden22collections, label overrides, search, dock, selection, grid. Real URLs replace23hash routing. Every interaction that changes discrete state is a `POST24/session/{concern}` answering with the partial set for exactly the regions that25concern touches.2627Four usage rules make it stay honest: morph swaps so scroll, focus and open28`<details>` survive a re-render; the viewport morph-skipped; explicit29`:inherited` rather than a spooky cascade; and no `hx-on` logic in templates —30the glue is one after-swap rescan hook in the seam's boot module.3132Two clauses bound the commitment. The **pragmatism clause**: an interaction33that proves laggy as a round trip is re-classified in the issue's interaction34inventory, never patched with ad-hoc client code. And **vocabulary35containment**: `hx-*` attributes live in templates only, so the published36contracts — routes, region names, the scene description, the diagnostics37protocol — stay framework-neutral.3839## Consequences4041- All display logic runs once, in Go, through `format/semconv`. Templates42 render; they do not decide.43- A world can be bookmarked, reloaded and linked to. A `GET` of an explorer44 page writes the session, so the session follows the address bar rather than45 the other way round.46- The concern table (app.md §4.3) becomes a real artifact: each concern names47 the regions it touches, and a partial set that under-covers an interaction is48 a bug with a name.49- Replacing HTMX later is a template concern, not an architecture event.50- The seam gets smaller than the frontend it replaces, because most of what the51 frontend did was decide.