Reading copy of lichen.page.review: one PR per unit, product changes only

ONE-DOOR unit 2: storage admission and building each go through one door #65

targeting base/one-door-unit-2 from view/one-door-unit-2
Open opened by and assigned to notplants-bot.bsky.social
targeting base/one-door-unit-2 from view/one-door-unit-2

Storage admission and building each go through one door.

  • Storage admission is one typed check at every entry point: site creation (before import creates a user or fetches content; an absent owner gets the default limit), existing write and execution checks, raw uploads (before staging and again before publishing; HTTP 507), and fetched frontend and plugin pins (before they enter the settings transaction). Package storage refusals use one typed API adapter, and boolean quota helpers are folded into the typed admission. The dashboard shows the usage that is enforced, from one traversal that excludes only the top-level dist; imports and existing sites share one usage measurement and allowance write.
  • Every build goes through the one build lane, including startup and the offline helper, which no longer call build execution directly. Publication outcomes are emitted once per actual lane attempt, and build requests and results use one channel carrying a typed publication or held-artifact outcome (awaited requests get a receiver, background ones none).
  • Frontend and plugin updates are admitted inside their update functions, before any network work.
  • Removed: duplicate walkers, the receipt wrapper enum and its methods, the redundant API rebuild wrapper, the legacy test enqueue conveniences and the offline forwarding wrapper.

ONE-DOOR, unit 2 (subunits 2a, 2b, 2c, 2d, 2e, 2f, 2g combined, replacing their per-subunit PRs). Plan: https://tangled.org/notplants-bot.bsky.social/lichen-orchestrator/blob/main/machine-docs/plans/ONE-DOOR-2026-10-30.md

This is a reading copy: only this PR's product changes, applied in order on its base. Nothing here is to be merged.

Source PRs on lichen.page.review (product), in order, with their original descriptions #

  • #3472 s/844-od-u2a-usage-product — shared dashboard storage usage

    The dashboard displays the same storage usage as enforcement: exclude only top-level dist and include the site backup. Reuse the existing server usage adapter and remove the dashboard-only whole-folder wrapper.

  • #3474 s/846-od-u2b-owner-product — owner storage admission for create and import

    Move creation quota admission from the HTTP adapter to the server operation and apply the same typed refusal before import creates a user or fetches content. An absent owner obeys the configured default limit.

  • #3476 s/848-od-u2b-site-product — typed site storage admission

    Route existing write and execution quota checks through one typed admission method, preserving cheap write checks and fresh execution measurements. Existing adapters retain their refusal ordering and messages.

  • #3478 s/850-od-u2b-save-product — storage admission inside raw uploads

    Check storage at the raw upload entry before staging, draining a refused body, and check again after streaming before publishing the prepared file. Keep the HTTP refusal as 507.

  • #3480 s/852-od-u2b-pins-product — recheck storage before package pins

    Measure storage afresh before a fetched frontend or plugin pin enters the settings transaction. Propagate the typed refusal through existing failed-update cleanup and 507 storage-full responses.

  • #3482 s/854-od-u2b-errors-product — shared storage refusal responses

    Use one typed API adapter for package storage refusals, preserving 507 and the existing message. Normalize page rendering from storage-limit to storage-full as specified by ONE-DOOR.

  • #3484 s/856-od-u2c-startup-product — managed startup through the checked build lane

    Prepare managed site files without the unchecked initial build. Construct the runtime with its owner allowance and published hook, then await the lane build before exposure. Invalid settings remain repairable without an invented build.

  • #3486 s/858-od-u2c-offline-product — offline builds through the shared lane

    Remove the offline helper direct call into build execution. Queue its initial publication on the common lane with a single-use bootstrap snapshot; managed runtimes continue loading current settings for every build.

  • #3488 s/860-od-u2c-events-product — build outcomes belong to the lane

    Emit publication outcomes once per actual lane attempt, independent of waiter count. Remove change-context outcome emission and background receipt observers; keep event handles weak and group lane callbacks in one argument.

  • #3490 s/862-od-u2c-door-product — one build request door

    Consolidate runtime, weak change-context and offline lane admission. Awaited requests retain typed dist or held-artifact receipts; background requests have no receiver. Preview admission retains its minimum revision and all receipt waits check lock ordering.

  • #3492 s/864-od-u2d-usage-product — one storage traversal

    Replace the duplicate recursive and top-level exclusion walkers with one traversal. Production callers use whole-folder counting or exclude top-level dist; nested dist, history and temporary bundles remain billable.

  • #3494 s/866-od-u2d-fetch-product — admit direct package fetches

    Admit frontend and plugin updates inside their update functions before network work. Retain fresh admission before pinning and existing HTTP refusal ordering. Share optional-limit admission with the runtime and build lane.

  • #3496 s/868-od-u2e-receipt-product — one typed build outcome channel

    Replace duplicate sender and receipt variants with one channel carrying a typed publication or held-artifact outcome. Background requests have no sender. Actual failed Dist builds still report Kept; actor shutdown and poisoned status still refuse without a known outcome.

  • #3498 s/870-od-u2e-adapters-product — reuse rebuild and refusal adapters

    Remove the redundant API rebuild wrapper and validate the runtime publication outcome directly. Raw upload admission reuses the existing bounded refused-body drain instead of an unbounded loop.

  • #3500 s/872-od-u2e-wait-product — optional typed build receipts

    Remove the receipt wrapper enum and methods. Awaited requests return a typed receiver; background requests return none. The common wait retains lock assertions, actor-drop refusal and publication report validation.

  • #3502 s/874-od-u2f-allowance-product — one allowance writer

    Share usage measurement and allowance writing between existing and newly imported sites. Explicit targets receive the saturating sum of other sites; ownership remains held through the blocking writer, including caller cancellation.

  • #3504 s/876-od-u2f-states-product — concrete lane state and shared traversal

    Make the lane source tree and successful attempt concrete: construction already refuses absent trees, and attempts always return an outcome or error. Replace the storage traversal stack with the existing walkdir iterator, preserving top-level directory exclusions and link metadata accounting.

  • #3506 s/878-od-u2g-admit-product — typed quota admission and cache refresh

    Fold boolean quota helpers into typed admission. Blocking measurements update the cached flag directly, removing the observer task; failed background measurements leave the flag unchanged. Execution still refreshes usage and writes still use the current cheap allowance.

  • #3508 s/880-od-u2g-entry-product — remove obsolete build entry conveniences

    Delete the legacy test enqueue conveniences and offline forwarding wrapper. Runtime and offline requests use the common admission and typed outcome path directly; runtime imports name that shared implementation consistently.

Commits #

  • 2f1e61893 ONE-DOOR unit 2: subunit 2a
  • 53a675c01 ONE-DOOR unit 2: subunit 2b
  • 68b830036 ONE-DOOR unit 2: subunit 2c
  • 83c12fce8 ONE-DOOR unit 2: subunit 2d
  • efc59fe9f ONE-DOOR unit 2: subunit 2e
  • e0b3dfd8e ONE-DOOR unit 2: subunit 2f
  • 5adb7e847 ONE-DOOR unit 2: subunit 2g

Count and shas #

count-product-code-lines db55ab4929cd..5adb7e847348: NET -4 · counted +377 -381 · moved out of the counted set +0 · comment-only deletions flagged 9 · macros flagged 0 · tests-folder code flagged 0

Base db55ab4929cd59a87606ae126998f2d4c51aa0a4 (tip of s/843-od-u1f-artifacts-tests). Head 5adb7e847348db8e192470f61227e7425cee37c3. 24 files changed.

Check #

Every changed file is a file one of the product PRs changed, and each is identical at the head to the same file at the last product branch s/880-od-u2g-entry-product.

No file here was changed by any tests PR of this unit.

Commits 0