The product is split into crates that point one way: lichen-server over lichen-site (the assembly) over lichen-core, with the add-ons beside each other under the assembly and none naming another.
Core. lichen-core is its own crate. Its unnamed parts are named and the entry points the add-ons use (on_the_site and the rest) are on its surface; items an add-on needs are pub. Core names no add-on feature.
Add-on crates. lichen-shell, lichen-atproto-client (the two pds.rs made one), lichen-git, lichen-iroh (git's iroh part out of git) and lichen-publish (the publish out of git, with standard_site/). Each add-on depends on core, and on lichen-git where it needs git; lichen-publish takes lichen-atproto-client as an optional dependency. None depends on lichen-site, lichen-server or lichen-cli.
The assembly. It stays in lichen-site, which re-exports core (pub use lichen_core::*) and each add-on under its old module name, so lichen_site::git::… and the like still resolve. One constructor installs the assembly.
Held by structure tests. An add-on's manifest names no other add-on but the arrows above; core names no add-on feature; no crate below lichen-server names it; and the assembly is installed by one constructor.
ADD-ON-CRATES, the whole phase in one reading PR. Plan: https://tangled.org/notplants-bot.bsky.social/lichen-orchestrator/blob/main/machine-docs/plans/ADD-ON-CRATES-2026-10-31.md
Only the phase's Rust product code is here: every .rs file under crates/<crate>/src/ (no tests folder in its path), which is what e2e/ci/count_product_code_lines.py counts as product. The head is the base plus one commit that sets each of those files to its content at the end tip (added, changed, deleted and renamed files alike). Tests, docs, scripts and non-Rust files (including Cargo.toml and Cargo.lock) are not in it, so the crates here are not meant to build on their own. Reading copy; nothing here is to be merged.
Source PRs on lichen.page.review (product), in order #
- #3730 core's unnamed parts named, the add-ons' entry points on its surface (ADD-ON-CRATES unit 1)
- #3732
lichen-core, its own crate (unit 2) - #3736
lichen-shell(unit 3) - #3741
lichen-atproto-client(unit 4) - #3743 git's iroh and atproto parts out of git (unit 5a)
- #3747 the same, second part (unit 5b)
- #3751 the publish out of git (6a) and
lichen-git(6b) - #3755 the closing standard's reds (R1)
- #3760 the closing reds of the earlier test pair (R2)
- #3761
lichen-iroh(unit 7) - #3763
lichen-publish, withstandard_site/(unit 8) - #3767 the reds referred from the closing standard and full runs (R3)
- #3771 reds from R3's own review (R3)
- #3773 reds from R3's own review (R3)
- #3774 the closing runs' repairs, comments
- #3775 the closing runs' repairs, and the lanes' check of the crates split from
lichen-site
Product commits from other work on stack, in this range #
Not ADD-ON-CRATES' own, but on stack between the base and the end tip, so in this diff: EGRESS-SOCKET-KIND unit 1's change, a connect's socket kind read by its protocol's name (c39670aa2, and its round 1 ea5c73db6). The rest of what landed in that range is tests, CI and docs.
Base, end tip, count #
Base 3a5f2d0bb1708e1745bff3bfe3ac409f2ad4a9c0. End tip 65a3cb4881ed2011eea4079368510f1714a63a8b. Head 31ab77c230e6b7d50cc8ace7bbb69695397c0cb3 (358 files: 188 added or changed, 170 deleted).
Counter, base to end tip (the phase as lichen.page.review has it):
count-product-code-lines 3a5f2d0bb170..65a3cb4881ed: NET +466 · counted +37726 -37771 · moved out of the counted set +511 · comment-only deletions flagged 6 · macros flagged 0 · tests-folder code flagged 0
Counter, base to head (this PR):
count-product-code-lines 3a5f2d0bb170..31ab77c230e6: NET -65 · counted +37706 -37771 · moved out of the counted set +0 · comment-only deletions flagged 6 · macros flagged 0 · tests-folder code flagged 0
The two are equal in every Rust line. They differ only by lines outside the Rust files that the counter reads from the end tip: the crates' build.rs files, the starter sites' HTML and CSS and nix/ci-docker.sh as moved out of the counted set (+511), and the included lichen-core/src/ssg/templates/layout.html (+20). Those files are not in this PR.
Check #
git diff base head lists only counter-product Rust files, and the head's content equals the end tip's for each of them. For the counter, the head's counted and NET lines equal the end tip's once those non-Rust lines are taken out.
Record #
ADD-ON-CRATES is COMPLETE at stack 65a3cb4881ed2011eea4079368510f1714a63a8b (coordination report machine-docs/reports/ADD-ON-CRATES-2026-11-09.md). Unit S3 (the publish screen's check loop) was withdrawn by the operator and is not here.