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

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

Files updated:

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

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 09:56:34 -05:00

56 lines
7 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Authoritative docs — read these first
This repo already has two thorough agent-facing references. **Always consult them before working** — they cover details intentionally omitted here:
- **`AGENTS.md`** — commands, build-system rules, per-tool parser quirks, testing gotchas, git/worktree workflow, release process, zddc-server notes
- **`ARCHITECTURE.md`** — single-file HTML pattern rationale, JS module/state patterns, per-tool architecture, security model
If something in this CLAUDE.md conflicts with those, those win — and please update them rather than letting drift accumulate.
## Repo shape
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; 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).
- `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/`.
- `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)
## Most-used commands
```bash
sh build.sh # build all five HTML tools (dist/ only) + regen website/releases/index.html + bootstrap stubs
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 alpha|beta # cut channel; overwrite website/releases/<tool>_<channel>.html in place. No tag (channel URLs are stable URLs by design)
./freshen-channel <tool> <channel> # rebuild alpha/beta from current stable tag (run after every stable release if you want to advance the channel mirror)
npm test # all Playwright specs (build first!)
npx playwright test <tool> # one spec
./dev-server start # ./dev-server stop # cache-busting HTTP on :8000
# zddc/ Go server (separate sub-project, not part of sh build.sh)
(cd zddc && go test ./...) # unit tests (Go 1.24+)
sh zddc/release.sh [<version>] # cut stable zddc-server release; tags + cross-compiles binaries + uploads to Codeberg. Stable-only (no alpha/beta channel for binaries).
```
No lint/typecheck/format commands exist for the HTML tools — vanilla JS + POSIX sh by design.
## Things that bite if you forget
- **`dist/` is gitignored.** `tool/dist/<tool>.html` is the canonical built artifact for testing and as the source for `--release` writes. Never hand-edit a `dist/` file.
- **`website/releases/` is committed.** Per-version files (`<tool>_v<X.Y.Z>.html`) are real immutable files; partial-version pins (`<tool>_v<X.Y>.html`, `<tool>_v<X>.html`) and channels (`<tool>_<channel>.html`) are checked-in symlinks. Stable cuts write the new versioned file + refresh the 5 symlinks (cascade rule: stable cut → beta + alpha both reset to the new stable). Beta/alpha cuts overwrite their channel mirror in place; on a beta cut, alpha cascades to point at beta.
- **No tags for alpha/beta.** Channel URLs are stable URLs by design — appending counter tags would defeat the purpose. The on-page label encodes `<date> · <sha>` for traceability. Stable cuts still get clean `<tool>-vX.Y.Z` tags.
- **Pre-release semver in the on-page label.** Plain dev builds and `--release alpha|beta` cuts embed `vX.Y.Z-{alpha,beta}` in `{{BUILD_LABEL}}` where X.Y.Z is the next-stable target (patch+1 from latest clean `<tool>-vX.Y.Z` tag). Plain dev adds a full timestamp + `-dirty` marker; `--release alpha|beta` is date-only.
- **Plain `sh tool/build.sh` is a dev build.** Writes `dist/<tool>.html` only; no `website/releases/` side-effect. To publish, re-run with `--release alpha`.
- **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.
- **Two globals only**: `window.app` (per-tool app state + modules) and `window.zddc` (shared library). No others — anything that crosses tool boundaries goes through one of these.
- **Worktrees live at `~/src/zddc-<branch>`.** Check `git worktree list` before starting a feature branch; never `git checkout`/`switch` inside a worktree another agent might be using.
- **Build scripts are POSIX `sh` with `set -eu`**, not bash. `concat_files` takes positional args only.