refactor: rename channel 'latest' to 'stable' across all artifacts

The 'latest' label for the current-stable channel was inconsistent
with the channel set we use elsewhere (alpha / beta / stable). Rename
to 'stable' so URLs, file names, zip names, and image tags all line
up with the channel terminology used in the bootstrap, AGENTS.md
discipline rules, and chart consumers.

File / artifact renames
- website/releases/<tool>_latest.html → <tool>_stable.html (5 files)
- website/track-latest.zip            → track-stable.zip
- shared/build-lib.sh: promote_release writes/refreshes _stable.html
- bootstrap/level{1,2}.html.tmpl: channels map drops 'latest', keeps
  'stable' as the canonical name. ?v=stable is now the explicit way
  to switch to current-stable for one request (alongside ?v=alpha,
  ?v=beta, and ?v=X.Y.Z).
- build.sh: install.zip sources from <tool>_stable.html; emits
  track-stable.zip instead of track-latest.zip.

Container image (.woodpecker.yml rewritten)
- Tag publishing now cascades:
    zddc-server-vX.Y.Z              → :X.Y.Z, :stable, :beta, :alpha, :latest
    zddc-server-vX.Y.Z-beta.N       → :X.Y.Z-beta.N, :beta, :alpha
    zddc-server-vX.Y.Z-alpha.N      → :X.Y.Z-alpha.N, :alpha
- :stable, :beta, :alpha are now first-class channel pointers; chart
  consumers (e.g. tnd-zddc-chart) can FROM :beta for dev and FROM
  :stable for prod.
- :latest kept as an alias for :stable per Docker convention.

Documentation sweep
- AGENTS.md, ARCHITECTURE.md, CLAUDE.md, README.md
- bootstrap/README.md, zddc/README.md
- website/index.html, website/zddc-server.html
- transmittal/template.html, transmittal/README.md
all updated to reference _stable.html / track-stable.zip / the
'stable' channel name. ARCHITECTURE.md's manual freshen example
points at ./freshen-channel instead of the old git-checkout snippet.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
ZDDC 2026-04-28 09:30:24 -05:00
parent 1da25eff3f
commit 67f794e6d0
26 changed files with 96 additions and 73 deletions

View file

@ -1,22 +1,30 @@
# Woodpecker CI for ZDDC.
#
# This pipeline only runs on `zddc-server-v*` tag pushes — it builds the
# zddc-server runtime container image and publishes it to Codeberg's
# container registry. Other tags (archive-v*, transmittal-v*, etc.) and
# regular pushes are ignored here; the HTML tool releases happen by
# pushing static files to the website (no image involved).
# Triggers on `zddc-server-v*` tag pushes. Builds the runtime container
# image and publishes it to Codeberg's container registry with channel
# tags that cascade downward, so that pinning to `:stable` always gets
# the most recent stable, `:beta` always tracks the most recent beta-or-
# stable, and `:alpha` always tracks the most recent alpha-or-newer.
#
# To enable: in Codeberg → repo Settings → Woodpecker → set the secrets
# codeberg_user = your Codeberg username (e.g. VARASYS)
# codeberg_token = a personal token with package:write scope
# Generate the token at https://codeberg.org/user/settings/applications.
# Tag conventions
# ---------------
# zddc-server-vX.Y.Z → stable release
# zddc-server-vX.Y.Z-beta.N → beta release
# zddc-server-vX.Y.Z-alpha.N → alpha release
#
# After setup, cut a release with:
# git tag zddc-server-v0.0.1
# git push --tags
# and the pipeline will publish:
# codeberg.org/varasys/zddc-server:0.0.1
# codeberg.org/varasys/zddc-server:latest
# Image tags applied (cascading)
# ------------------------------
# stable release: :X.Y.Z + :stable, :beta, :alpha, :latest
# beta release: :X.Y.Z-beta.N + :beta, :alpha
# alpha release: :X.Y.Z-alpha.N + :alpha
#
# `:latest` is kept as an alias for `:stable` (Docker convention).
#
# To enable: in the Woodpecker dashboard at https://ci.codeberg.org →
# repo → Settings → Secrets, add codeberg_user (your Codeberg username)
# and codeberg_token (a personal token with package:write scope from
# https://codeberg.org/user/settings/applications). Restrict both
# secrets to the `tag` event for safety.
when:
- event: tag
@ -26,17 +34,32 @@ steps:
prepare-bundle:
image: docker.io/alpine:3.20
commands:
# build.sh assembles zddc/dist/web/ from landing and archive
# built outputs (which are committed force-tracked dist files).
# Falls back gracefully when podman isn't present — we don't
# need the cross-compiled binaries here, the runtime container
# builds its own linux/amd64 binary internally.
# 1. Assemble zddc/dist/web/ from the landing + archive built outputs.
# build.sh now skips the (host-side) podman binary build when
# podman is absent, which is the case in CI — the runtime
# container image's own builder stage produces linux/amd64.
- sh build.sh
# Image tag = the bare semver after the "zddc-server-v" prefix.
# Plus a "latest" tag for convenience.
- VERSION="${CI_COMMIT_TAG#zddc-server-v}"
- printf '%s\nlatest\n' "$VERSION" > .image-tags
- echo "Will tag image with: $(cat .image-tags | tr '\n' ' ')"
# 2. Compute the image tags. Grammar:
# zddc-server-vX.Y.Z → stable
# zddc-server-vX.Y.Z-alpha.N → alpha (cascade: alpha)
# zddc-server-vX.Y.Z-beta.N → beta (cascade: beta, alpha)
# Anything else is rejected by the `when:` filter; nothing to
# handle here.
- |
VERSION="${CI_COMMIT_TAG#zddc-server-v}"
case "$VERSION" in
*-alpha.*) CHANNEL=alpha ;;
*-beta.*) CHANNEL=beta ;;
*) CHANNEL=stable ;;
esac
case "$CHANNEL" in
stable) TAGS="$VERSION stable beta alpha latest" ;;
beta) TAGS="$VERSION beta alpha" ;;
alpha) TAGS="$VERSION alpha" ;;
esac
printf '%s\n' $TAGS > .image-tags
echo "Channel: $CHANNEL"
echo "Tags: $TAGS"
publish-image:
image: woodpeckerci/plugin-docker-buildx

View file

@ -58,11 +58,11 @@ website/
index.html current stable landing (root URL)
releases/
<tool>_v<X>.<Y>.<Z>.html immutable stable release archives
<tool>_latest.html -> ... symlink to current stable (highest semver)
<tool>_stable.html -> ... symlink to current stable (highest semver)
<tool>_alpha.html mutable; overwritten by --release alpha
<tool>_beta.html mutable; overwritten by --release beta
install.zip drop-in self-contained install (5 stable HTMLs + _template/ stubs)
track-latest.zip level-2 stubs that track the current-stable channel
track-stable.zip level-2 stubs that track the current-stable channel
track-alpha.zip level-2 stubs that track the alpha channel
track-beta.zip level-2 stubs that track the beta channel
@ -163,7 +163,7 @@ Format: `trackingNumber_revision (status) - title.extension`
Three channels:
- **Stable**: versioned, immutable. `sh tool/build.sh --release [version]` writes `website/releases/<tool>_v<version>.html`, refreshes the `<tool>_latest.html` symlink, and tags `<tool>-v<version>`. Skips automatically if source has not changed since the latest tag. Pass an explicit version to override auto-increment.
- **Stable**: versioned, immutable. `sh tool/build.sh --release [version]` writes `website/releases/<tool>_v<version>.html`, refreshes the `<tool>_stable.html` symlink, and tags `<tool>-v<version>`. Skips automatically if source has not changed since the latest tag. Pass an explicit version to override auto-increment.
- **Beta**: mutable. `sh tool/build.sh --release beta` overwrites `website/releases/<tool>_beta.html` in place. No tag. The on-page label is `beta · <date> · <sha>` so the source is recoverable from git via the SHA.
- **Alpha**: mutable, analogous. `sh tool/build.sh --release alpha`.
@ -214,7 +214,7 @@ Note: the build pipeline used is the one **at the tag**, not on `main`. That is
`build.sh` regenerates three downloadable zips into `website/` on every invocation:
- `install.zip` — 5 current-stable HTMLs at root + `_template/` directory containing 4 level-1 bootstrap stubs (per-project use). Skipped if any tool has no stable release yet.
- `track-{alpha,beta,latest}.zip` — 5 level-2 stubs each, hardcoded to fetch the named channel from `zddc.varasys.io/releases/`. Drop one over a deployment root to switch the whole site to that channel.
- `track-{alpha,beta,stable}.zip` — 5 level-2 stubs each, hardcoded to fetch the named channel from `zddc.varasys.io/releases/`. Drop one over a deployment root to switch the whole site to that channel.
See `bootstrap/README.md` for the install / pin / audit story.

View file

@ -40,11 +40,11 @@ website/
index.html # current stable landing tool (root URL)
releases/
<tool>_v<X>.<Y>.<Z>.html # immutable stable release archives
<tool>_latest.html -> ... # symlink to the highest-versioned stable
<tool>_stable.html -> ... # symlink to the highest-versioned stable
<tool>_alpha.html # mutable: overwritten on every --release alpha
<tool>_beta.html # mutable: overwritten on every --release beta
install.zip # current-stable HTMLs + project bootstrap stubs
track-{alpha,beta,latest}.zip # level-2 channel-tracking stubs
track-{alpha,beta,stable}.zip # level-2 channel-tracking stubs
```
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.
@ -68,7 +68,7 @@ Each topic has exactly one authoritative home; everything else links to it.
| Architecture & internal patterns | `ARCHITECTURE.md` (this file) | `AGENTS.md` |
| 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 ships only via `website/releases/landing_v<X>.html` and `install.zip``install.zip` copies `landing_latest.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 landing tool ships only via `website/releases/landing_v<X>.html` and `install.zip``install.zip` copies `landing_stable.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.
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.
@ -86,17 +86,17 @@ Each tool's `build.sh`:
4. Writes the result to `dist/tool.html`
5. If `--release <channel-or-version>` was passed, calls `promote_release` to write the appropriate file under `website/releases/`
The top-level `build.sh` at the repository root calls all five tool build scripts in sequence and then regenerates the bootstrap zips (`install.zip`, `track-{alpha,beta,latest}.zip`) so they always match what's in `releases/`.
The top-level `build.sh` at the repository root calls all five tool build scripts in sequence and then regenerates the bootstrap zips (`install.zip`, `track-{alpha,beta,stable}.zip`) so they always match what's in `releases/`.
### Channels
Three release channels:
- **Stable** — versioned, immutable. `--release [version]` writes `website/releases/<tool>_v<version>.html`, refreshes the `<tool>_latest.html` symlink, and tags `<tool>-v<version>` in git. Skips automatically when there is no source change since the last tag.
- **Stable** — versioned, immutable. `--release [version]` writes `website/releases/<tool>_v<version>.html`, refreshes the `<tool>_stable.html` symlink, and tags `<tool>-v<version>` in git. Skips automatically when there is no source change since the last tag.
- **Beta** — mutable. `--release beta` overwrites `website/releases/<tool>_beta.html` in place. No git tag; the on-page label is `beta · <date> · <sha>` so the source is recoverable from git history via the SHA.
- **Alpha** — mutable, analogous to beta.
Stable releases do not automatically clobber `<tool>_alpha.html` / `<tool>_beta.html` — those keep whatever was last built into them. To freshen alpha to current stable, `git checkout v<X>.<Y>.<Z> && sh tool/build.sh --release alpha`.
Stable releases do not automatically clobber `<tool>_alpha.html` / `<tool>_beta.html` — those keep whatever was last built into them. Use `./freshen-channel <tool> <channel>` (worktree-based, no manual `git checkout`) to drag a channel forward to current stable.
The on-page `{{BUILD_LABEL}}` is rendered red+bold for dev/alpha/beta builds (`is_red=1`) and black for stable releases. The label format is:

View file

@ -18,7 +18,7 @@ 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`).
- `zddc/` — Go HTTP server (separate sub-project, podman/podman-compose; Go 1.24+). Serves `ZDDC_ROOT/index.html` at `GET /` as the landing page; `Accept: application/json` on `/` returns the ACL-filtered project list.
- `shared/``base.css` plus shared JS modules (`zddc.js`, `hash.js`, `zddc-filter.js`, `theme.js`, `help.js`) included by every tool's build, and `build-lib.sh` (POSIX sh helpers sourced by every tool's `build.sh`)
- `website/` — published artifacts: `index.html` (root URL), `releases/<tool>_v<X.Y.Z>.html` (immutable stable archives), `releases/<tool>_latest.html` (symlink to current stable), `releases/<tool>_{alpha,beta}.html` (mutable channel files), plus bootstrap zips (`install.zip`, `track-{alpha,beta,latest}.zip`). `--release` is the only path to publishing — there is no `website/dev/`.
- `website/` — published artifacts: `index.html` (root URL), `releases/<tool>_v<X.Y.Z>.html` (immutable stable archives), `releases/<tool>_stable.html` (symlink to current stable), `releases/<tool>_{alpha,beta}.html` (mutable channel files), plus bootstrap zips (`install.zip`, `track-{alpha,beta,stable}.zip`). `--release` is the only path to publishing — there is no `website/dev/`.
- `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
@ -38,7 +38,7 @@ No lint/typecheck/format commands exist — vanilla JS + POSIX sh by design.
## Things that bite if you forget
- **`dist/` is gitignored but force-committed** (`git add -f tool/dist/tool.html`). Never hand-edit a `dist/` file.
- **Never write to `website/index.html` or `website/releases/*` directly** — promote via `sh tool/build.sh --release [version|alpha|beta]`. Stable releases write `website/releases/<tool>_v<ver>.html` (immutable) and refresh `<tool>_latest.html`; alpha/beta overwrite `<tool>_<channel>.html` in place.
- **Never write to `website/index.html` or `website/releases/*` directly** — promote via `sh tool/build.sh --release [version|alpha|beta]`. Stable releases write `website/releases/<tool>_v<ver>.html` (immutable) and refresh `<tool>_stable.html`; alpha/beta overwrite `<tool>_<channel>.html` in place.
- **Always build before running tests** — Playwright opens `dist/tool.html` via `file://`.
- **`</` in JS string/template literals breaks inline `<script>`** embedding. `shared/build-lib.sh` provides `escape_js_close_tags`; every tool's `build.sh` runs JS through it before inlining.
- **All ZDDC parsing/formatting/hashing goes through `window.zddc`** (from `shared/zddc.js` + `shared/hash.js` + `shared/zddc-filter.js`). API: `parseFilename`, `parseFolder`, `parseRevision`, `formatFilename`, `formatFolder`, `compareRevisions`, `isValidStatus`, `splitExtension`, `joinExtension`, `crypto.{sha256Hex, sha256String, sha256File, bytesToHex}`, `filter.{parse, matches}`. File objects across tools use `trackingNumber` (string) and `extension` (string, **no leading dot** — use `zddc.joinExtension(name, ext)` to build a filename). Add edge cases to `tests/zddc.spec.js`, not per-tool tests.

View file

@ -12,10 +12,10 @@ The name "Zero Day Document Control" comes from the convention itself — adopt
| Tool | What it does |
|------|--------------|
| **[Archive Browser](https://zddc.varasys.io/releases/archive_latest.html)** | Browse, search, and filter a project archive folder. Group by transmittal, export selections as ZIP. |
| **[Transmittal Creator](https://zddc.varasys.io/releases/transmittal_latest.html)** | Self-contained HTML transmittal records with SHA-256 checksums and optional digital signatures. |
| **[Document Classifier](https://zddc.varasys.io/releases/classifier_latest.html)** | Spreadsheet-like bulk-renamer that copy/pastes with Excel and writes back to disk. |
| **[Markdown Editor](https://zddc.varasys.io/releases/mdedit_latest.html)** | Browser-based markdown editor with YAML front matter, TOC, and direct local file access. |
| **[Archive Browser](https://zddc.varasys.io/releases/archive_stable.html)** | Browse, search, and filter a project archive folder. Group by transmittal, export selections as ZIP. |
| **[Transmittal Creator](https://zddc.varasys.io/releases/transmittal_stable.html)** | Self-contained HTML transmittal records with SHA-256 checksums and optional digital signatures. |
| **[Document Classifier](https://zddc.varasys.io/releases/classifier_stable.html)** | Spreadsheet-like bulk-renamer that copy/pastes with Excel and writes back to disk. |
| **[Markdown Editor](https://zddc.varasys.io/releases/mdedit_stable.html)** | Browser-based markdown editor with YAML front matter, TOC, and direct local file access. |
Each tool is published in three channels (stable, beta, alpha) at `https://zddc.varasys.io/releases/<tool>_<channel>.html`. Append `?v=alpha` (or `?v=0.0.4`, etc.) to any URL to switch versions for one request. See [`bootstrap/README.md`](bootstrap/README.md) for the install / pin / audit story.

View file

@ -65,7 +65,7 @@ choice sticks for everyone using that file.
| URL | Behavior |
|------------------------------------------------------------------|-----------------------------------------|
| `https://zddc.varasys.io/releases/<tool>_latest.html` | current stable; auto-updates within stable |
| `https://zddc.varasys.io/releases/<tool>_stable.html` | current stable; auto-updates within stable |
| `https://zddc.varasys.io/releases/<tool>_beta.html` | latest beta build (mutable) |
| `https://zddc.varasys.io/releases/<tool>_alpha.html` | latest alpha build (mutable) |
| `https://zddc.varasys.io/releases/<tool>_v1.2.3.html` | pinned to exact stable version |
@ -112,7 +112,7 @@ upstream must serve `Access-Control-Allow-Origin: *` (or a list including
your deployment origin) on the released HTML files. Verify with:
```sh
curl -I https://zddc.varasys.io/releases/archive_latest.html | grep -i access-control
curl -I https://zddc.varasys.io/releases/archive_stable.html | grep -i access-control
```
Level-1 fetches are same-origin so no CORS is involved.

View file

@ -15,7 +15,7 @@
//
// URL parameter ?v= selects a specific version or channel:
// ?v=0.0.4 (or v0.0.4) tries ../{{TOOL}}_v0.0.4.html locally
// ?v=alpha|beta|latest tries ../{{TOOL}}_<channel>.html locally
// ?v=alpha|beta|stable tries ../{{TOOL}}_<channel>.html locally
// (none) fetches ../{{TOOL}}.html (default)
//
// If the requested version is not staged locally, falls back to the
@ -30,7 +30,7 @@
const params = new URLSearchParams(location.search);
const v = params.get('v');
const tool = '{{TOOL}}';
const channels = { alpha: '_alpha', beta: '_beta', latest: '_latest', stable: '_latest' };
const channels = { alpha: '_alpha', beta: '_beta', stable: '_stable' };
function suffixFor(value) {
if (!value) return '';

View file

@ -13,7 +13,7 @@
// document.write()s it in place. The default upstream is the
// {{CHANNEL}} channel; the URL parameter ?v= overrides it:
//
// ?v=alpha|beta|latest switches to that channel
// ?v=alpha|beta|stable switches to that channel
// ?v=0.0.4 (or v0.0.4) pins to that exact stable version
// (none) uses the {{CHANNEL}} default
//
@ -23,7 +23,7 @@
const v = params.get('v');
const tool = '{{TOOL}}';
const defaultChannel = '{{CHANNEL}}';
const channels = { alpha: '_alpha', beta: '_beta', latest: '_latest', stable: '_latest' };
const channels = { alpha: '_alpha', beta: '_beta', stable: '_stable' };
function suffixFor(value) {
if (!value) return '_' + defaultChannel;

View file

@ -81,7 +81,7 @@ build_install_zip() {
# Verify a stable release exists for every tool before staging.
_missing=""
while IFS='|' read -r _tool _file _title; do
[ -e "$RELEASES_DIR/${_tool}_latest.html" ] || _missing="$_missing $_tool"
[ -e "$RELEASES_DIR/${_tool}_stable.html" ] || _missing="$_missing $_tool"
done <<EOF
$TOOL_TABLE
EOF
@ -93,7 +93,7 @@ EOF
_staging=$(mktemp -d)
while IFS='|' read -r _tool _file _title; do
cp "$RELEASES_DIR/${_tool}_latest.html" "$_staging/$_file"
cp "$RELEASES_DIR/${_tool}_stable.html" "$_staging/$_file"
done <<EOF
$TOOL_TABLE
EOF
@ -139,7 +139,7 @@ echo "=== Building install.zip and track-*.zip ==="
build_install_zip
build_track_zip alpha
build_track_zip beta
build_track_zip latest
build_track_zip stable
echo ""
echo "=== All tools built successfully ==="
@ -152,4 +152,4 @@ echo "Bootstrap downloads: website/"
echo " install.zip — self-contained install for deployment root"
echo " track-alpha.zip — level-2 stubs that track the alpha channel"
echo " track-beta.zip — level-2 stubs that track the beta channel"
echo " track-latest.zip — level-2 stubs that track the latest stable"
echo " track-stable.zip — level-2 stubs that track the stable channel"

View file

@ -66,7 +66,7 @@ if [ "$is_release" = "1" ]; then
# NOTE: website/index.html is a hand-edited intro page for
# zddc.varasys.io, not the landing tool. The landing tool ships
# only via website/releases/ and install.zip — install.zip puts
# landing_latest.html at the customer deployment root, where the
# landing_stable.html at the customer deployment root, where the
# project picker UI is useful (it queries zddc-server for the
# project list). See AGENTS.md "Releasing — channels and layout".
fi

View file

@ -23,7 +23,7 @@
# See "Channels and release args" below.
# promote_release <tool> — write to website/releases/ in the layout
# driven by $channel and $build_version. For
# stable, also update the _latest.html
# stable, also update the _stable.html
# symlink and create the git tag.
#
# Channels and release args:
@ -155,7 +155,7 @@ compute_build_label() {
# Reads from caller scope: $channel, $build_version, $output_html, $root_dir.
#
# Stable releases write website/releases/<tool>_v<version>.html, refresh the
# website/releases/<tool>_latest.html symlink, and tag <tool>-v<version> in
# website/releases/<tool>_stable.html symlink, and tag <tool>-v<version> in
# git. Skips silently when the source has not changed since the latest tag.
#
# Alpha and beta channel releases overwrite website/releases/<tool>_<channel>.html
@ -190,8 +190,8 @@ promote_release() {
# Symlink target is relative to its own directory so the link survives
# path moves and works regardless of where the website is mounted.
(cd "$_releases_dir" && ln -sfn "${_tool}_v${build_version}.html" "${_tool}_latest.html")
echo "Updated ${_tool}_latest.html -> ${_tool}_v${build_version}.html"
(cd "$_releases_dir" && ln -sfn "${_tool}_v${build_version}.html" "${_tool}_stable.html")
echo "Updated ${_tool}_stable.html -> ${_tool}_v${build_version}.html"
git -C "$root_dir" tag "${_tool}-v${build_version}"
echo "Tagged ${_tool}-v${build_version} — run: git push --tags"

View file

@ -56,7 +56,7 @@ When you open a transmittal, it may display "✓ Signature Valid" - but **this d
**For Document Controllers / Official Verification:**
1. **Use a trusted tool instance** - Download the official transmittal tool from a trusted source (e.g., your organization's approved version or https://zddc.varasys.io/releases/transmittal_latest.html)
1. **Use a trusted tool instance** - Download the official transmittal tool from a trusted source (e.g., your organization's approved version or https://zddc.varasys.io/releases/transmittal_stable.html)
2. **Export JSON from the transmittal** - Open the transmittal → Click "Download Data"
3. **Import JSON into trusted tool** - Open your trusted tool → Click "Load JSON" → Paste the exported data
4. **Verify file hashes** - Click "Select Directory" and point to the actual files
@ -285,7 +285,7 @@ When viewing a published transmittal, signature status is displayed above the fi
**Verification Actions**:
- **Verify Externally** — Opens a trusted tool instance for independent verification
- Copies JSON data to clipboard
- Opens https://zddc.varasys.io/releases/transmittal_latest.html in validation mode
- Opens https://zddc.varasys.io/releases/transmittal_stable.html in validation mode
- Paste JSON and select directory to verify file hashes independently
- Only trust verification results from the trusted tool, not this document

View file

@ -353,7 +353,7 @@ conventions at https://codeberg.org/VARASYS/ZDDC#file-naming-convention.
<li><strong>Digital signatures</strong> &mdash; ECDSA signatures bind the digest to a signer&rsquo;s private key. Any change invalidates the signature, preventing undetected tampering. Add signatures after publishing via <em>Add Signature</em>.</li>
<li><strong>Independent verification</strong> &mdash; A tampered HTML file could ship modified JavaScript that always says &ldquo;Verified.&rdquo; To rule this out, the recipient opens the sender&rsquo;s file in their <em>own</em> trusted copy of the tool using <em>Import HTML</em>. This extracts the raw data and re-verifies it with the recipient&rsquo;s own code. Use this level for anything that matters.</li>
</ol>
<p class="text-sm text-gray-500">Level&nbsp;4 assumes the recipient&rsquo;s tool is trustworthy (downloaded from a known source or built from source). A reference instance is at <a href="https://zddc.varasys.io/releases/transmittal_latest.html" target="_blank" rel="noopener">zddc.varasys.io</a>.</p>
<p class="text-sm text-gray-500">Level&nbsp;4 assumes the recipient&rsquo;s tool is trustworthy (downloaded from a known source or built from source). A reference instance is at <a href="https://zddc.varasys.io/releases/transmittal_stable.html" target="_blank" rel="noopener">zddc.varasys.io</a>.</p>
<h3>Menu Actions</h3>
<p>Actions available from the dropdown button. <span class="help-badge help-badge--draft">draft</span> items appear only while editing. <span class="help-badge help-badge--published">published</span> items appear only after publishing. Unmarked items appear in both modes.</p>

View file

@ -49,19 +49,19 @@
</button>
<div class="dropdown-menu">
<div class="dropdown-menu__inner">
<a href="releases/archive_latest.html">
<a href="releases/archive_stable.html">
<svg class="dropdown-menu-icon" viewBox="0 0 24 24"><path d="M20 6H4a2 2 0 00-2 2v10a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2zm0 12H4V8h16v10zM4 2h16v2H4z"/></svg>
Archive Browser
</a>
<a href="releases/transmittal_latest.html">
<a href="releases/transmittal_stable.html">
<svg class="dropdown-menu-icon" viewBox="0 0 24 24"><path d="M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/></svg>
Transmittal Creator
</a>
<a href="releases/classifier_latest.html">
<a href="releases/classifier_stable.html">
<svg class="dropdown-menu-icon" viewBox="0 0 24 24"><path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"/></svg>
Document Classifier
</a>
<a href="releases/mdedit_latest.html">
<a href="releases/mdedit_stable.html">
<svg class="dropdown-menu-icon" viewBox="0 0 24 24"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04a1 1 0 000-1.41l-2.34-2.34a1 1 0 00-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></svg>
Markdown Editor
</a>
@ -101,7 +101,7 @@
<div class="tool-card__title">Archive Browser</div>
<div class="tool-card__desc">Browse, search, and filter your project folder. Group by transmittal; filter by tracking number, revision, status, or free text. Export selections as ZIP.</div>
<div class="channel-row">
<a href="releases/archive_latest.html" class="channel-stable">stable</a>
<a href="releases/archive_stable.html" class="channel-stable">stable</a>
<a href="releases/archive_beta.html" class="channel-beta">beta</a>
<a href="releases/archive_alpha.html" class="channel-alpha">alpha</a>
</div>
@ -111,7 +111,7 @@
<div class="tool-card__title">Transmittal Creator</div>
<div class="tool-card__desc">Fill in metadata, drag in files, publish a self-contained HTML transmittal record with SHA-256 checksums. Optional digital signatures. The published file <em>is</em> the transmittal record.</div>
<div class="channel-row">
<a href="releases/transmittal_latest.html" class="channel-stable">stable</a>
<a href="releases/transmittal_stable.html" class="channel-stable">stable</a>
<a href="releases/transmittal_beta.html" class="channel-beta">beta</a>
<a href="releases/transmittal_alpha.html" class="channel-alpha">alpha</a>
</div>
@ -121,7 +121,7 @@
<div class="tool-card__title">Document Classifier</div>
<div class="tool-card__desc">Spreadsheet-like interface for bulk-renaming files into ZDDC format. Copy/paste with Excel. Point it at a folder, fill in the columns, save all at once.</div>
<div class="channel-row">
<a href="releases/classifier_latest.html" class="channel-stable">stable</a>
<a href="releases/classifier_stable.html" class="channel-stable">stable</a>
<a href="releases/classifier_beta.html" class="channel-beta">beta</a>
<a href="releases/classifier_alpha.html" class="channel-alpha">alpha</a>
</div>
@ -131,7 +131,7 @@
<div class="tool-card__title">Markdown Editor</div>
<div class="tool-card__desc">Browser-based markdown editor with live preview, YAML front matter, and table of contents. Direct local file access via the File System Access API.</div>
<div class="channel-row">
<a href="releases/mdedit_latest.html" class="channel-stable">stable</a>
<a href="releases/mdedit_stable.html" class="channel-stable">stable</a>
<a href="releases/mdedit_beta.html" class="channel-beta">beta</a>
<a href="releases/mdedit_alpha.html" class="channel-alpha">alpha</a>
</div>
@ -155,7 +155,7 @@
<div class="install-card">
<h3>Track stable</h3>
<p>Five level-2 bootstrap stubs. Drop over the deployment root to auto-track latest stable.</p>
<p><a href="track-latest.zip">track-latest.zip →</a></p>
<p><a href="track-stable.zip">track-stable.zip →</a></p>
</div>
<div class="install-card">
<h3>Track beta</h3>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
website/track-stable.zip Normal file

Binary file not shown.

View file

@ -47,19 +47,19 @@
</button>
<div class="dropdown-menu">
<div class="dropdown-menu__inner">
<a href="releases/archive_latest.html">
<a href="releases/archive_stable.html">
<svg class="dropdown-menu-icon" viewBox="0 0 24 24"><path d="M20 6H4a2 2 0 00-2 2v10a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2zm0 12H4V8h16v10zM4 2h16v2H4z"/></svg>
Archive Browser
</a>
<a href="releases/transmittal_latest.html">
<a href="releases/transmittal_stable.html">
<svg class="dropdown-menu-icon" viewBox="0 0 24 24"><path d="M20 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm0 4l-8 5-8-5V6l8 5 8-5v2z"/></svg>
Transmittal Creator
</a>
<a href="releases/classifier_latest.html">
<a href="releases/classifier_stable.html">
<svg class="dropdown-menu-icon" viewBox="0 0 24 24"><path d="M3 18h18v-2H3v2zm0-5h18v-2H3v2zm0-7v2h18V6H3z"/></svg>
Document Classifier
</a>
<a href="releases/mdedit_latest.html">
<a href="releases/mdedit_stable.html">
<svg class="dropdown-menu-icon" viewBox="0 0 24 24"><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04a1 1 0 000-1.41l-2.34-2.34a1 1 0 00-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></svg>
Markdown Editor
</a>

View file

@ -188,7 +188,7 @@ ZDDC_ROOT/
This is fully self-contained — no external dependencies. To make the
deployment auto-track a published channel from `zddc.varasys.io`, drop
`track-alpha.zip` / `track-beta.zip` / `track-latest.zip` (also at
`track-alpha.zip` / `track-beta.zip` / `track-stable.zip` (also at
`https://zddc.varasys.io/`) over `ZDDC_ROOT/`: those replace the root
`<tool>.html` files with level-2 bootstrap stubs that fetch the named
channel from `zddc.varasys.io` on each page load. See