Adds the first Playwright spec that drives a real running zddc-server
in Chromium. Future UI debugging (the conflict-UI in phase 5, browser-
side iteration on the master's HTML pages, etc.) reuses the same
harness — beforeAll spins up a master on a random port, the spec
talks to it, afterAll tears it down.
Files:
- tests/lib/server.js: CommonJS module exporting startMaster(opts).
Builds the binary on first run via the canonical podman/zddc-go:1.24
invocation from AGENTS.md, caching at zddc/dist/zddc-server-test
with a sibling .hash file (SHA256 of cmd/+internal/+go.{mod,sum})
that invalidates on source change. Subsequent runs skip the build.
Set ZDDC_TEST_BIN=<path> to use a pre-built binary (CI / debugging).
Seeds a minimal master root in os.tmpdir() with a permissive .zddc
granting the test user (default alice@example.com) full access plus
read for *@example.com. Picks a free port via net.listen(:0), spawns
the binary on 127.0.0.1:<port>, polls until listening (max 10s).
Returns { baseURL, root, proc, logs(), stop() }.
CommonJS (require/module.exports) rather than ESM because Playwright's
loader transforms top-level `import` in *.spec.js files but not in
the .js helpers we ship alongside; mixing produces "exports is not
defined in ES module scope" at the helper's first line. Spec files
use `import { ... } from './lib/server.js'` and the import resolves
through the CJS interop layer cleanly.
- tests/tokens.spec.js: 8 server-backed scenarios covering the entire
/.tokens contract:
1. Anonymous → 401 on /.tokens (X-Auth-Request-Email empty).
2. Authenticated GET /.tokens renders the page with the user's email
visible in the .who line and the create form + tokens table both
present and populated.
3. GET /.api/tokens returns an empty list initially.
4. Create-via-page round-trip: fill the form, click submit, plaintext
appears once in #created .token-secret (hidden from later reads),
row appears in the table, API list confirms the description, the
row's Revoke button removes it from both the table and the API.
5. Plaintext token authenticates a subsequent Bearer request even
when X-Auth-Request-Email is empty — confirms the middleware
bridge from Bearer to ACL email.
6. Invalid Bearer → 401 (no silent fallback to anonymous).
7. Cross-user revoke returns 404 (not 403) — the ownership-non-leak
guarantee.
8. XSS guard: description with <img src=x onerror="window.__xss=1">
should render as text (assert window.__xss !== 1) — the inline
JS's escapeHTML is the only thing standing between an attacker
who could create tokens and stored XSS on the management page.
test.use({ extraHTTPHeaders }) injects X-Auth-Request-Email on every
request from the Playwright browser context, mimicking what an
upstream auth proxy adds in production. Per-test overrides clear it
to test anonymous paths.
- playwright.config.js: adds the `tokens` project. Bumps the global
timeout from 30s → 60s so the first run's binary-build (~30s on a
cold gocache) doesn't time out the suite. The tokens project
testMatches only tokens.spec.js, so other projects (the file://-
driven tool tests) are unaffected.
Verified: all 8 tests pass (12.5s warm; ~45s cold including the build).
The harness is ready to graft additional server-backed specs onto —
phase 5's conflict-UI in particular will follow the same pattern.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|---|---|---|
| .forgejo | ||
| archive | ||
| browse | ||
| classifier | ||
| form | ||
| helm | ||
| landing | ||
| mdedit | ||
| pandoc | ||
| shared | ||
| tables | ||
| tests | ||
| transmittal | ||
| zddc | ||
| .gitignore | ||
| AGENTS.md | ||
| ARCHITECTURE.md | ||
| build | ||
| CLAUDE.md | ||
| deploy | ||
| dev-server | ||
| freshen-channel | ||
| LICENSE.txt | ||
| package.json | ||
| playwright.config.js | ||
| README.md | ||
| SECURITY.md | ||
Zero Day Document Control (ZDDC)
The Universal Distributed Filing Cabinet
ZDDC is an information management convention plus a small set of single-file HTML tools. Every deliverable's filename encodes its tracking number, revision, status, and title; every transmittal folder is date-prefixed and self-describing. A plain shared folder becomes a fully searchable, auditable archive — no server, no database, no software required to read it.
The name "Zero Day Document Control" comes from the convention itself — adopt it on day zero of a project, with no setup time. The tools are optional interfaces around the structure; the structure works without them.
For end users: https://zddc.varasys.io/ introduces the project, links to all tool channels (stable / beta / alpha), and prints copy-paste shell snippets to install on a self-hosted deployment.
Tools
| Tool | What it does |
|---|---|
| Archive Browser | Browse, search, and filter a project archive folder. Group by transmittal, export selections as ZIP. |
| Transmittal Creator | Self-contained HTML transmittal records with SHA-256 checksums and optional digital signatures. |
| 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. |
| Form Renderer | Schema-driven *.form.yaml editor — every form spec auto-mounts an editable form at <name>.form.html. |
| Tables | Read-only grid view of a directory of YAML files with sort + filter; click row → edit in the form renderer. Declared per-directory in .zddc. |
Each tool is published in three channels (stable, beta, alpha) as static files served from 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
The full specification — filename format, tracking numbers, revision rules, status codes, folder naming, and the transmittal workflow — lives at https://zddc.varasys.io/reference.html.
Quick example: 123456-EL-SPC-2623_A (IFR) - Specification For Switchgear.pdf
Build & develop
git clone https://codeberg.org/VARASYS/ZDDC.git && cd ZDDC
sh build.sh # build all tools (writes to dist/ only)
sh archive/build.sh # build one tool
sh archive/build.sh --release # cut stable; auto-bumps patch from last tag
sh archive/build.sh --release 0.1.0 # explicit version
sh archive/build.sh --release alpha # cut alpha (mutable channel, no tag)
sh archive/build.sh --release beta # cut beta
npm install && npx playwright install chromium && npm test # tests
./dev-server start # cache-busting HTTP on :8000
Authoritative build/release docs are in AGENTS.md. Architecture notes (single-file rationale, JS module pattern, security model) are in ARCHITECTURE.md. zddc-server (optional Go HTTP server with ACL and a virtual archive index) is in zddc/README.md. Example Helm charts for deploying zddc-server (production + dev) are under helm/.
Contributing
ZDDC is an open source project hosted on Codeberg at https://codeberg.org/VARASYS/ZDDC. Bug reports, feature requests, and pull requests welcome.
ZDDC is designed for zero configuration to start and minimal configuration overall — feature proposals are filtered through that lens.
License
GNU Affero General Public License v3.0. Free to use, modify, and distribute, including commercially, under the terms of the license. Provided "as is" without warranty.