# Distro composition manifest — single source of truth for "what files make a # deployable distro". Consumed by: # - lian-build/build_directives.ncl (image_only → what the runtime image bakes) # - provisioning/content.nu (content_hot → incremental PV hot-updates) # - just distro (site_tree + image_only → local tarball) # # Two layers, mapping the Build-Time vs Runtime tension (ADR-006): # # site_tree Capa B — delivered to the PV at /var/www/site/. Identical for # both render profiles, independent of the binary, updatable # without a rebuild. website.css under public/styles/ must be # freshly built (uno) before packing — that is an assembly step, # not a Dockerfile concern (the runtime image is content-agnostic). # # image_only Capa A — baked into the runtime image, per profile. The Leptos # WASM pkg/ is version-matched to the binary by construction: # baked to /usr/local/share/website/pkg/ and bootstrap-copied # into the PV. htmx-ssr ships no WASM, so its image bakes nothing # beyond the binary. # # reload_classes Update taxonomy — the class of a changeset drives the minimal # correct action. The classifier (content.nu, T2) buckets each # changed path, takes the highest-severity class present, publishes # the payload once, then runs only that class's action. Paths are # matched against changed-file paths as `git diff` emits them from # the content source-of-truth root (so both `site/…` and top-level # trees like `htmx-templates/` are addressable). Any path not # matched escalates conservatively to `restart` (T2 default). # # soft_reload_enabled Capability flag: whether the running binary can hot-reload # templates + rbac IN-PROCESS (T2b wires a notify watcher on # HTMX_TEMPLATE_PATH → reset_htmx_env(), and adds `rbac-watcher` to # the htmx-ssr feature). While false, the `soft_reloadable` paths # fall back to `restart`; flip true once the soft-reload image ships. { site_tree = [ "site/content", "site/config", "site/i18n", "site/templates", "site/public", "site/rbac.ncl", # Vendored htmx runtime (htmx.min.js + ext/*), top-level sibling of site/. # Binary-independent, PV-delivered, served at /assets/htmx/* via the router's # dedicated ServeDir(HTMX_ASSETS_PATH) — NOT from site/public. Assembled by the # site's `just htmx-assets` from templates/shared/htmx. Mounted unconditionally # by the router, so harmless to ship for leptos-hydration too. "htmx-assets", ], image_only = { "leptos-hydration" = ["target/site/pkg"], "htmx-ssr" = [], }, soft_reload_enabled | default = false, # Paths that BECOME config_reload-class when soft_reload_enabled is true, and # fall back to restart while it is false (verified against the shipped binary: # reset_htmx_env has no watcher, rbac-watcher is absent from the htmx-ssr feature # set — see the 2026-07-08 review). NOTE: htmx-templates is a sibling of site/ in # the source tree but is NOT yet staged onto the PV by distro.nu / bootstrap, so # the live server currently reads the BAKED templates. Until PV delivery lands # (T2b/T7), a real htmx-templates change is effectively rebuild-class; this entry # encodes the intended policy once templates are PV-delivered. soft_reloadable = [ "site/rbac.ncl", "htmx-templates", ], reload_classes = { # Served per request from disk — no pod action. Markdown bodies are truly # per-request; the `r/` listing indexes pass a TTL cache, so index-affecting # changes are visible in listings only after the TTL (content.nu reports it). hot = [ "site/content", "site/public", # Static runtime files served per-request by ServeDir — a new version is # visible immediately, no pod action needed. "htmx-assets", ], # In-process reload, no restart. Empty until soft_reload_enabled (see above). config_reload = if soft_reload_enabled then soft_reloadable else [], # Rolling restart + wait. FTL locales and startup-read config live here. The # broad `site/config` catches every startup-read *.ncl (database, email, # security, …); `site/config/rendering.ncl` is carved out to `rebuild` below # and wins by higher severity in the classifier. `site/i18n/locales` moved out # of the hot set here — the server never hot-reloads FTL, so hot-shipping it # was a silently-broken deploy (the T1 fix). restart = [ "site/i18n/locales", "site/config", ] @ (if soft_reload_enabled then [] else soft_reloadable), # Image rebuild + deploy update. Flipping the render profile (leptos↔htmx) is a # different image; new routes/pages need a recompiled router. rebuild = [ "site/config/rendering.ncl", ], }, # Back-compat alias: content.nu still reads `--field content_hot` (T2 replaces it # with the reload_classes-aware classifier). Derived, so reload_classes.hot stays # the single source of truth. content_hot = reload_classes.hot, }