superseded by the full set from 09-23, #17–#37
description:
Review set for lichen.page.review, 0b92cb61 (reviewed) → eb5a1653 (stack). PR 5 of 16. 7 files, +3853/−878. One commit, 182d4a2a1780, which sets these files to their content at eb5a1653. Targets #4 (oct/04-site-area). #6 stacks on this one. Tests and generated files are not in any PR; they are in main.
Every push into a site's history now goes through one receive on the site's hub (SITE-FRONT-BOUNDARY unit 4, decisions 3, 13 and 16), whoever pushes:
- The site pushes too. Each commit lichen makes in the site is pushed into the hub right after (
commit-to-hub). The site reads the hub by path, read-only; if the hub'smainhas moved, it merges first (never a rebase), and a refused push merges and retries, at most three attempts in all. The push is written by the site itself as one smart-HTTP request, so no child of the site reaches the front server. - Clients' git goes to the hub, not to the site.
GET /git/{domain}/info/refsand theupload-pack/receive-packroutes are served by the front server from the hub, in every mode. The old path, where the front server forwarded a client to the site'sgit http-backendCGI, is deleted from both crates (−878 lines). - The receive's rules (
check_main, run before any ref moves): onlymain(and, for the site,refs/dist/latest); no deletions;mainonly forward unless the pusher's policy allows a force push (a full token, decision 7; never the site); no symlink that leaves the tree. The pack is bounded by the owner's remaining storage (receive.maxInputSize). Admission is the only difference between pushers: a client by its token or session, the site by the connection the front server opened for it. - A full token's force push is received into
refs/lichen/incomingfirst, thenmainis moved by the front server's rewrite sequence (#6), and the client gets the front server's own report. - After a client's push moves
main, the site is asked to merge it (merge-from-hub).
info:
Plans: SITE-FRONT-BOUNDARY-2026-10-17.md ("The hub", decisions 3, 7, 13, 16; units 4, 5 and 8b), notes SITE-FRONT-BOUNDARY-U1-DESIGN-2026-10-19.md and -U8-DESIGN-2026-10-22.md §11.
Files
crates/lichen-server/src/site_area/hub.rs— new:receive(gitreceive-packconfined to the hub, the front server's config on its command line, none of the hub's own hooks),check_main(the pre-receive, front-server code),PusherandPolicy,upload. Read this first.crates/lichen-server/src/site_area/hub/full_push.rs— new: the full token's push tomainviarefs/lichen/incoming.crates/lichen-server/src/git/hub_http.rs— new: clients' smart-HTTP routes on the hub, their groups, and the merge request after a push.crates/lichen-server/src/git/hub_files.rs— new: read one blob of a hub commit through git, bounded, never a link or a tree. Used by the publish (manifest, covers) and the PDS import.crates/lichen-site/src/git/hub.rs— new (1807 lines): the site's side: read the hub, merge, build and send the push (HubTransport: the site process's request channel, or the front server's own receive in local mode), retry on "hub moved";holdandresetfor the rewrites.crates/lichen-server/src/git/smart_http.rs,crates/lichen-site/src/git/smart_http.rs— deleted: the forwardedgit http-backend.
Moved in: the starting map put these files under "Git" and "Site area". They are one subject (the receive and the two kinds of pusher), so they are one PR, between the area (#4) and the sync with remotes (#6).
Lives elsewhere
- The hub repository itself (create, migrate, rewrite helpers, restore): #4.
/hub/git-receive-pack, the site process's one request to the front server: #3.- The
lichen hub-checkdispatch in the CLI (lichen-cli/src/main.rs): #11. - Tests (
site_area__hub*.rs, the CLI's site-process tests, e2e git tests) are inmain.