clone

an offline map explorer where each world, from a game map to a city's open data, ships as one .atlas file

main
atlas / docs / decisions / 0013-assets-and-static-are-two-mounts.md
0013-assets-and-static-are-two-mounts.md 2.0K rendered
1# 13. `/assets` and `/static` are two different mounts23- **Date:** 2026-08-024- **Status:** accepted5- **Where it is written down:** [app.md](../app.md) §2.2; issue #5 §3.2, §5.567## Context89The page needs two kinds of static file: the application's own chrome (the10stylesheet system and the hypermedia runtime) and the seam's built bundle. It11would be simpler to serve both from one static tree. It would also make the12deletability principle unfalsifiable, because a build without the seam would be13a build without a stylesheet.1415## Decision1617Two mounts, and the difference **is** the deletability principle in the URL18space.1920| Route | What it is |21|---|---|22| `GET /assets/{app.css,htmx.js}` | the application's own chrome, compiled into the binary (`internal/app/assets`) |23| `GET /static/{path...}` | whatever static tree the host mounted; `404` when it mounted none |2425A build with no seam serves a complete, styled, interactive page.2627Both are **vendored rather than linked**. The offline invariant is not only28about bundles: an atlas opens on a machine with no network, forever, and a page29that fetches its runtime from a CDN is a page that does not.3031## Consequences3233- The `404` is asserted rather than tolerated — `TestStaticWithoutASeam`34 (`internal/app/app_test.go`) — which turns the difference into a check of35 the deletability principle rather than an unchecked absence. (It was first36 asserted by the harness's `seam-assets` waiver, archived on37 `golden-reference`.)38- The `make static` target copies only `render/dist/app.js` into the tree a39 host mounts. The stylesheet is deliberately not there: deleting the seam40 costs the page one script tag, not its chrome.41- The dev loop can reload the two independently — `templates.Reload(fs.FS)` and42 `assets.Reload(fs.FS)` for the application's own files, esbuild `--watch` for43 the seam.44- A host that hands over no static tree is a legitimate, tested configuration,45 which is what `atlas serve` is on a machine that never built the seam.