ZDDC/bootstrap
ZDDC 7365e94cac docs: align with simplified release model
Updates to all six top-level docs to describe the new flow:

- Storage: HTML tools live in website/releases/ as committed static
  files. Per-version files are real bytes; partial-version pins and
  channel mirrors are checked-in symlinks. No manifest.json, no Codeberg
  indirection, no Caddy regex-rewrite.
- URL scheme: <tool>_v<X.Y.Z>.html (exact), <tool>_v<X.Y>.html (latest
  patch), <tool>_v<X>.html (latest minor), <tool>_<channel>.html
  (channel mirror). All resolve via the symlink chain.
- Cascade rule: stable cut → beta + alpha symlinks reset to stable;
  beta cut → alpha resets to beta. Channels are never stale.
- No -alpha.N / -beta.N counter tags. Channel URLs are stable URLs by
  design; counters defeat that. The on-page <date> · <sha> label is
  enough for traceability.
- bootstrap/install.sh is the canonical install path. The four hand-
  rolled snippets are gone; one script handles all three deployment
  patterns + both target shapes.
- Helm charts under helm/ (zddc-server-{prod,dev}/) build from source
  via init container; documented as the recommended k8s deployment
  path.
- zddc-server now publishes binaries on stable cuts only — no alpha/
  beta channel for binaries. Active dev runs through the dev helm chart
  which builds from source on each rollout.

Files updated:

- CLAUDE.md — Repo shape, Most-used commands, Things that bite if you
  forget. Drops mentions of manifest.json, the Codeberg-as-canonical
  model, and -alpha.N/-beta.N tags.
- AGENTS.md — website/ tree, Releasing — channels and layout, Channel
  discipline rules (renumbered to add coordinated minor/major bump
  rule), Freshen helper, Bootstrap stubs, zddc-server Release tagging.
- ARCHITECTURE.md — website/ tree, build.sh step 5, Channels section,
  level-2 bootstrap description.
- README.md — tool publishing description, link to helm/.
- bootstrap/README.md — install path is install.sh now; pin URL table
  uses static symlinks; CORS check uses release-asset URLs (not
  manifest.json).
- zddc/README.md — Quick Start uses Codeberg URLs directly (no proxy);
  Release tagging is stable-only; Distribution / Versioning sections
  rewritten.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 09:56:34 -05:00
..
install.sh feat: unified bootstrap/install.sh replaces 4 hand-rolled install snippets 2026-04-30 09:44:13 -05:00
level1.html.tmpl feat(tools,build): in-flight HTML-tool reworks and build-infra updates 2026-04-29 12:52:27 -05:00
level2.html.tmpl refactor: HTML tools live in website/releases/ as static files + symlink hierarchy 2026-04-30 09:40:16 -05:00
README.md docs: align with simplified release model 2026-04-30 09:56:34 -05:00

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 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 -c "$(curl -fsSL https://zddc.varasys.io/install.sh)" -- [options]

The published stubs live under https://zddc.varasys.io/bootstrap/:

  • bootstrap/level1/<tool>.html — same-origin level-1 stubs (4 tools, no landing — landing only lives at deployment root).
  • bootstrap/track-{stable,beta,alpha}/<tool>.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:

<ZDDC_ROOT>/
  index.html                # landing tool (or bootstrap)
  archive.html              # archive tool (or bootstrap; site-wide channel switch lives here)
  transmittal.html
  classifier.html
  mdedit.html
  <project-A>/
    archive.html            # level-1 bootstrap → fetches ../archive.html
    transmittal.html
    classifier.html
    mdedit.html
    <project files…>
  <project-B>/
    archive.html            # level-1 bootstrap (or pinned to a specific version)
    …
  • Level-1 stubs at <project>/<tool>.html always fetch the same-origin ../<tool>.html. They never touch zddc.varasys.io. Install them once; they don't need to change.
  • At deployment root (<ZDDC_ROOT>/<tool>.html), put either:
    • the actual built tool HTML — fully self-contained install, no external dependencies; or
    • a level-2 bootstrap — fetches <source>/releases/<tool>_<channel>.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 <name> — that overwrites the root <tool>.html files with the matching level-2 stubs. A single project can override one tool by editing just <project-X>/<tool>.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 <source>/releases/<tool>_<channel>.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/<tool>_vX.Y.Z.html
Latest patch within <X.Y>.* https://zddc.varasys.io/releases/<tool>_v<X.Y>.html (symlink)
Latest within <X>.*.* https://zddc.varasys.io/releases/<tool>_v<X>.html (symlink)
Track stable channel (default) https://zddc.varasys.io/releases/<tool>_stable.html (symlink)
Track beta / alpha channel https://zddc.varasys.io/releases/<tool>_<channel>.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) <tool>_v0.0.4.html (exact)
?v=0.0 (or ?v=v0.0) <tool>_v0.0.html (latest 0.0.x patch — symlink)
?v=0 (or ?v=v0) <tool>_v0.html (latest 0.x — symlink)
?v=stable <tool>_stable.html
?v=beta <tool>_beta.html
?v=alpha <tool>_alpha.html
(omitted) the default channel baked into the stub at install time

When level-1 has ?v=…, it tries ../<tool>_<suffix>.html first (useful when the admin has staged specific versions locally — the upstream's symlink layout works the same locally) and falls back to ../<tool>.html if 404 — which then forwards the parameter via level-2 if one is installed.

Stable per-version files are immutable. The <tool>_stable.html, <tool>_beta.html, and <tool>_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<next-stable>-{alpha,beta} · <date> · <sha> for channel mirrors, v<X.Y.Z> 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:

grep -rn "fallback\|upstream" <ZDDC_ROOT>

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:

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-<channel>/, which the install snippets curl from https://zddc.varasys.io/bootstrap/.