From 7570fb7494384a0abff78c973b4fc7e566228e33 Mon Sep 17 00:00:00 2001 From: ZDDC Date: Sat, 2 May 2026 09:14:40 -0500 Subject: [PATCH] refactor: separate website repo + deploy-host model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Migrates from in-repo orphan `website` branch + LFS to a two-repo + deploy-host model so source editing is fully decoupled from live state. - Source code stays here (codeberg.org/VARASYS/ZDDC). - Hand-edited website content moves to a separate Codeberg repo (codeberg.org/VARASYS/ZDDC-website, cloned at ~/src/zddc-website/). - Live site is /srv/zddc/ on the deploy host (Caddy bind-mount), populated by ./deploy from this repo's dist/release-output/ plus ~/src/zddc-website/. - Releases are no longer in any git history — reproducible from -vX.Y.Z tags via `./build release X.Y.Z`. No LFS, no Codeberg release assets. Build/deploy split: - ./build (no arg) is source-only; nothing in dist/release-output/ or /srv/zddc/ is touched. - ./build alpha|beta|release seeds dist/release-output/ from /srv/zddc/releases/ (preserving symlinks), then mutates the channel(s) being cut on top. The bundle is always a complete intended-live snapshot, so the verifier sees a complete world and ./deploy --releases (rsync --delete-after) replaces live state cleanly. - New ./deploy wraps the rsync flow with --content / --releases subcommands. Docs updated to reflect the new model: CLAUDE.md, AGENTS.md, ARCHITECTURE.md, zddc/README.md, README.md, .gitignore, shared/ build-lib.sh comments, deprecated zddc/release.sh message. Co-Authored-By: Claude Opus 4.7 (1M context) --- .gitignore | 26 +++--- AGENTS.md | 90 +++++++++++-------- ARCHITECTURE.md | 71 ++++++++------- CLAUDE.md | 27 ++++-- README.md | 2 +- build | 79 +++++++++++------ deploy | 91 ++++++++++++++++++++ freshen-channel | 12 ++- mdedit/dist/mdedit.html | 2 +- shared/build-lib.sh | 62 +++++++------ zddc/README.md | 24 +++--- zddc/internal/apps/embedded/archive.html | 2 +- zddc/internal/apps/embedded/classifier.html | 2 +- zddc/internal/apps/embedded/index.html | 2 +- zddc/internal/apps/embedded/mdedit.html | 2 +- zddc/internal/apps/embedded/transmittal.html | 2 +- zddc/internal/apps/embedded/versions.txt | 10 +-- zddc/release.sh | 30 +++---- 18 files changed, 349 insertions(+), 187 deletions(-) create mode 100755 deploy diff --git a/.gitignore b/.gitignore index 321abef..eec5842 100644 --- a/.gitignore +++ b/.gitignore @@ -16,22 +16,20 @@ node_modules/ playwright-report/ test-results/ -# Build artifacts -# NOTE: dist/ is listed here but each tool's dist/*.html is force-tracked in git -# (added with `git add -f tool/dist/tool.html`). This is intentional — built artifacts -# are committed alongside source so users can download them directly from the repo. -# New tool dist files must be force-added: git add -f tool/dist/tool.html +# Build artifacts. dist/ is ignored everywhere: per-tool dist/.html +# is a transient build output (and the canonical thing tests open via +# file://), and dist/release-output/ is the local-only release bundle +# produced by `./build alpha|beta|release`, then rsync'd to the live +# site by `./deploy`. Nothing in dist/ should be committed. +# +# Hand-edited website content (index.html, reference.html, css/, js/, +# img/) lives in a SEPARATE Codeberg repo at codeberg.org/VARASYS/ +# ZDDC-website, typically cloned at ~/src/zddc-website/. Release +# artifacts are NOT in git history at all — they're produced by this +# repo's build, rsync'd to /srv/zddc/releases/ on the deploy host, +# and reproducible from any -vX.Y.Z tag. dist/ -# The website (hand-edited index.html / reference.html / css/ / js/ / img/ -# plus all release artifacts) lives in the orphan `website` branch of this -# same Codeberg repo. A `git worktree` of that branch is typically checked -# out at ~/src/zddc-website/ and is what the system Caddy serves at -# zddc.varasys.io. The lockstep build pipeline writes release artifacts -# directly to ~/src/zddc-website/releases/ (override with -# $ZDDC_DEPLOY_RELEASES_DIR). zddc-server binaries are LFS-tracked on -# the website branch; HTML tools + symlinks stay in regular git. - # IDE and project files .opencode/ opencode.json diff --git a/AGENTS.md b/AGENTS.md index 9147894..a1ee9d6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -5,12 +5,12 @@ ```bash # ── ./build subcommands ──────────────────────────────────────────────────── # `./build` (no arg) is a source-side dev build only — assembles tool/dist/ -# + cross-compiles zddc-server. The website worktree is left alone. -# Channel + release subcommands deploy artifacts to the website worktree -# under $ZDDC_DEPLOY_RELEASES_DIR (default ~/src/zddc-website/releases). +# + cross-compiles zddc-server. dist/release-output/ and the live site are +# left alone. Channel + release subcommands produce a complete release +# bundle in dist/release-output/ (gitignored). Run `./deploy` to publish. # Workflow: alpha = active dev → beta = ready for testing → release = ship. -./build # dev build (no website worktree write) +./build # dev build (no release bundle) ./build alpha # cut alpha (cascades nothing) ./build beta # cut beta (cascades alpha → beta) ./build release # cut stable, coordinated next version @@ -18,7 +18,15 @@ ./build release 1.2.0 # cut stable at explicit version ./build help -# Single-tool dev build for testing (does NOT touch the website worktree): +# ── ./deploy subcommands ──────────────────────────────────────────────────── +# rsync the build output and content repo to /srv/zddc/ (Caddy's bind-mount). +# --delete-after — the live tree exactly mirrors source. + +./deploy # full sync (content + releases) +./deploy --content # only ~/src/zddc-website/ → /srv/zddc/ +./deploy --releases # only dist/release-output/ → /srv/zddc/releases/ + +# Single-tool dev build for testing (does NOT touch dist/release-output/): sh tool/build.sh # archive|transmittal|classifier|mdedit|landing # Single-tool release (rare; prefer ./build alpha|beta|release so versions @@ -39,13 +47,16 @@ npx playwright test tool # archive | transmittal | classifier | mded No lint, typecheck, or format commands exist — the project is plain sh + vanilla JS. +Channel/release cuts seed `dist/release-output/` from the current +`/srv/zddc/releases/` (preserving symlinks) before running per-tool +promote, then mutate the channels being cut on top. The bundle is +therefore always a complete intended-live snapshot, not a sparse diff. The build ends with a **channel-link verifier** that asserts every `_{stable,beta,alpha}.html` (and zddc-server's per-platform binary -mirrors + stub pages) resolves. Build fails if any link is dangling. -Output goes to `${ZDDC_DEPLOY_RELEASES_DIR:-$HOME/src/zddc-website/releases}` -— the website branch's worktree, what Caddy serves. **Nothing is -pushed automatically;** review with `git -C ~/src/zddc-website status`, -commit + push the website branch yourself when ready. +mirrors + stub pages) resolves. Build fails if any link is dangling — +because the bundle is complete, dangling-link errors mean a real bug. +**Nothing is pushed automatically.** Run `./deploy` to publish; commit ++ push source changes to `main` separately. ## Architecture @@ -68,19 +79,26 @@ shared/ build-lib.sh POSIX sh helpers (ensure_exists, concat_files, build_timestamp) sourced by every tool's build.sh via: . "$root_dir/../shared/build-lib.sh" -# Website lives on the `website` orphan branch of this same repo -# (NOT in main's tree). Worktree typically at ~/src/zddc-website/: +# Hand-edited website content lives in a SEPARATE Codeberg repo +# (codeberg.org/VARASYS/ZDDC-website), typically cloned at +# ~/src/zddc-website/. Just content — no releases, no LFS: # index.html, reference.html, css/, js/, img/ hand-edited content -# releases/ -# index.html regenerated by `./build` -# _v.html per-version (committed, immutable) -# _v.html -> ... symlink chain (regular git symlinks) -# _stable.html -> ... channel mirror, follows latest stable -# _{beta,alpha}.html -> ... channels (cascade to stable when idle) -# zddc-server_v_ per-platform binary (LFS-tracked) -# zddc-server__ channel binary mirror (symlink) -# zddc-server_.html stub page surfacing 4 platform DLs -# .gitattributes LFS rules for binaries +# README.md, LICENSE repo housekeeping +# +# This repo's ./build produces a release bundle in dist/release-output/ +# (gitignored, local-only). ./deploy rsyncs both into /srv/zddc/ on +# the deploy host (Caddy's bind-mount): +# /srv/zddc/ +# index.html, reference.html, css/, js/, img/ ← from ~/src/zddc-website +# releases/ +# index.html regenerated by `./build` +# _v.html per-version (immutable) +# _v.html -> ... symlink chain +# _stable.html -> ... channel mirror, follows latest stable +# _{beta,alpha}.html -> ... channels (cascade to stable when idle) +# zddc-server_v_ per-platform binary (raw bytes, no LFS) +# zddc-server__ channel binary mirror (symlink) +# zddc-server_.html stub page surfacing 4 platform DLs helm/ zddc-server-prod/ production-shaped Helm chart (compiles from source via init container) @@ -88,9 +106,9 @@ helm/ README.md chart design rationale + quick-start ``` -**Critical:** `dist/` files are gitignored. They're the canonical built artifact for testing and the source for `--release` writes into `~/src/zddc-website/releases/`, but they aren't checked in. Never edit them directly. +**Critical:** `dist/` files are gitignored. `tool/dist/.html` is the canonical built artifact for testing and the source for `--release` writes into `dist/release-output/`. `dist/release-output/` is the local-only release bundle. Neither is in git. Never edit them directly. -**Release artifacts live on the `website` orphan branch** of this same Codeberg repo, not on `main`. A `git worktree` of that branch — typically at `~/src/zddc-website/` — is what the system Caddy bind-mounts and serves at `zddc.varasys.io/`. The build pipeline writes its release outputs to `${ZDDC_DEPLOY_RELEASES_DIR:-$HOME/src/zddc-website/releases}` directly, then the operator commits + pushes that worktree separately from `main`. Per-version HTML and per-version zddc-server binaries are real bytes (binaries are LFS-tracked; HTML stays regular git); partial-version pins (`_v`, `_v`) and channel mirrors (`_stable`, `_beta`, `_alpha`) are symlinks. `shared/build-lib.sh` provides `promote_release` (HTML tools) and `promote_zddc_server` (binaries + matching stub pages); the top-level `./build` calls them in lockstep. No Codeberg release-asset publication anymore; everything serves from `zddc.varasys.io/releases/`. +**Two-repo + deploy-host model.** Source code lives here (`codeberg.org/VARASYS/ZDDC`); hand-edited website content lives in a separate repo (`codeberg.org/VARASYS/ZDDC-website`, typically cloned at `~/src/zddc-website/`). The live site at `zddc.varasys.io` is `/srv/zddc/` on the deploy host (Caddy bind-mount), populated by `./deploy`. Release artifacts are NOT in git — they're produced by `./build alpha|beta|release` into `dist/release-output/` and rsync'd to `/srv/zddc/releases/` by `./deploy --releases`. Per-version files (HTML and zddc-server binaries) are real immutable bytes; partial-version pins (`_v`, `_v`) and channel mirrors (`_stable`, `_beta`, `_alpha`) are symlinks. `shared/build-lib.sh` provides `promote_release` (HTML tools) and `promote_zddc_server` (binaries + matching stub pages); the top-level `./build` seeds from live state, then calls them in lockstep. Older releases are reproducible from any `-vX.Y.Z` tag in this repo (`git checkout zddc-server-v0.0.8 && ./build release 0.0.8`). No Codeberg release assets, no LFS. ## Shared CSS (`shared/base.css`) @@ -175,14 +193,15 @@ Format: `trackingNumber_revision (status) - title.extension` - Feature-branch workflow; squash-merge feature branches to `main` - Conventional commits: `feat(archive): ...`, `fix(transmittal): ...` - Release tags: `-v` per tool, all six sharing the same X.Y.Z on a coordinated cut (e.g. `archive-v0.0.8`, `transmittal-v0.0.8`, `classifier-v0.0.8`, `mdedit-v0.0.8`, `landing-v0.0.8`, `zddc-server-v0.0.8`) -- Commit dist files: `git add -f tool/dist/tool.html` -- Commit zddc-server binaries (per-version + symlinks) on the `website` branch's worktree (`~/src/zddc-website/releases/`) — they're LFS-tracked there alongside the HTML tool releases. Push that branch separately from `main` +- `dist/` is gitignored. Build artifacts (per-tool `dist/.html` and `dist/release-output/`) are NOT committed to this repo. Reproduce them from a tag with `./build release X.Y.Z` +- Hand-edited website content lives in a separate Codeberg repo (`codeberg.org/VARASYS/ZDDC-website`, cloned at `~/src/zddc-website/`). Source-code commits go to `main` here; content commits go to that repo +- Release artifacts live on the deploy host (`/srv/zddc/`), not in any git history. Use `./deploy` to publish ### Releasing — lockstep, channels, layout **Lockstep convention.** Every release cut bumps all six artifacts (5 HTML tools + zddc-server) to the same version, even if a tool didn't change. Per-tool independent versions are gone. The coordinated next-stable target is `max(latest tag across all six tools) + 1` — `_coordinated_next_stable` in `shared/build-lib.sh`. Channel cuts (alpha/beta) follow the same lockstep — every tool's channel mirror is overwritten in step. Three channels, ordered: **alpha** (dev iteration) → **beta** (general testing) → **stable** (ship). -**Storage model.** All release artifacts live under the `website` orphan branch of this repo (worktree typically at `~/src/zddc-website/releases/`) and are served from `zddc.varasys.io/releases/`. The `website` branch's history is independent of `main`. No Codeberg release assets, no third-party mirrors. +**Storage model.** All release artifacts live on the deploy host at `/srv/zddc/releases/` (Caddy bind-mount, served as `https://zddc.varasys.io/releases/`). Locally they materialize in this repo's `dist/release-output/` (gitignored) when `./build alpha|beta|release` runs; `./deploy` rsyncs them out. **No git history holds release artifacts** — older versions are reproducible from any `-vX.Y.Z` tag (`git checkout zddc-server-v0.0.8 && ./build release 0.0.8`). No Codeberg release assets, no LFS, no third-party mirrors. | Artifact | Type | Layout | |---|---|---| @@ -194,12 +213,12 @@ Format: `trackingNumber_revision (status) - title.extension` | `zddc-server_.html` | generated stub page | per-version / per-channel; lists the four platform downloads. This is what the matrix-cell link points at — one stub fans out to four binaries | | `index.html` | regenerated by `build.sh` | matrix table, one column per tool, one row per release | -**Single point of truth.** `./build release` is the canonical lockstep cut. It forwards each HTML tool's build with the agreed version, then `promote_zddc_server` (in `shared/build-lib.sh`) copies the freshly cross-compiled binaries into `~/src/zddc-website/releases/` with the matching symlink chain, then `write_zddc_server_stubs_all` regenerates every stub page, then `build_releases_index` rewrites the matrix, then `verify_channel_links` asserts nothing dangles. +**Single point of truth.** `./build release` is the canonical lockstep cut. It seeds `dist/release-output/` from `/srv/zddc/releases/` (so cascades and the verifier see a complete world), forwards each HTML tool's build with the agreed version, then `promote_zddc_server` (in `shared/build-lib.sh`) copies the freshly cross-compiled binaries into `dist/release-output/` with the matching symlink chain, then `write_zddc_server_stubs_all` regenerates every stub page, then `build_releases_index` rewrites the index, then `verify_channel_links` asserts nothing dangles. `./deploy --releases` then publishes the bundle. - **Stable** (`./build release` or `--release X.Y.Z`): Writes per-version HTML for the five HTML tools + per-version binaries for zddc-server (real bytes, immutable). Refreshes 5 symlinks per HTML tool + 5 symlinks per zddc-server platform → the new version. Tags all six: `-v`. Cascade: stable cut means beta and alpha both reset to stable for every tool. Skips silently if source for an HTML tool hasn't changed since the latest stable tag (the binary always builds). - **Beta** (`./build beta`): Overwrites `_beta.html` with dist bytes for each HTML tool, and `zddc-server_beta_` with each platform's binary. Cascade: `_alpha.html` → `_beta.html` and `zddc-server_alpha_` → `zddc-server_beta_` (symlinks). No tag. - **Alpha** (`./build`): Overwrites only the alpha mirrors, all six tools. No tag, no other side-effects. -- **Plain dev builds** (no `--release`): produce `tool/dist/.html` for HTML tools and `zddc/dist/zddc-server-` binaries; do NOT touch `~/src/zddc-website/releases/`. The matrix index and stub pages still get regenerated from whatever `~/src/zddc-website/releases/` contains, so the build is idempotent for repeated dev runs. +- **Plain dev builds** (`./build` with no arg): produce `tool/dist/.html` for HTML tools and `zddc/dist/zddc-server-` binaries; do NOT touch `dist/release-output/` or the live site. Use it to iterate without affecting deployable state. On-page `{{BUILD_LABEL}}` format (HTML tools only — zddc-server's version comes from the binary itself): @@ -304,7 +323,7 @@ zddc-server ships as a cross-compiled binary, not a container image. There's no (cd zddc && go run ./cmd/zddc-server) ``` -The repo's top-level `./build` cross-compiles the four release binaries (linux/amd64, darwin/amd64, darwin/arm64, windows/amd64) into `zddc/dist/` via a containerized Go toolchain (podman or docker). On `--release` it also promotes those binaries to `~/src/zddc-website/releases/` with the matching symlink chain and stub pages — same lockstep flow as the HTML tools. +The repo's top-level `./build` cross-compiles the four release binaries (linux/amd64, darwin/amd64, darwin/arm64, windows/amd64) into `zddc/dist/` via a containerized Go toolchain (podman or docker). On `./build alpha|beta|release` it also promotes those binaries to `dist/release-output/` with the matching symlink chain and stub pages — same lockstep flow as the HTML tools. `./deploy` rsyncs the bundle to `/srv/zddc/releases/`. ### Run (development) @@ -335,20 +354,21 @@ ZDDC_ROOT=/path/to/your/archive ZDDC_TLS_CERT=none ZDDC_ADDR=:8080 \ ### Release tagging -zddc-server has no separate release script anymore. The top-level `./build release [version|alpha|beta]` is the canonical path: it cross-compiles the binaries inside the containerized Go toolchain, copies them into `~/src/zddc-website/releases/` with the lockstep symlink chain (one set of symlinks per platform), regenerates the per-version + per-channel stub pages, refreshes the matrix, and tags `zddc-server-v` alongside the five HTML-tool tags. +zddc-server has no separate release script. The top-level `./build alpha|beta|release [version]` is the canonical path: it cross-compiles the binaries inside the containerized Go toolchain, copies them into `dist/release-output/` with the lockstep symlink chain (one set of symlinks per platform), regenerates the per-version + per-channel stub pages, refreshes the index, and (on stable) tags `zddc-server-v` alongside the five HTML-tool tags. ```sh ./build release # lockstep stable, coordinated next version ./build release 1.2.0 # lockstep stable, explicit version -./build # lockstep alpha cut for everything -./build beta # lockstep beta cut for everything +./build alpha # lockstep alpha cut for everything +./build beta # lockstep beta cut for everything +./deploy --releases # publish the bundle to /srv/zddc/releases/ ``` -The script tags every tool but does NOT push — finish with `git push origin main && git push origin --tags`. +The script tags every tool but does NOT push — finish with `git push origin main && git push origin --tags` (and run `./deploy` to put the artifacts on the live site). **Versioning** — clean semver. Stable cuts emit one `-vX.Y.Z` tag per tool, all six sharing the same X.Y.Z. No `-alpha.N` / `-beta.N` counter tags — channel URLs are stable URLs by design. Historical per-tool independent tags (`archive-v0.0.2`, `zddc-server-v0.0.7`, etc.) stay as artifacts; the next coordinated cut jumps every tool to the same number. -**Binary distribution** — `website/releases/zddc-server__` are real static files served from `zddc.varasys.io/releases/`. No Codeberg release assets, no `$CODEBERG_TOKEN`, no third-party mirror. The matrix-cell link points at `zddc-server_.html`, a generated stub page that surfaces the four platform downloads in one click. +**Binary distribution** — `/srv/zddc/releases/zddc-server__` (on the deploy host) are real static files served from `zddc.varasys.io/releases/`. No Codeberg release assets, no `$CODEBERG_TOKEN`, no third-party mirror, no LFS. The matrix-cell link points at `zddc-server_.html`, a generated stub page that surfaces the four platform downloads in one click. There is no CI for this — solo workflow benefits from one canonical local path that fails loudly and visibly on the developer's terminal. diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 276801c..8959c8d 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -33,36 +33,42 @@ tool/ tool.html # Generated output — never edit this manually ``` -Website files (what `zddc.varasys.io` serves) live on the **`website` orphan branch** of this same Codeberg repo, separate from `main`. A `git worktree` of that branch — typically at `~/src/zddc-website/` — is what the system Caddy bind-mounts and serves. The build pipeline writes release artifacts directly to that worktree's `releases/` subdir: +Website files (what `zddc.varasys.io` serves) live on a **separate Codeberg repo** (`codeberg.org/VARASYS/ZDDC-website`, typically cloned at `~/src/zddc-website/`) for hand-edited content, plus the **deploy host's `/srv/zddc/`** for the assembled live site. The system Caddy bind-mounts `/srv/zddc/`. `./deploy` rsyncs both into it. ``` -~/src/zddc-website/ (git worktree of `website` branch) +~/src/zddc-website/ (clone of codeberg.org/VARASYS/ZDDC-website) index.html # hand-edited intro page + install snippets (root URL) reference.html # hand-edited file-naming convention spec css/, js/, img/ # hand-edited static assets - .gitattributes # LFS rules: zddc-server_*-{amd64,arm64,*.exe} - releases/ - index.html # matrix-style download page, regenerated by build.sh - _v.html # real per-version HTML (committed, immutable) - _v.html → ... # symlink: latest patch within X.Y.* - _v.html → ... # symlink: latest within X.*.* - _stable.html → ... # symlink: current stable HTML - _beta.html → ... # symlink to stable (or real bytes when active beta dev) - _alpha.html → ... # symlink to beta/stable (or real bytes when active alpha dev) - zddc-server_v_ # real per-version cross-compiled binary (LFS-tracked) - zddc-server_v_ → ... # symlink chain (mirrors the HTML cascade per platform) - zddc-server_v_ → ... - zddc-server__ → ... # channel mirror per platform - zddc-server_.html # generated stub: matrix-cell link → fans out 4 platform downloads + README.md, LICENSE # repo housekeeping + # NO releases/ — release artifacts are NOT in any git history. + +~/src/zddc/dist/release-output/ (gitignored, produced by ./build alpha|beta|release) + index.html # download page, regenerated by build + _v.html # real per-version HTML (immutable) + _v.html → ... # symlink: latest patch within X.Y.* + _v.html → ... # symlink: latest within X.*.* + _stable.html → ... # symlink: current stable HTML + _beta.html → ... # symlink to stable (or real bytes when active beta dev) + _alpha.html → ... # symlink to beta/stable (or real bytes when active alpha dev) + zddc-server_v_ # real per-version cross-compiled binary (raw bytes, no LFS) + zddc-server_v_ → ... # symlink chain (mirrors the HTML cascade per platform) + zddc-server_v_ → ... + zddc-server__ → ... # channel mirror per platform + zddc-server_.html # generated stub: cell link → fans out 4 platform downloads + +/srv/zddc/ (deploy host; Caddy bind-mount) + index.html, reference.html, css/, js/, img/ ← rsync'd from ~/src/zddc-website/ + releases/ ← rsync'd from ~/src/zddc/dist/release-output/ ``` `` ∈ {archive, transmittal, classifier, mdedit, landing}. `` ∈ {linux-amd64, darwin-amd64, darwin-arm64, windows-amd64.exe}. Every URL under `/releases/` resolves directly via the symlink chain — no `manifest.json`, no Caddy regex-rewrite, no JavaScript indirection, no third-party mirror. Caddy serves these as plain static files. The Docker-tag pattern: `:1.2.3` is pinned, `:1.2` floats, `:1` floats further, `:stable` floats furthest, and `:beta` / `:alpha` are mutable channel mirrors that overwrite in place. -**zddc-server binaries live in this repo too** — committed under `~/src/zddc-website/releases/`, served from `zddc.varasys.io/releases/`. No Codeberg release assets, no separate distribution channel. The `helm/zddc-server-{prod,dev}/` charts build from source via init container, but operators who want a prebuilt binary just `curl -O https://zddc.varasys.io/releases/zddc-server_stable_linux-amd64`. The single matrix-cell link per release points at `zddc-server_.html`, a small generated stub that surfaces all four platform downloads. +**zddc-server binaries are reproducible from a tag, not in git** — `./build alpha|beta|release` cross-compiles them into `dist/release-output/`, `./deploy` rsyncs them to `/srv/zddc/releases/`, Caddy serves from there. Older versions: `git checkout zddc-server-v0.0.8 && ./build release 0.0.8`. The `helm/zddc-server-{prod,dev}/` charts build from source via init container, but operators who want a prebuilt binary just `curl -O https://zddc.varasys.io/releases/zddc-server_stable_linux-amd64`. The single cell link per release points at `zddc-server_.html`, a small generated stub that surfaces all four platform downloads. -There is no `website/dev/`. To preview a build locally, open `dist/tool.html` directly via the dev server. To publish on `zddc.varasys.io`, cut a release. +To preview a build locally, open `dist/tool.html` directly via the dev server. To publish on `zddc.varasys.io`, cut a release with `./build alpha|beta|release` and then `./deploy`. Vendor dependencies (bundled third-party libraries) live in `tool/vendor/` if present. The build script is responsible for inlining them into the output. @@ -74,16 +80,16 @@ Each topic has exactly one authoritative home; everything else links to it. | Topic | Single home | Linked from | |---|---|---| -| What ZDDC is + tool channel links + dual-mode (local/server) overview + install snippets | `website/index.html` (hand-edited intro for `zddc.varasys.io/`) | repo `README.md`, `zddc/README.md` | -| File-naming convention spec (status codes, modifiers, folder format) | `website/reference.html` | repo `README.md`, in-tool help text | -| Versions + channel builds index of every tool | `~/src/zddc-website/releases/index.html` (regenerated by `build.sh`) | website intro nav, "Browse all versions" link | +| What ZDDC is + tool channel links + dual-mode (local/server) overview + install snippets | `~/src/zddc-website/index.html` (hand-edited intro for `zddc.varasys.io/`, in the `ZDDC-website` repo) | repo `README.md`, `zddc/README.md` | +| File-naming convention spec (status codes, modifiers, folder format) | `~/src/zddc-website/reference.html` | repo `README.md`, in-tool help text | +| Versions + channel builds index of every tool | `dist/release-output/index.html` (regenerated by `./build`; deployed to `/srv/zddc/releases/index.html`) | website intro nav, "Browse all versions" link | | Customer-deployment install (`zddc-server` binary embeds current-stable tools; `.zddc apps:` cascade overrides; cache at `/_app/`) | `zddc/README.md` "Apps: virtual tool HTMLs" section | website intro, `AGENTS.md` | | zddc-server operations: env vars, ACL syntax, `.archive` URLs, container vs binary | `zddc/README.md` | `AGENTS.md`, website intro | | Build / release / channel commands | `AGENTS.md` | repo `README.md` ("see AGENTS.md") | | Architecture & internal patterns | `ARCHITECTURE.md` (this file) | `AGENTS.md` | | Per-tool internal design quirks | `/README.md` | (linked from website intro tool cards) | -`index.html` on the `website` branch (working dir `~/src/zddc-website/index.html`) is **hand-edited static content** (analogous to `reference.html`), not the landing-tool output. The install section points operators at two paths: **local** (download a `.html` file from `/releases/`) and **server** (run `zddc-server`; current-stable builds of all five tools are baked into the binary at compile time via `//go:embed`). The landing tool's released bytes live at `~/src/zddc-website/releases/landing_v.html`; the embedded copy serves at the deployment root by default. The public website at `zddc.varasys.io/` is the same hand-edited `index.html` — its root URL is the introduction page, not the project picker (because there are no projects to pick from a static site). +`index.html` in the `ZDDC-website` repo (working dir `~/src/zddc-website/index.html`) is **hand-edited static content** (analogous to `reference.html`), not the landing-tool output. The install section points operators at two paths: **local** (download a `.html` file from `/releases/`) and **server** (run `zddc-server`; current-stable builds of all five tools are baked into the binary at compile time via `//go:embed`). The landing tool's released bytes live at `/srv/zddc/releases/landing_v.html` (rsync'd from `dist/release-output/`); the embedded copy serves at the deployment root by default. The public website at `zddc.varasys.io/` is the same hand-edited `index.html` — its root URL is the introduction page, not the project picker (because there are no projects to pick from a static site). When updating documentation, prefer linking over duplicating. If you find yourself rewriting the file-naming convention in a tool's README, link to `reference.html` instead. @@ -99,16 +105,19 @@ Each HTML tool's `build.sh`: 2. Reads JS files in declaration order, concatenates them 3. Processes `template.html` with `awk`, replacing `{{PLACEHOLDER}}` markers with the concatenated content and stripping CDN `