Site directory layout
A Dropbits site is a directory that holds identity, themes, and content. It may live under a hub’s sites/, under deployable/, or inside a content-owned install — resolution follows site.json and (on hubs) a scan of known roots, not a fixed parent path. Contract: OPEN-DECISIONS.md S3 · deploy: DEPLOY.md.
For where documentation lives in the monorepo (docs/ vs dropbits/docs/ vs website/), see Repo docs layout.
Classes of site (S3)
| Class | Home | Git / ship | Wipable? |
|---|---|---|---|
| Shipped | dropbits/sites/minimal, _template | Tracked in product tip | No |
| Ephemeral / playground tenant | dropbits/sites/<id>/ (non-underscore = provision; _smoke = CI) | Gitignored | Yes — TTL or test recreate |
| Deployable / dogfood | deployable/<id>/ (sibling of dropbits/) | Gitignored in product tip; optional separate private git repo (symlink) | No |
| Production install | $LOCAL_INSTALL_ROOT/sites/<id>/ | Outside monorepo | No |
Monorepo tree
dropbits-v9/
playground/ # hub UI — ships with clone/dist (Codeberg v9)
deployable/ -> ../dropbits-dogfood # symlink to private dogfood repo (optional)
dropbits/ # shipped product
sites.json # tracked — default + minimal only
sites.local.json # optional special-case overlay (gitignored)
sites/
minimal/
site.json # shipped identity
themes/<slug>/
shell.html
dropbits-site.css # identity + durable mechanisms (not chat-writable)
dropbits-user.css # LLM / Appearance overrides only
assets/cms/ …
data/ … # runtime only; not routine-deploy uploaded
_template/
deploy.env.example
README.md
_smoke/ … # ephemeral CI (recreated; not registered in overlay)
<ttl-tenant>/ … # playground provision
dropbits-dogfood/ # separate private git — persistent SoT
<id>/
site.json # identity (id, label?, created_at/modified_at, llm_profile?)
deploy.env # gitignored (host paths)
themes/ …
data/ … # gitignored; backup separately (not routine-deploy)
Production install tree
$LOCAL_INSTALL_ROOT/ # DocumentRoot parent of public/
src/ bin/ public/ packs/ … # kernel (rsync’d)
docs/ # product docs
sites.json # one entry — materialized at deploy from site.json + live
sites/<id>/
site.json
themes/ …
data/ # content-owned
Install roots (closed)
public/is the kernel web root. Point DocumentRoot at…/public/inside the install. Do not extract it beside the install —public/index.phpself-locates the install viadirname(__DIR__).- Tenant sites may live under
sites/or siblingdeployable/(SiteContext::knownSiteRoots). Seed (minimal,_template) stays underdropbits/sites/. - Do not split the install into separate kernel and content halves that must find each other at runtime; one-box prod already co-locates both under the install.
What lives where (inside a site dir)
| Path | Role |
|---|---|
site.json | Portable identity — never live, ttl_days, paths, or secrets (S3) |
themes/<active>/ | Shell + CSS layers (base / site / user) |
data/ | site.db, uploads, secrets, pack config — content-owned. Routine rsync does not ship or --delete this directory. Migrate, deploy-log, optional empty-dest seed, and --remote editorial pull may write it. |
assets/ | Optional site assets |
deploy.env | Host-local deploy targets (gitignored). Presence ≠ live. |
sites.production.json | Legacy/fallback install registry source in site dir; deploy prefers materializing install sites.json from site.json. |
Theme CSS write roles (D34)
| File | Who writes | Practice |
|---|---|---|
dropbits-site.css | Humans / coding agents on disk — not Assistant tools | Identity + durable theme mechanisms (layout, brand, default nav compact). Optional :root knobs when owners may tune them. |
dropbits-user.css | Assistant patch_user_css only | Overrides (Appearance tokens, duration knobs, owner tweaks such as View Transitions fade). Checkpoints restore this + DB, not site CSS. |
| — | Do not add patch_site_css | Chat must not wipe identity. |
Same mechanism, two writers: theme authors may ship defaults in site CSS; owner chat requests go through patch_user_css → user CSS. Tokens: Prefer the curated Appearance set (colours, fonts, --max-width / --space / --radius). Discover via read_theme_file on site :root. Do not invent a token for every CSS property — site-specific dials (e.g. --page-fade-duration) live in site :root until several sites need them in Appearance. Detail: OPEN-DECISIONS.md A0 safety model.
Compact nav (first paint): hamburger CSS keys off html.db-nav-compact, driven by :root { --nav-mobile-max: 900px; } (themes may override the token). Custom properties cannot appear inside @media, so the kernel injects a blocking head script (id="db-nav-compact-sniffer") after stylesheets; nested-nav.js (defer) still handles the drawer and resize. Scope compact rules to the shell header (.site-header / .header). Do not dual-load nested-nav.js. Do not replace the class with a fixed @media px that disagrees with the token. A remaining full-page blink between URLs is MPA paint — optional @view-transition { navigation: auto; } in site or user CSS, not a client router.
Registries / overlay
| File | Role |
|---|---|
sites.json (tracked) | Shipped demo: default: minimal + minimal |
sites.local.json | Optional special-case overlay only (out-of-tree path, rare overrides). Not required when the site sits in a known root. |
Install sites.json | One site; DROPBITS_SITE + optional DROPBITS_LIVE |
Do not add customer site trees to the public git registry. Do not ship sites.local.json or deployable/ in the Codeberg tip. Prefer a separate private repo for dogfood SoT (themes + notes); keep site.db / uploads / secrets out of that git history and recover them with bin/site backup — see DEPLOY.md § Dogfood git.
New site (dev host)
mkdir -p deployable/<id>/{data,themes/default}
# copy shell/CSS from dropbits/sites/minimal/themes/default
# write site.json with id, modified_at
cp dropbits/sites/_template/deploy.env.example deployable/<id>/deploy.env
# hub scan / SiteContext resolve discovers deployable/<id>; no sites.local.json required
DROPBITS_SITE=<id> ./bin/site migrate
Or provision under dropbits/sites/<id>/, then graduate: ./bin/site graduate --id=<id> — see DEPLOY.md § Graduate.
See also
- Install locally
- Content-owned deploy
- Install on server
- Deploy companion: docs/DEPLOY.md
- Provisioner / TTL: docs/PROVISIONER.md