A site's builds: the rebuild lane and the static site generators (lichen-ssg, Hugo, mdBook, and the new script generator). Since 09-23 the lane has become the site's one build path with three targets (the published site, a preview with drafts that publishes nothing, and a check), lichen-ssg runs shortcodes and build hooks, and a site may be built by its own script. The code also moved from the lichen-cms crate to lichen-site with the rename.
AST-verified changes
- The crate rename lichen-cms → lichen-site (PER-SITE-PROCESS P2c-1, d7c4a668) carried every file here. Checked (run id not recorded): "Rename move check with rn6 at f3e7470b..d7c4a668: ok (4365 items, 113 renamed, 1874 carried, 0 visibility)"; adversary rerun (A11324): "d7c4a668 equal=true 0-err 113-renamed 1874-carried 0-vis". Allowed:
lichen_cms→lichen_siterewrites,Cargo.tomland static files as other files, rustfmt rewraps; string literals changed in a separate commit (8eef92b4).rebuild.rschanged so much after that git shows it as a deletion undercrates/lichen-cms/and an addition undercrates/lichen-site/, both here;ssg/mdbook.rsreads as a rename again since FULL-SITE-PROCESS moved its process-group code out. ssg/mod.rsrenamed tossg.rs(OPERATOR-REVIEW-FIXES U1, N8, f6a10c32). Checked over 8b30050a..f6a10c32 (run id not recorded): "3004 items, 48 moved, 69 carried, 19 renamed, 2 visibility as mapped, 233 module declarations"; adversary rerun notify-abab368a, the same counts.- The publication renames of OPERATOR-REVIEW-REVISIONS R7 (d52675cd), in
rebuild.rs,ssg/lichen.rs,ssg/script.rsandssg/ssg_trait.rs:Target::Published→Dist,Made::Published→DistInstalled,publish_staged→install_dist,BuildKind::Publish→Site, and others. Checked by substituting the names back: run notify-392a0b96, "names substituted back AST EQUAL, control RED"; adversary (A11506): "rename AST-equal (control RED)".
Roughly 600 of this PR's 2,890 changed lines are code these moves carried verbatim, nearly all of it the old rebuild.rs reappearing under lichen-site; the rest is the lane's targets, the script generator and the shortcodes in lichen-ssg.
On this forge the 7 renamed files here show as a whole deletion and a whole addition, so its diff reads 6,048 changed lines; with rename detection (git diff -M full/10-scripts full/11-ssg) it is 2,890.
What changed
- The lane (
rebuild.rs): a request names a target: the published site, the preview (drafts, future-dated and expired pages, its base URL the preview route) or a check that publishes nothing. Requests for one target coalesce, a build whose revision moved while it ran is redone, and only the published target publishes and records failures. "Changed" is the tree's revision (lichen-flat-file's change counter), so writes to the site's metadata, which do not advance it, never trigger a build. After a publication whose scripts ran, aPublishedHookcommits what they wrote without advancing the revision (operator note N1). Over the owner's storage limit no build runs (SHB-STORAGE1). - The preview (
preview.rs, 9b's design record): the whole site as an editor sees it, built into a private folder the lane holds; its routes are in #35. - lichen-ssg (
ssg/lichen.rs): runs shortcodes and the build's before and after hooks; a failing shortcode leaves its place empty in a publish and is reported, and withstrict_scriptsa failing shortcode or hook refuses the publish. A page that is live and fails refuses a site build; one that was never live is left out and reported. - The script generator (
ssg/script.rs, SSG-BUILD-OVERRIDE B2): a site whosessg = "script"is built by its ownbuild/ssg.<lua|js|py>, called only where it has something to say. - Hugo and mdBook (
ssg/hugo.rs,ssg/mdbook.rs): Hugo's previews build drafts with the preview's base URL, and Hugo gets the site child's prepared environment (CHILD-ENV-CLEAR); mdBook runs in an mdBook child of its own (FULL-SITE-PROCESS unit 1c,scripts::engine::build_book), confined to what the build may touch: its book's commands are that child's children, in its process group, and past the time bound it is killed with them. - The generator trait (
ssg/ssg_trait.rs):SSGKind::Script, aBuildKind(site or preview), and a staged build that carries its check report and whether scripts ran. - The default layout (
templates.rs): the no-JavaScript editor's Tera templates are gone (REPLACE-TERA R1b), so lichen-ssg renders with the site's templates and its own defaultlayout.html, nowinclude_str!'d fromssg/templates/layout.html(operator note N7) instead of an embedded templates folder.
Files (crates/lichen-site/src/)
rebuild.rs— the lane. Read this first. Its 09-23 copy,crates/lichen-cms/src/rebuild.rs(−485), is deleted here.ssg/ssg_trait.rs— the generator trait and the staged build.ssg/lichen.rs— lichen-ssg.ssg/script.rs— new: the script generator.ssg/mdbook.rs— mdBook, renamed fromcrates/lichen-cms/src/ssg/mdbook.rs; the build itself is the engine child's (#26).ssg/hugo.rs,ssg/overlay.rs(create_content_overlay_in) — Hugo and the shared preview overlay.preview.rs— the preview's build and its base URL.templates.rs— the default layout.ssg.rs— the module list.
Moved in: the lichen-cms rebuild.rs deletion above, with the file it became (git pairs them only below its default similarity); preview.rs (the starting map put it in site core; it is the lane's preview target).
Lives elsewhere
- Shortcodes, the script runners, the engine child mdBook runs in, and the no-JavaScript render: #26.
- A publish's build and what is deployed: #24, #25.
- The preview's and check's routes (
api/preview.rs,api/build.rs): #35. call-joinand the process groups: #17.ssg/templates/layout.html(the default layouttemplates.rsincludes) and the starters are non-Rust, in the base commit. Tests (ssg/tests/,src/tests/rebuild.rs,src/tests/preview.rs,tests/call_cleanup_mdbook.rs) are in the base commit.
Category: SSGs, rebuilds and the preview build
Size: 11 files, +2,184/−706
Rounds: round 0 at stack ae42e3c0; at 29a7c15b and at 6b650b2a none of this PR's files changed; round 1 at b66397c0 (FULL-SITE-PROCESS units 1 and 1c): mdBook builds in its own child (scripts::engine::build_book), so ssg/mdbook.rs loses the code that put each book command into the build's process group; ssg/script.rs starts its pane sweep on the narrowed thread at a site process's start. Read this round in its interdiff: https://tangled.org/notplants-bot.bsky.social/lichen.page.october/pulls/27/round/1/interdiff
Plans and ledger: FULL-SITE-PROCESS-2026-10-25.md (units 1, 1c); SSG-BUILD-OVERRIDE-2026-10-02.md with SSG-BUILD-OVERRIDE-DESIGN-2026-10-08.md (B2); SSG-SCRIPT-SHORTCODES-2026-10-02.md; PER-SITE-PROCESS-2026-10-09.md (P2c-1, P4-5); CHILD-ENV-CLEAR-2026-10-08.md; REPLACE-TERA-WITH-SSR-REACT-2026-10-07.md (R1b); OPERATOR-REVIEW-REVISIONS-2026-10-13.md (N1, N7, R7); OPERATOR-REVIEW-FIXES-2026-10-07.md (U1, N8); SITE-FRONT-BOUNDARY-2026-10-17.md (decision 6). Ledger: lichen-builder B2087, B2322, B2777; lichen-adversary A11224, A11324, A11506.
Inline #[cfg(test)] modules: none inline; 7 files point to a test file with #[path].
Bucket moves: round 1's Builds PR is split: SSGs and the lane here, scripts and the SSR in #26. preview.rs moved in from site core; the lichen-cms rebuild.rs deletion is placed with its new file.
Round 1: #8 (Builds: scripts, shortcodes, SSGs and the server render) covered these files from 0b92cb61, except preview.rs, ssg.rs, ssg/overlay.rs and the lichen-cms deletions, which are new to the set.