docs: rewrite for embedded + cascade install model
Updates every repo doc to reflect the simplified install model:
- Local install is just a download from /releases/.
- Server install is just running zddc-server (current-stable HTMLs
embedded at compile time).
- Customize via .zddc apps: cascade entries (channel/version/URL/path,
with default + per-app composition); editor at /.profile/zddc/.
Removes references to the old install scripts, level-1/level-2 stubs,
admin UI at /.profile/apps, SHA-256 verification, TOFU writes, refresh
worker, and ZDDC_APPS_* env vars.
zddc/README.md: replaces "Landing Page and Tool Install" section with
"Apps: virtual tool HTMLs" — covers the folder-name availability rules,
the resolution chain (real-file override / cascade / embedded), spec
syntax cheat sheet, cache layout under <ZDDC_ROOT>/_app/, the ?v=
cache-only override, and the X-ZDDC-Source response header.
ARCHITECTURE.md: install-distribution-model section rewritten to
describe the embed-first / cascade-override model with one canonical
example.
AGENTS.md, CLAUDE.md: short-form summaries pointing at the same model.
README.md: install bullet rewritten.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7b764956bd
commit
adb6904397
5 changed files with 118 additions and 85 deletions
45
AGENTS.md
45
AGENTS.md
|
|
@ -3,7 +3,7 @@
|
||||||
## Commands
|
## Commands
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Build all tools (writes to dist/ only; also regenerates website/releases/index.html + bootstrap stubs)
|
# Build all tools (writes to dist/ only; also regenerates website/releases/index.html)
|
||||||
sh build.sh
|
sh build.sh
|
||||||
|
|
||||||
# Build single tool
|
# Build single tool
|
||||||
|
|
@ -55,8 +55,7 @@ shared/
|
||||||
sourced by every tool's build.sh via: . "$root_dir/../shared/build-lib.sh"
|
sourced by every tool's build.sh via: . "$root_dir/../shared/build-lib.sh"
|
||||||
|
|
||||||
website/
|
website/
|
||||||
index.html hand-edited intro page (root URL)
|
index.html hand-edited intro page + install snippets (root URL)
|
||||||
install.sh → ../bootstrap/install.sh symlink so the upstream serves /install.sh
|
|
||||||
releases/
|
releases/
|
||||||
index.html versions index, regenerated by build.sh from filesystem scan
|
index.html versions index, regenerated by build.sh from filesystem scan
|
||||||
<tool>_v<X.Y.Z>.html real per-version files (committed, immutable)
|
<tool>_v<X.Y.Z>.html real per-version files (committed, immutable)
|
||||||
|
|
@ -65,17 +64,6 @@ website/
|
||||||
<tool>_stable.html -> ... symlink: current stable
|
<tool>_stable.html -> ... symlink: current stable
|
||||||
<tool>_beta.html -> ... symlink to stable (or real bytes if active beta)
|
<tool>_beta.html -> ... symlink to stable (or real bytes if active beta)
|
||||||
<tool>_alpha.html -> ... symlink to beta/stable (or real bytes if active alpha)
|
<tool>_alpha.html -> ... symlink to beta/stable (or real bytes if active alpha)
|
||||||
bootstrap/
|
|
||||||
level1/<tool>.html same-origin level-1 stubs (4 tools, no landing)
|
|
||||||
track-stable/<tool>.html level-2 stubs that track the current-stable channel
|
|
||||||
track-alpha/<tool>.html level-2 stubs that track the alpha channel
|
|
||||||
track-beta/<tool>.html level-2 stubs that track the beta channel
|
|
||||||
|
|
||||||
bootstrap/
|
|
||||||
level1.html.tmpl per-project bootstrap template (relative ../<tool>.html)
|
|
||||||
level2.html.tmpl level-2 channel-tracking bootstrap template
|
|
||||||
install.sh unified bootstrap script (modes: copy / track; channels: stable/beta/alpha/<version>)
|
|
||||||
README.md install / channel / pin docs
|
|
||||||
|
|
||||||
helm/
|
helm/
|
||||||
zddc-server-prod/ production-shaped Helm chart (compiles from source via init container)
|
zddc-server-prod/ production-shaped Helm chart (compiles from source via init container)
|
||||||
|
|
@ -198,7 +186,7 @@ After cutting a stable release, `git push origin <tag>` to publish the tag. `git
|
||||||
|
|
||||||
No `$CODEBERG_TOKEN` is needed for HTML-tool releases — they never touch Codeberg. (`zddc/release.sh` for zddc-server stable cuts still requires it for binary uploads.)
|
No `$CODEBERG_TOKEN` is needed for HTML-tool releases — they never touch Codeberg. (`zddc/release.sh` for zddc-server stable cuts still requires it for binary uploads.)
|
||||||
|
|
||||||
`website/index.html` (the root URL of zddc.varasys.io) is **hand-edited static content**, not built by `landing/build.sh`. The landing tool's release file is `website/releases/landing_v<X.Y.Z>.html`; the unified install script (`bootstrap/install.sh`) curls the chosen channel's `landing_<channel>.html` to `<deployment-root>/index.html` at customer-deployment time.
|
`website/index.html` (the root URL of zddc.varasys.io) is **hand-edited static content**, not built by `landing/build.sh`. Its "Install on your server" section points operators at two paths: local download (per-tool links to `/releases/`) and `zddc-server` install (the binary has the current-stable build of every tool baked in via `//go:embed`). The landing tool's release file is `website/releases/landing_v<X.Y.Z>.html`; on a `zddc-server` deployment, the embedded copy is served at the root URL by default, with operators able to override via `.zddc apps:` entries or by dropping a real `index.html`.
|
||||||
|
|
||||||
### Channel discipline (MUST rules)
|
### Channel discipline (MUST rules)
|
||||||
|
|
||||||
|
|
@ -207,7 +195,7 @@ The build system does not enforce these. Treating channels carelessly defeats th
|
||||||
1. **Stable doesn't regress.** No known-broken features that worked in the previous stable. If you ship `v0.0.5` with a bug, the path forward is `v0.0.6` with a fix — never edit a previously-published `<tool>_v0.0.5.html` in place. Stable per-version files are immutable.
|
1. **Stable doesn't regress.** No known-broken features that worked in the previous stable. If you ship `v0.0.5` with a bug, the path forward is `v0.0.6` with a fix — never edit a previously-published `<tool>_v0.0.5.html` in place. Stable per-version files are immutable.
|
||||||
2. **Coordinated minor/major bumps.** When any tool needs a minor or major bump, all five tools cut at the same time even if patches differ. Per-tool patches stay independent. This is a release-time process rule, not enforced by tooling.
|
2. **Coordinated minor/major bumps.** When any tool needs a minor or major bump, all five tools cut at the same time even if patches differ. Per-tool patches stay independent. This is a release-time process rule, not enforced by tooling.
|
||||||
3. **No backports.** Don't try to patch an older stable version. Always cut a new stable at a higher version. Users pinned to the old version stay pinned by choice; they can move forward when they want.
|
3. **No backports.** Don't try to patch an older stable version. Always cut a new stable at a higher version. Users pinned to the old version stay pinned by choice; they can move forward when they want.
|
||||||
4. **Alpha and beta are mutable.** Document this anywhere you invite users to test them. Pinning a deployment to a channel mirror means it gets rebuilt without notice. For something stable, pin to a per-version URL (`?v=0.0.5` or the `<tool>_v0.0.5.html` mirror).
|
4. **Alpha and beta are mutable.** Document this anywhere you invite users to test them. Pinning a deployment to a channel mirror means it gets rebuilt without notice. For something stable, pin to a per-version URL (the `<tool>_v0.0.5.html` file).
|
||||||
5. **Cascade is automatic.** A stable cut resets beta and alpha symlinks → stable. A beta cut resets alpha → beta. So "no active beta" silently shows current stable and "no active alpha" silently shows current beta. Operators don't need to run a freshen step after a stable release; the cascade handles it.
|
5. **Cascade is automatic.** A stable cut resets beta and alpha symlinks → stable. A beta cut resets alpha → beta. So "no active beta" silently shows current stable and "no active alpha" silently shows current beta. Operators don't need to run a freshen step after a stable release; the cascade handles it.
|
||||||
6. **Hotfix path.** For critical bugs: fix on `main`, cut a new stable. Tag the commit message `fix:` or include "hotfix" so intent is visible in `git log`.
|
6. **Hotfix path.** For critical bugs: fix on `main`, cut a new stable. Tag the commit message `fix:` or include "hotfix" so intent is visible in `git log`.
|
||||||
7. **Beta soak before promoting (recommended).** Give a beta a few days of exposure before cutting the same code as stable. Not enforced; use judgment for trivial changes.
|
7. **Beta soak before promoting (recommended).** Give a beta a few days of exposure before cutting the same code as stable. Not enforced; use judgment for trivial changes.
|
||||||
|
|
@ -230,16 +218,29 @@ What it does:
|
||||||
|
|
||||||
The build pipeline used is the one **at the tag**, not on `main`. That is intentional (pure reproducibility). If you have made build-system improvements since stable was cut and want the freshen to use them, cut a new stable first.
|
The build pipeline used is the one **at the tag**, not on `main`. That is intentional (pure reproducibility). If you have made build-system improvements since stable was cut and want the freshen to use them, cut a new stable first.
|
||||||
|
|
||||||
### Bootstrap stubs
|
### Install model
|
||||||
|
|
||||||
`build.sh` regenerates `website/bootstrap/` on every invocation:
|
No install script. Two paths:
|
||||||
|
|
||||||
- `bootstrap/level1/<tool>.html` — 4 same-origin level-1 stubs (archive, transmittal, classifier, mdedit; landing has no level-1 stub since it only lives at deployment root).
|
- **Local** — download a tool `.html` from `https://zddc.varasys.io/releases/` and open it. Done.
|
||||||
- `bootstrap/track-{alpha,beta,stable}/<tool>.html` — 5 level-2 stubs per channel that fetch `<source>/releases/<tool>_<channel>.html` directly. Static-file resolution end-to-end via the symlink chain — no JS indirection, no manifest lookup.
|
- **Server** (`zddc-server`) — every tool is `//go:embed`'d into the binary at compile time (the current-stable build). The server virtually serves them at folder-name-driven paths:
|
||||||
|
- `archive.html` at every directory (multi-project, project, archive, vendor levels)
|
||||||
|
- `classifier.html` in any `Incoming`/`Working`/`Staging` directory and its subtree
|
||||||
|
- `mdedit.html` in any `Working` directory and its subtree
|
||||||
|
- `transmittal.html` in any `Staging` directory and its subtree
|
||||||
|
- `index.html` (landing) only at the deployment root
|
||||||
|
|
||||||
End users install via the unified `bootstrap/install.sh` script (also served at `https://zddc.varasys.io/install.sh`). The home page's "Install on your server" section prints one-liners that invoke the script with the appropriate `--mode` / `--channel` / `--target` flags.
|
See `internal/apps/availability.go`. Outside these locations, requesting `<app>.html` returns 404 (just like any other missing file).
|
||||||
|
|
||||||
See `bootstrap/README.md` for the install / pin / audit story.
|
To override at any level, either:
|
||||||
|
1. Drop a real `<app>.html` file at the path → static handler serves it (highest priority).
|
||||||
|
2. Write an `apps:` entry in any `.zddc` along the path. Spec is one of `stable`/`beta`/`alpha`/`v0.0.4`/`v0.0`/`v0`/full URL/local path. Closer-to-leaf entries win.
|
||||||
|
|
||||||
|
URL sources fetch once and cache forever in `<ZDDC_ROOT>/_app/<host>/<path>`. To force a re-fetch, delete the cache file. No background refresh, no SHA-256 verification, no admin UI. If a configured URL fetch fails, the server falls back to the embedded copy and emits a one-time WARN log.
|
||||||
|
|
||||||
|
Operators audit by reading the `X-ZDDC-Source` response header: `fetch:URL` / `cache:URL` / `path:/abs` / `embedded:<app>@<build>`. Direct URL access to `/_app/...` is blocked at the dispatch layer.
|
||||||
|
|
||||||
|
**Runtime mode detection** in archive is independent of install: it auto-detects multi-project / project-root / in-archive from `?projects=` plus folder shape. The other tools don't care where they live.
|
||||||
|
|
||||||
### Worktrees
|
### Worktrees
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -37,8 +37,7 @@ Website files (what `zddc.varasys.io` serves) — committed in this repo as stat
|
||||||
|
|
||||||
```
|
```
|
||||||
website/
|
website/
|
||||||
index.html # hand-edited intro page (root URL)
|
index.html # hand-edited intro page + install snippets (root URL)
|
||||||
install.sh → ../bootstrap/install.sh # symlink so the upstream serves /install.sh
|
|
||||||
releases/
|
releases/
|
||||||
index.html # versions index, regenerated by build.sh from filesystem scan
|
index.html # versions index, regenerated by build.sh from filesystem scan
|
||||||
<tool>_v<X.Y.Z>.html # real per-version files (committed, immutable)
|
<tool>_v<X.Y.Z>.html # real per-version files (committed, immutable)
|
||||||
|
|
@ -47,9 +46,6 @@ website/
|
||||||
<tool>_stable.html → ... # symlink: current stable
|
<tool>_stable.html → ... # symlink: current stable
|
||||||
<tool>_beta.html → ... # symlink to stable (or real bytes when active beta dev)
|
<tool>_beta.html → ... # symlink to stable (or real bytes when active beta dev)
|
||||||
<tool>_alpha.html → ... # symlink to beta/stable (or real bytes when active alpha dev)
|
<tool>_alpha.html → ... # symlink to beta/stable (or real bytes when active alpha dev)
|
||||||
bootstrap/
|
|
||||||
level1/<tool>.html # same-origin stubs for project subdirectories
|
|
||||||
track-{alpha,beta,stable}/ # per-channel level-2 stubs (5 tools each)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Every URL under `/releases/` resolves directly via the symlink chain — no `manifest.json`, no Caddy regex-rewrite, no JavaScript indirection, no Codeberg proxy. 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.
|
Every URL under `/releases/` resolves directly via the symlink chain — no `manifest.json`, no Caddy regex-rewrite, no JavaScript indirection, no Codeberg proxy. 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.
|
||||||
|
|
@ -68,16 +64,16 @@ Each topic has exactly one authoritative home; everything else links to it.
|
||||||
|
|
||||||
| Topic | Single home | Linked from |
|
| 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`, `bootstrap/README.md` |
|
| 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 |
|
| 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 | `website/releases/index.html` (regenerated by `build.sh`) | website intro nav, "Browse all versions" link |
|
| Versions + channel builds index of every tool | `website/releases/index.html` (regenerated by `build.sh`) | website intro nav, "Browse all versions" link |
|
||||||
| Customer-deployment install (copy-paste shell snippets, level-1/2 stubs, `?v=`, audit) | `bootstrap/README.md` | website intro, `zddc/README.md` |
|
| Customer-deployment install (`zddc-server` binary embeds current-stable tools; `.zddc apps:` cascade overrides; cache at `<root>/_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`, `bootstrap/README.md`, website intro |
|
| 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") |
|
| Build / release / channel commands | `AGENTS.md` | repo `README.md` ("see AGENTS.md") |
|
||||||
| Architecture & internal patterns | `ARCHITECTURE.md` (this file) | `AGENTS.md` |
|
| Architecture & internal patterns | `ARCHITECTURE.md` (this file) | `AGENTS.md` |
|
||||||
| Per-tool internal design quirks | `<tool>/README.md` | (linked from website intro tool cards) |
|
| Per-tool internal design quirks | `<tool>/README.md` | (linked from website intro tool cards) |
|
||||||
|
|
||||||
`website/index.html` is **hand-edited static content** (analogous to `reference.html`), not the landing-tool output. The landing tool's released bytes live at `website/releases/landing_v<X.Y.Z>.html` (with `landing_<channel>.html` symlinks for channel mirrors). The unified install script (`bootstrap/install.sh`, served at `/install.sh`) curls the chosen channel's `landing_<channel>.html` to `<deployment-root>/index.html` for customer sites where the project picker UI is actually useful (it queries `zddc-server` for the project list). The public website at `zddc.varasys.io/` has nothing to pick, so its root URL is the introduction page.
|
`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 `website/releases/landing_v<X.Y.Z>.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).
|
||||||
|
|
||||||
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.
|
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.
|
||||||
|
|
||||||
|
|
@ -95,7 +91,7 @@ Each tool's `build.sh`:
|
||||||
4. Writes the result to `dist/tool.html`
|
4. Writes the result to `dist/tool.html`
|
||||||
5. If `--release <channel-or-version>` was passed, calls `promote_release` to write into `website/releases/` (per-version file + symlink updates for stable; channel mirror overwrite for alpha/beta).
|
5. If `--release <channel-or-version>` was passed, calls `promote_release` to write into `website/releases/` (per-version file + symlink updates for stable; channel mirror overwrite for alpha/beta).
|
||||||
|
|
||||||
The top-level `build.sh` at the repository root calls all five tool build scripts in sequence, regenerates `website/bootstrap/` (level-1 stubs and per-channel level-2 stubs), and writes `website/releases/index.html` from a filesystem scan of `website/releases/` so the versions index always matches the on-disk state.
|
The top-level `build.sh` at the repository root calls all five tool build scripts in sequence and writes `website/releases/index.html` from a filesystem scan of `website/releases/` so the versions index always matches the on-disk state.
|
||||||
|
|
||||||
### Channels
|
### Channels
|
||||||
|
|
||||||
|
|
@ -120,16 +116,35 @@ The on-page `{{BUILD_LABEL}}` is rendered red+bold for dev/alpha/beta builds (`i
|
||||||
|
|
||||||
`X.Y.Z` for non-stable labels is the **next-stable target** — patch+1 from the latest clean `<tool>-vX.Y.Z` tag. Dev builds use the full timestamp + `-dirty` marker so iterative work is distinguishable from a formal `--release alpha` cut (which stamps date-only and is committed-clean by definition).
|
`X.Y.Z` for non-stable labels is the **next-stable target** — patch+1 from the latest clean `<tool>-vX.Y.Z` tag. Dev builds use the full timestamp + `-dirty` marker so iterative work is distinguishable from a formal `--release alpha` cut (which stamps date-only and is committed-clean by definition).
|
||||||
|
|
||||||
### Two-level bootstrap
|
### Install distribution model
|
||||||
|
|
||||||
Customer deployments under `zddc-server` use a two-level bootstrap pattern that keeps tool installation decoupled from publishing. See `bootstrap/README.md` for the full story; in short:
|
Two orthogonal axes: how the bytes get there (this section), and what runtime mode the tool ends up in (next section).
|
||||||
|
|
||||||
- **Level 1**: per-project stub at `<project>/<tool>.html` that fetches `../<tool>.html` (always same-origin). One file per project per tool, never edited after install.
|
**Local mode** (no server): download a tool `.html` from <https://zddc.varasys.io/releases/> and open it. Tools are self-contained — no install, no install script.
|
||||||
- **Level 2** (optional): site admin replaces `<deployment-root>/<tool>.html` with a stub that fetches `<source>/releases/<tool>_<channel>.html` (e.g. `https://zddc.varasys.io/releases/archive_beta.html`) — a checked-in symlink on the upstream that resolves to the current channel mirror. Switches the whole site to a channel. Without it, `<deployment-root>/<tool>.html` is just the actual built tool HTML (self-contained install). The `bootstrap/install.sh` script handles both modes plus per-version pinning via a single `--mode` / `--channel` interface.
|
|
||||||
|
|
||||||
`document.write()` chains across both levels; origin stays at the deployment domain throughout. CORS only matters at level 2 (cross-origin to `zddc.varasys.io`); level 1 is same-origin.
|
**Server mode** (`zddc-server`): the binary `//go:embed`s the current-stable build of every tool at compile time. That's the default — no fetching happens out of the box. The server virtually serves each tool only at directories where the convention says it belongs (`internal/apps/availability.go`):
|
||||||
|
|
||||||
The stubs are generated from `bootstrap/level{1,2}.html.tmpl` by the root `build.sh` and published as standalone files under `website/bootstrap/level1/` and `website/bootstrap/track-<channel>/`. The home page's "Install on your server" section prints copy-paste shell snippets that `curl` these into the operator's deployment directory.
|
| App | Available at |
|
||||||
|
|---------------|-------------------------------------------------------------------------|
|
||||||
|
| `archive` | every directory (multi-project, project, archive, vendor) |
|
||||||
|
| `classifier` | any `Incoming`, `Working`, or `Staging` directory and its subtree |
|
||||||
|
| `mdedit` | any `Working` directory and its subtree |
|
||||||
|
| `transmittal` | any `Staging` directory and its subtree |
|
||||||
|
| `landing` | only at the deployment root |
|
||||||
|
|
||||||
|
Resolution order at a request to `<dir>/<app>.html` where the app is available:
|
||||||
|
|
||||||
|
1. **Override** — real `.html` file at the path → static handler.
|
||||||
|
2. **`.zddc apps:` cascade** — walk leaf→root for an `apps.<app>` entry. Spec is `stable`/`beta`/`alpha` (canonical channel), `v0.0.4`/`v0.0`/`v0` (canonical version), full URL (custom mirror), or local path. Closer-to-leaf wins.
|
||||||
|
3. **Embedded** — the build-time HTML compiled into the binary.
|
||||||
|
|
||||||
|
URL sources fetch once on first request and cache forever in `<ZDDC_ROOT>/_app/<host>/<path>`. There is no background refresh, no SHA-256 verification, no admin UI. To pull a new build, delete the cache file. Concurrent misses for the same URL share one outbound fetch (hand-rolled singleflight). Failed fetches fall through to embedded with a one-time WARN log per source URL. Direct URL access to `/_app/...` is blocked at dispatch.
|
||||||
|
|
||||||
|
The `X-ZDDC-Source` response header always reports what was served: `fetch:URL`, `cache:URL`, `path:/abs`, or `embedded:<app>@<build>`.
|
||||||
|
|
||||||
|
### Runtime mode detection
|
||||||
|
|
||||||
|
Independent of how the tool got installed. `archive` auto-detects from the URL and folder shape (`?projects=` set → multi-project; scan root has an `archive/` child → project-root; otherwise → in-archive). The other tools don't care — `transmittal`, `classifier`, `mdedit` work the same regardless of where they live.
|
||||||
|
|
||||||
### Build Script Requirements
|
### Build Script Requirements
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,14 @@ This is a **monorepo of independent tools**, not one application:
|
||||||
- `archive/`, `transmittal/`, `classifier/`, `mdedit/`, `landing/` — five self-contained HTML tools, each compiled to a single inlined HTML file in its own `dist/`. Naming: the first four output `dist/tool.html`; **`landing/` outputs `dist/index.html`** (it's the project picker served at the root of `zddc-server`).
|
- `archive/`, `transmittal/`, `classifier/`, `mdedit/`, `landing/` — five self-contained HTML tools, each compiled to a single inlined HTML file in its own `dist/`. Naming: the first four output `dist/tool.html`; **`landing/` outputs `dist/index.html`** (it's the project picker served at the root of `zddc-server`).
|
||||||
- `zddc/` — Go HTTP server (separate sub-project; Go 1.24+). Serves `ZDDC_ROOT/index.html` at `GET /` as the landing page; `Accept: application/json` on `/` returns the ACL-filtered project list. Stable releases ship as cross-compiled binaries on Codeberg release assets; the `helm/` charts in this repo build from source at deploy time.
|
- `zddc/` — Go HTTP server (separate sub-project; Go 1.24+). Serves `ZDDC_ROOT/index.html` at `GET /` as the landing page; `Accept: application/json` on `/` returns the ACL-filtered project list. Stable releases ship as cross-compiled binaries on Codeberg release assets; the `helm/` charts in this repo build from source at deploy time.
|
||||||
- `shared/` — `base.css` plus shared JS modules (`zddc.js`, `hash.js`, `zddc-filter.js`, `theme.js`, `help.js`) included by every tool's build, `build-lib.sh` (POSIX sh helpers sourced by every tool's `build.sh`), and `publish-codeberg-release.sh` (used by `zddc/release.sh` to upload zddc-server binaries — HTML tools no longer use it).
|
- `shared/` — `base.css` plus shared JS modules (`zddc.js`, `hash.js`, `zddc-filter.js`, `theme.js`, `help.js`) included by every tool's build, `build-lib.sh` (POSIX sh helpers sourced by every tool's `build.sh`), and `publish-codeberg-release.sh` (used by `zddc/release.sh` to upload zddc-server binaries — HTML tools no longer use it).
|
||||||
- `website/` — committed static site: `index.html` (root URL, hand-edited intro), `releases/<tool>_v<X.Y.Z>.html` (immutable per-version archives), `releases/<tool>_v<X.Y>.html` and `_v<X>.html` (symlinks to latest patch within minor / major), `releases/<tool>_{stable,beta,alpha}.html` (channel mirrors — symlinks when no active channel dev, real bytes when in flight), `releases/index.html` (regenerated by `build.sh` from a filesystem scan), `bootstrap/{level1,track-stable,track-beta,track-alpha}/<tool>.html` (per-channel level-2 stubs + same-origin level-1 stubs), and `install.sh` (symlink to `../bootstrap/install.sh` so the upstream serves it at `/install.sh`). All tool HTML files live in git — no Codeberg indirection, no manifest.json. There is no `website/dev/`.
|
- `website/` — committed static site: `index.html` (root URL, hand-edited intro), `releases/<tool>_v<X.Y.Z>.html` (immutable per-version archives), `releases/<tool>_v<X.Y>.html` and `_v<X>.html` (symlinks), `releases/<tool>_{stable,beta,alpha}.html` (channel mirrors), `releases/index.html` (regenerated by `build.sh`). **Install model:** local use is a download from `/releases/`. Server use is `zddc-server`, which has the current-stable build of all five tools baked in via `//go:embed` (compile-time default). Tools auto-served at folder-name-driven paths: `archive` everywhere, `classifier` in `Incoming`/`Working`/`Staging` subtrees, `mdedit` in `Working` subtrees, `transmittal` in `Staging` subtrees, `landing` only at root. Override via `.zddc apps:` cascade entry (channel/version/URL/path) — fetched once, cached at `<ZDDC_ROOT>/_app/`. Drop a real `.html` file at any path to override.
|
||||||
- `helm/` — example Helm charts for zddc-server (`zddc-server-prod/`, `zddc-server-dev/`). Both compile from source via init container. Operators copy `values.yaml.example` and customize. No secrets in repo.
|
- `helm/` — example Helm charts for zddc-server (`zddc-server-prod/`, `zddc-server-dev/`). Both compile from source via init container. Operators copy `values.yaml.example` and customize. No secrets in repo.
|
||||||
- `tests/` — Playwright specs (Chromium only, requires File System Access API). `tests/schema.spec.js` validates `transmittal.schema.json` against canonical fixtures via `ajv` (only dev dep besides Playwright)
|
- `tests/` — Playwright specs (Chromium only, requires File System Access API). `tests/schema.spec.js` validates `transmittal.schema.json` against canonical fixtures via `ajv` (only dev dep besides Playwright)
|
||||||
|
|
||||||
## Most-used commands
|
## Most-used commands
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sh build.sh # build all five HTML tools (dist/ only) + regen website/releases/index.html + bootstrap stubs
|
sh build.sh # build all five HTML tools (dist/ only) + regen website/releases/index.html
|
||||||
sh tool/build.sh # build one (archive|transmittal|classifier|mdedit|landing)
|
sh tool/build.sh # build one (archive|transmittal|classifier|mdedit|landing)
|
||||||
sh tool/build.sh --release [version] # cut stable; write website/releases/<tool>_v<X.Y.Z>.html, refresh 5 symlinks, tag <tool>-vX.Y.Z
|
sh tool/build.sh --release [version] # cut stable; write website/releases/<tool>_v<X.Y.Z>.html, refresh 5 symlinks, tag <tool>-vX.Y.Z
|
||||||
sh tool/build.sh --release alpha|beta # cut channel; overwrite website/releases/<tool>_<channel>.html in place. No tag (channel URLs are stable URLs by design)
|
sh tool/build.sh --release alpha|beta # cut channel; overwrite website/releases/<tool>_<channel>.html in place. No tag (channel URLs are stable URLs by design)
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ The name "Zero Day Document Control" comes from the convention itself — adopt
|
||||||
| **Document Classifier** | Spreadsheet-like bulk-renamer that copy/pastes with Excel and writes back to disk. |
|
| **Document Classifier** | Spreadsheet-like bulk-renamer that copy/pastes with Excel and writes back to disk. |
|
||||||
| **Markdown Editor** | Browser-based markdown editor with YAML front matter, TOC, and direct local file access. |
|
| **Markdown Editor** | Browser-based markdown editor with YAML front matter, TOC, and direct local file access. |
|
||||||
|
|
||||||
Each tool is published in three channels (stable, beta, alpha) as static files committed under `website/releases/`, browsable at <https://zddc.varasys.io/releases/>. Append `?v=alpha`, `?v=0.0.4` (exact), `?v=0.0` (latest patch), or `?v=0` (latest minor) to any deployment URL to switch versions for one request. See [`bootstrap/README.md`](bootstrap/README.md) for the install / pin / audit story.
|
Each tool is published in three channels (stable, beta, alpha) as static files committed under `website/releases/`, browsable at <https://zddc.varasys.io/releases/>. **Local use:** download a `.html` file from `releases/` and open it in a browser. **Server use:** run `zddc-server` — the current-stable build of every tool is baked into the binary at compile time, so a fresh deployment Just Works with zero config. Tools auto-appear at folder-name-driven paths (archive everywhere; classifier in `Incoming`/`Working`/`Staging`; mdedit in `Working`; transmittal in `Staging`). Override per-directory by writing an `apps:` entry in any `.zddc` file (channel/version/URL/path). URL overrides are fetched once and cached in `<ZDDC_ROOT>/_app/`; drop a real `.html` file at any path to override entirely.
|
||||||
|
|
||||||
## File-naming convention
|
## File-naming convention
|
||||||
|
|
||||||
|
|
|
||||||
105
zddc/README.md
105
zddc/README.md
|
|
@ -180,10 +180,9 @@ Two prefixes are filtered from listings under `ZDDC_ROOT`:
|
||||||
side-state (caches, dev-shell home dirs, snapshot staging) on the same volume
|
side-state (caches, dev-shell home dirs, snapshot staging) on the same volume
|
||||||
that's served, without exposing it.
|
that's served, without exposing it.
|
||||||
- **`_`-prefixed** (e.g. `/_template/`) — excluded from listings only. Direct URL
|
- **`_`-prefixed** (e.g. `/_template/`) — excluded from listings only. Direct URL
|
||||||
access still works, so the `_template/` directory of bootstrap stubs created
|
access still works. Use this for operator-managed scaffolding the user shouldn't
|
||||||
by the install snippet is reachable but doesn't clutter the project picker.
|
browse to but might link to (e.g. a `_template/` directory of stub-HTML examples
|
||||||
Use this for operator-managed scaffolding the user shouldn't browse to but
|
to copy into project subdirs).
|
||||||
might link to.
|
|
||||||
|
|
||||||
## Admin Debug Page
|
## Admin Debug Page
|
||||||
|
|
||||||
|
|
@ -235,48 +234,66 @@ callers.
|
||||||
- An interactive terminal is not yet available; that's planned as a follow-up
|
- An interactive terminal is not yet available; that's planned as a follow-up
|
||||||
behind a separate `ZDDC_ADMIN_TERM=1` env-var gate so it stays opt-in.
|
behind a separate `ZDDC_ADMIN_TERM=1` env-var gate so it stays opt-in.
|
||||||
|
|
||||||
## Landing Page and Tool Install
|
## Apps: virtual tool HTMLs
|
||||||
|
|
||||||
The recommended install is the unified [`install.sh`](https://zddc.varasys.io/install.sh) script — `cd` into `ZDDC_ROOT/` and run:
|
`zddc-server` virtually serves the five tool HTMLs (archive, transmittal,
|
||||||
|
classifier, mdedit, landing) at the appropriate paths. The current-stable
|
||||||
|
build of each tool is **baked into the binary at compile time** via
|
||||||
|
`//go:embed`; that's the default. No fetch happens out of the box.
|
||||||
|
|
||||||
```sh
|
### Where each tool is served
|
||||||
sh -c "$(curl -fsSL https://zddc.varasys.io/install.sh)" # self-contained, current stable (default)
|
|
||||||
sh -c "$(curl -fsSL https://zddc.varasys.io/install.sh)" -- --mode track --channel beta # track beta
|
| App | Available at |
|
||||||
sh -c "$(curl -fsSL https://zddc.varasys.io/install.sh)" -- --channel 0.0.2 # pin to a specific version
|
|---------------|-------------------------------------------------------------------------|
|
||||||
|
| `archive` | every directory (multi-project, project, archive, vendor) |
|
||||||
|
| `classifier` | any `Incoming`, `Working`, or `Staging` directory and its subtree |
|
||||||
|
| `mdedit` | any `Working` directory and its subtree |
|
||||||
|
| `transmittal` | any `Staging` directory and its subtree |
|
||||||
|
| `landing` | only at the deployment root (the project picker) |
|
||||||
|
|
||||||
|
Outside these locations, the corresponding `<app>.html` URL returns 404.
|
||||||
|
|
||||||
|
### Override and version-pin
|
||||||
|
|
||||||
|
For any path, the resolution order is:
|
||||||
|
|
||||||
|
1. **Real file at the path** — operator drops `archive.html` (or any other)
|
||||||
|
into a directory; the static handler serves it. Beats everything below.
|
||||||
|
2. **Closer-to-leaf `.zddc apps:` entry** — walks `.zddc` files leaf→root
|
||||||
|
for an `apps.<app>` entry. The first match wins. Spec is one of:
|
||||||
|
- `stable` / `beta` / `alpha` (canonical upstream channel)
|
||||||
|
- `v0.0.4` / `v0.0` / `v0` (canonical upstream version pin)
|
||||||
|
- `https://...` (full URL to a custom mirror)
|
||||||
|
- `./local.html` / `/abs/path.html` (local file)
|
||||||
|
3. **Embedded** — the build-time HTML compiled into the binary.
|
||||||
|
|
||||||
|
URL sources are fetched once on first request and cached forever in
|
||||||
|
`<ZDDC_ROOT>/_app/<host>/<path>`. There is no background refresh and no
|
||||||
|
hash verification — to pull a new build, delete the cache file. Concurrent
|
||||||
|
misses for the same URL share one outbound fetch (singleflight). Direct
|
||||||
|
URL access to `/_app/...` is blocked at dispatch; cached HTMLs are served
|
||||||
|
only via the apps resolver.
|
||||||
|
|
||||||
|
If a configured URL fetch fails (network down, 5xx), the server falls back
|
||||||
|
to the embedded copy and emits a one-time WARN log per source. The
|
||||||
|
`X-ZDDC-Source` response header always reports what was served:
|
||||||
|
`fetch:URL`, `cache:URL`, `path:/abs`, or `embedded:<app>@<build>`.
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# <ZDDC_ROOT>/Project-A/.zddc
|
||||||
|
apps:
|
||||||
|
classifier: alpha # track alpha for this project
|
||||||
|
archive: https://my-mirror.internal/zddc/archive_v0.0.4.html # custom mirror, pinned
|
||||||
|
mdedit: ./our-mdedit.html # local fork
|
||||||
```
|
```
|
||||||
|
|
||||||
The script handles all three deployment patterns:
|
### Env vars
|
||||||
|
|
||||||
- **Self-contained** (default) — fetches the five current-channel tool HTMLs and populates a `_template/` directory of level-1 bootstrap stubs. No runtime dependency on `zddc.varasys.io`. Re-run to update.
|
| Variable | Default | Purpose |
|
||||||
- **Channel-tracking** — fetches five tiny level-2 stubs (~10 KB total) that fetch the named channel from `zddc.varasys.io` on every page load.
|
|----------------------|---------|----------------------------------------------------------|
|
||||||
- **Pin-to-version** — copies a specific version's HTML locally; site does not move.
|
| `ZDDC_BUILD_VERSION` | `dev` | String stamped into `X-ZDDC-Source: embedded:<app>@<v>` |
|
||||||
|
|
||||||
For project subdirectories, run the same command from inside `<ZDDC_ROOT>/Project-X/` — it auto-detects the parent and installs four level-1 stubs that fetch `../<tool>.html`.
|
|
||||||
|
|
||||||
After running one of the snippets, the deployment looks like:
|
|
||||||
|
|
||||||
```
|
|
||||||
ZDDC_ROOT/
|
|
||||||
index.html ← landing page (current stable, or level-2 stub)
|
|
||||||
archive.html ← archive browser (likewise)
|
|
||||||
transmittal.html
|
|
||||||
classifier.html
|
|
||||||
mdedit.html
|
|
||||||
_template/ ← level-1 bootstrap stubs (self-contained snippet only);
|
|
||||||
rename a copy to <project-name>/ for each project
|
|
||||||
Project-001/
|
|
||||||
archive.html ← level-1 stub: fetches ../archive.html
|
|
||||||
transmittal.html
|
|
||||||
classifier.html
|
|
||||||
mdedit.html
|
|
||||||
Project-002/
|
|
||||||
…
|
|
||||||
```
|
|
||||||
|
|
||||||
The level-2 stubs require `zddc-server` to accept cross-origin requests
|
|
||||||
from `zddc.varasys.io`, controlled via `ZDDC_CORS_ORIGIN`. See
|
|
||||||
[`bootstrap/README.md`](../bootstrap/README.md) for the full install
|
|
||||||
guide and the `?v=…` URL parameter for per-request version selection.
|
|
||||||
|
|
||||||
The landing page fetches `GET /` (with `Accept: application/json`) to retrieve the list
|
The landing page fetches `GET /` (with `Accept: application/json`) to retrieve the list
|
||||||
of top-level project directories the requesting user has access to. It renders checkboxes
|
of top-level project directories the requesting user has access to. It renders checkboxes
|
||||||
|
|
@ -369,9 +386,9 @@ returns JSON directory listings in exactly the same format as Caddy's `file-serv
|
||||||
— no changes to `archive/js/source.js` are needed.
|
— no changes to `archive/js/source.js` are needed.
|
||||||
|
|
||||||
To use: install `archive.html` at `ZDDC_ROOT/archive.html` (or any subdirectory) — either
|
To use: install `archive.html` at `ZDDC_ROOT/archive.html` (or any subdirectory) — either
|
||||||
the actual built tool fetched by the self-contained install snippet, or a
|
the actual built tool downloaded by the self-contained install snippet, or one of the
|
||||||
level-1/level-2 bootstrap stub that fetches it. Then open it via the zddc-server URL;
|
six-line stubs from the project-subdir / track-upstream snippets that fetches it. Then
|
||||||
the app will auto-connect and scan the directory tree.
|
open it via the zddc-server URL; the app will auto-connect and scan the directory tree.
|
||||||
|
|
||||||
## Distribution
|
## Distribution
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue