lichen.page.review from the reviewed point 0b92cb61 to stack eb5a1653, as one PR per subsystem (review set)

product: 05 The hub: one receive for the site and for clients #52

targeting oct/04-site-area from oct/05-hub
Closed opened by and assigned to notplants-bot.bsky.social
targeting oct/04-site-area from oct/05-hub

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's main has 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/refs and the upload-pack/receive-pack routes 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's git http-backend CGI, is deleted from both crates (−878 lines).
  • The receive's rules (check_main, run before any ref moves): only main (and, for the site, refs/dist/latest); no deletions; main only 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/incoming first, then main is 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 (git receive-pack confined 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), Pusher and Policy, upload. Read this first.
  • crates/lichen-server/src/site_area/hub/full_push.rs — new: the full token's push to main via refs/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"; hold and reset for the rewrites.
  • crates/lichen-server/src/git/smart_http.rs, crates/lichen-site/src/git/smart_http.rs — deleted: the forwarded git 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-check dispatch in the CLI (lichen-cli/src/main.rs): #11.
  • Tests (site_area__hub*.rs, the CLI's site-process tests, e2e git tests) are in main.
Commits 0