# ZDDC Architecture This document is the single authoritative reference for how ZDDC tools are designed and built. It covers the shared single-file HTML application pattern, the build system, tool-specific architectural decisions, and contribution guidelines. --- ## Why Single-File HTML Applications Every ZDDC tool compiles to a single self-contained `.html` file — no servers, no installers, no subscriptions. | Principle | Rationale | |-----------|-----------| | **Reliability** | Opens in any modern Chromium-based browser without network access or external services | | **Portability** | Can be emailed, archived, or deployed to air-gapped environments with no tooling | | **Auditability** | Source, embedded data, and output travel together, satisfying ZDDC traceability requirements | | **Longevity** | Static assets remain functional long after build environments have changed | | **Simplicity** | A single `.html` file eliminates deployment steps and brittle dependency chains | --- ## Repository Structure Every HTML tool follows the same directory layout: ``` tool/ README.md # Feature scope, UI design, domain rules, help content css/ # Logically separated stylesheets (one responsibility per file) js/ # Vanilla ES modules (one responsibility per file) template.html # Shell markup with {{PLACEHOLDER}} markers for development build.sh # Inlines css/ and js/ into dist/tool.html dist/ tool.html # Generated output — never edit this manually ``` Website files (what `zddc.varasys.io` serves) are organized by channel: ``` website/ index.html # current stable landing tool (root URL) releases/ _v...html # immutable stable release archives _latest.html -> ... # symlink to the highest-versioned stable _alpha.html # mutable: overwritten on every --release alpha _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 ``` 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. Vendor dependencies (bundled third-party libraries) live in `tool/vendor/` if present. The build script is responsible for inlining them into the output. --- ## Documentation ownership Each topic has exactly one authoritative home; everything else links to it. | Topic | Single home | Linked from | |---|---|---| | What ZDDC is + tool channel links + install bundles | `website/index.html` (hand-edited intro for `zddc.varasys.io/`) | repo `README.md`, `bootstrap/README.md` | | File-naming convention spec (status codes, modifiers, folder format) | `website/reference.html` | repo `README.md`, in-tool help text | | Customer-deployment install (install.zip, level-1/2 stubs, `?v=`, audit) | `bootstrap/README.md` | website intro, `zddc/README.md` | | zddc-server config, ACL, `.archive`, deployment | `zddc/README.md` | `AGENTS.md`, `bootstrap/README.md` | | 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) | `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.html` and `install.zip` — `install.zip` copies `landing_latest.html` to `/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. --- ## Build System ### How It Works Each tool's `build.sh`: 1. Reads CSS files in declaration order, concatenates them 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 `` to terminate the block — backslash escaping (`<\/script>`) does **not** prevent termination. Any JS source file or vendor library that contains `` sequences inside string literals or template literals will break the inline `` (not `<\/script>`) to close the `` or any `` in JS string literals | Breaks inline HTML embedding — escape with `'<' + '/tag>'` or use `<\/` in `sed` at build time | | No external dependencies at runtime | Self-contained output requirement | | No TypeScript, no bundlers | Keeps the build system auditable and simple | | Only `window.app` and `window.zddc` are global | Keeps the global namespace clean; expose only what's needed for debugging | | Defensive input validation | File System API handles and user-pasted data are untrusted | | Update README.md when features ship | Documentation parity is a delivery requirement, not optional | --- ## Git Workflow **Branching:** short-lived feature branches (`feature/`, `bugfix/`, `hotfix/`), squash-merged to `main` and immediately deleted. Quick fixes (typos, one-liners) go direct to `main`. **Commit messages:** Conventional Commits — `(): `. Types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `chore`. See `AGENTS.md` for the full table and examples. **Releases:** Tag the commit after confirming `dist/` is current. Format: `{project}-v{version}` (e.g. `archive-v1.0.0`). Semantic versioning applies. There is no CI/CD — the built `.html` file is already committed to the repo. ```bash bash tool/build.sh # rebuild dist/ git add -f tool/dist/tool.html # stage if needed git commit -m "chore(tool): rebuild for vX.Y.Z" git tag tool-vX.Y.Z git push origin main --tags git tag -l "archive-v*" # list releases git push origin :refs/tags/tag-name # delete a remote tag ``` --- ## Adding a New Tool 1. Create `tool/` with the standard directory layout 2. Write `template.html` with `{{CSS_PLACEHOLDER}}` and `{{JS_PLACEHOLDER}}` markers 3. Write `tool/build.sh` following the pattern of an existing tool 4. Add `bash "$SCRIPT_DIR/tool/build.sh"` to the root `build.sh` 5. Add a test project entry to `playwright.config.js` 6. Create a stub `tests/tool.spec.js` 7. Force-add the dist output: `git add -f tool/dist/tool.html` If the tool requires vendor dependencies, download them to `tool/vendor/`, add them to `.gitignore` exclusions if appropriate, and update `build.sh` to inline them (with the `