superseded by the full set from 09-23, #17–#37
description:
Review set for lichen.page.review, 0b92cb61 (reviewed) → eb5a1653 (stack). PR 11 of 16. 17 files, +4043/−769. One commit, a85be6aff884, which sets these files to their content at eb5a1653. Targets #10 (oct/10-front-auth). #12 stacks on this one. Tests and generated files are not in any PR; they are in main.
The front server's state, its settings and the dashboard's JSON API, plus the CLI and the desktop app's entry points.
- The dashboard API is a contract.
contract/dashboard-api.jsonlists every route the dashboard router serves on the dashboard host, each classified (provisional, internal, page) with its responses and permission group, and a test fails when the router and the contract differ. Every/apierror is in one error shape, and?format=htmlon an/apiroute is refused with 406 inside the route's group. A custom dashboard may use the provisional routes throughlichen-ts/dashboard(#14). api.rs, the dashboard API, puts every route in its permission group and does the site acts through the new front-server code: create and delete (shared with the no-JavaScript forms), backup status (STC-BACKUP1),POST /api/auto-pull(a GET never acts, ADMIN-EDIT-HOST-SPLIT H3), compact, compact-all, force-pull, force push (#6), trigger-publish (#7), and the edit-host handoff (#10).state.rsgains what the front server now owns: each site's publish lock and asks, each site's iroh transport, the dashboard's per-owner event stream (created, deleted, publish finished), the password sign-in limit, the PDS import into the hub (SITE-FRONT-BOUNDARY unit 10a: settings read from the hub by git, not from a checkout), and recycling an owner's site processes when the owner's public facts change (N8).- A single-site server keeps its own state beside the site, not in it (SINGLE-STATE1, STC-CLAIM1): users, tokens, keys and its own
lichen.tomlmove once into.<site>.lichen/(orLM_STATE_DIR), mode 0700, and server keys left in the site'ssettings.tomlare then ignored, with a warning. - New settings:
use_shortcodes_cache,trusted_proxies;hot_reload_templatesis gone with Tera.confined()andsite_processes()say how sites run in each mode. - CLI and desktop:
lichendispatches the hub's pre-receive check and--build-idbefore anything else, starts site processes from its own inode on Linux, and losesssh-relay. The desktop app can serve a site process too.
info:
Plans: DASHBOARD-REACT-2026-10-07.md (unit 1: the API and its contract; design note DASHBOARD-REACT-U1-DESIGN-2026-10-17.md §5–§7), SITE-FRONT-BOUNDARY-2026-10-17.md (units 8, 9a, 10a, 11d, 11e), ADMIN-EDIT-HOST-SPLIT-2026-10-13.md (H1e, H2a, H3), OPERATOR-REVIEW-REVISIONS-2026-10-13.md (N8), and the single-site fixes SINGLE-STATE1 and STC-CLAIM1.
Files
contract/dashboard-api.json— new (2024 lines): the dashboard API contract. Hand-written (route notes and design references), and read by product code (dashboard_source.rsincludes it), so it is reviewed here rather than treated as generated.crates/lichen-server/src/api.rs(+576/−358) — the dashboard API. Read first.crates/lichen-server/src/state.rs(+798/−210) — what the server holds; the PDS import; site events; owner-fact recycles.crates/lichen-server/src/server_settings.rs(+449) — SINGLE-STATE1's state directory and migration; new settings;confined,site_processes.crates/lichen-server/src/owner.rs— the owner's public facts only; the session moved tocredentials.rs.crates/lichen-server/src/features.rs— mostly its inline test module: the site-runtime iroh sync test goes with the site's iroh runtime (#9).crates/lichen-server/src/index.rs— two folders whose names differ only in case are one host; the second is not served.crates/lichen-server/src/lib.rs,site_settings.rs,site_host.rs,desktop/server.rs— module list, re-exports, the storage question removed, desktop defaults.crates/lichen-server/Cargo.toml— iroh and iroh-blobs (the transport moved here),lichen-sandbox,flate2;teraremoved; test-onlyzip,syn,quote,sha2.crates/lichen-cli/src/main.rs,client.rs,oauth_server.rs,server.rs— the dispatches above; error text from the API's error shape; the OAuth callback's route in a group.crates/lichen-tauri/src/main.rs— serves a site process when launched as one.
Moved in: contract/dashboard-api.json (the starting map called it generated; it is hand-written and product code reads it).
Lives elsewhere
- The dashboard's pages, its custom-dashboard loader and the Tera removal: #12. The dashboard frontend itself: #14.
- Host routing and sign-in: #10. Permission groups and
access.rs: #2. - Tests (
tests/dashboard_api.rs,tests/state.rs,tests/server.rs, the boundary guard and its tables,workspace_structure.rs, the CLI's tests) are inmain.