# Deployment bootstrap ZDDC tools (archive, transmittal, classifier, mdedit, landing) are single-file HTML bundles. The bootstrap pattern lets you install once on a deployment and update by editing a few lines, without re-uploading multi-megabyte HTML files. End users install via the unified [`install.sh`](install.sh) script, served at `https://zddc.varasys.io/install.sh`. The script handles all three deployment patterns (self-contained / channel-tracking / pin-to-version) plus both target shapes (deployment root or project subdirectory) via a single command: ```sh sh -c "$(curl -fsSL https://zddc.varasys.io/install.sh)" -- [options] ``` The published stubs live under `https://zddc.varasys.io/bootstrap/`: - `bootstrap/level1/.html` — same-origin level-1 stubs (4 tools, no landing — landing only lives at deployment root). - `bootstrap/track-{stable,beta,alpha}/.html` — per-channel level-2 stubs (5 tools each). Both directories are produced by the project's top-level `build.sh` from `bootstrap/level{1,2}.html.tmpl`. `install.sh` orchestrates which stubs to fetch and where to put them based on `--mode` / `--target` / `--channel`. ## The two-level model A typical `zddc-server` deployment looks like this: ``` / index.html # landing tool (or bootstrap) archive.html # archive tool (or bootstrap; site-wide channel switch lives here) transmittal.html classifier.html mdedit.html / archive.html # level-1 bootstrap → fetches ../archive.html transmittal.html classifier.html mdedit.html / archive.html # level-1 bootstrap (or pinned to a specific version) … ``` - **Level-1 stubs** at `/.html` always fetch the same-origin `../.html`. They never touch `zddc.varasys.io`. Install them once; they don't need to change. - **At deployment root** (`/.html`), put either: - the actual built tool HTML — fully self-contained install, no external dependencies; or - a level-2 bootstrap — fetches `/releases/_.html` directly (that path is a checked-in symlink on the upstream that resolves to the current channel mirror). No manifest lookup, no version arithmetic, no Codeberg proxy magic — every URL is a real static file or a static symlink chain. The site administrator switches the whole site to a channel by re-running `install.sh --mode track --channel ` — that overwrites the root `.html` files with the matching level-2 stubs. A single project can override one tool by editing just `/.html` (replace the relative `upstream` URL with an absolute zddc.varasys.io URL pointing at the desired version, channel mirror, or partial-version pin). ## Why two levels The level-1 stubs let projects share a single source of truth for "which build of the archive tool runs here." Switching channels is one file change at the root; pinning a single project is one file change in that directory. `document.write()` chains across both levels: level-1 fetches and writes, the new document's level-2 script runs and writes again, the third write is the actual tool. Origin stays at the deployment domain throughout, so File System Access API, `crypto.subtle`, and `localStorage` all work and preferences stay scoped to the deployment. ## Pinning options There are two ways to choose a version: edit the stub for a permanent pin, or pass a `?v=` URL parameter for a per-request override. ### 1. Permanent pin (point the stub at a fixed URL) The default level-2 stub fetches `/releases/_.html` — which is itself a symlink on the upstream that resolves to the current channel mirror. To pin permanently, change the URL inside the stub: | Target stability | URL the stub should fetch | |----------------------------------|------------------------------------------------------------------------| | Exact stable version | `https://zddc.varasys.io/releases/_vX.Y.Z.html` | | Latest patch within `.*` | `https://zddc.varasys.io/releases/_v.html` (symlink) | | Latest within `.*.*` | `https://zddc.varasys.io/releases/_v.html` (symlink) | | Track stable channel (default) | `https://zddc.varasys.io/releases/_stable.html` (symlink) | | Track beta / alpha channel | `https://zddc.varasys.io/releases/_.html` | ### 2. Per-request `?v=` parameter Both stub levels honor a `?v=` URL parameter. The parameter survives the `document.write()` chain, so it flows through level-1 → level-2 → upstream automatically. | URL parameter | Resolves to | |--------------------------------|-------------------------------------------------------| | `?v=0.0.4` (or `?v=v0.0.4`) | `_v0.0.4.html` (exact) | | `?v=0.0` (or `?v=v0.0`) | `_v0.0.html` (latest 0.0.x patch — symlink) | | `?v=0` (or `?v=v0`) | `_v0.html` (latest 0.x — symlink) | | `?v=stable` | `_stable.html` | | `?v=beta` | `_beta.html` | | `?v=alpha` | `_alpha.html` | | (omitted) | the default channel baked into the stub at install time | When level-1 has `?v=…`, it tries `../_.html` first (useful when the admin has staged specific versions locally — the upstream's symlink layout works the same locally) and falls back to `../.html` if 404 — which then forwards the parameter via level-2 if one is installed. Stable per-version files are immutable. The `_stable.html`, `_beta.html`, and `_alpha.html` symlinks (or real bytes when a channel has active dev) get updated whenever the relevant channel advances upstream — expect them to change. The build label rendered on the tool page tells you exactly which build you're seeing (`v-{alpha,beta} · · ` for channel mirrors, `v` for pinned stables). ## Auditing what's installed Every stub contains a `fallback` (level-1) or `upstream` (level-2) constant. To see what each tool / project on the deployment points at: ```sh grep -rn "fallback\|upstream" ``` ## CORS prerequisite (level-2 only) A level-2 fetch is cross-origin (deployment → `zddc.varasys.io`). The upstream must serve `Access-Control-Allow-Origin: *` (or a list including your deployment origin) on each released asset. Verify with: ```sh curl -I https://zddc.varasys.io/releases/archive_stable.html | grep -i access-control curl -I https://zddc.varasys.io/releases/archive_v0.0.2.html | grep -i access-control ``` Level-1 fetches are same-origin so no CORS is involved. ## Templates `level1.html.tmpl` and `level2.html.tmpl` are the source of truth. The project's top-level `build.sh` substitutes `{{TOOL}}`, `{{TOOL_TITLE}}`, `{{CHANNEL}}`, and `{{FAVICON}}` to produce the per-tool stubs published under `website/bootstrap/level1/` and `website/bootstrap/track-/`, which the install snippets curl from `https://zddc.varasys.io/bootstrap/`.