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>
162 lines
10 KiB
HTML
162 lines
10 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>zddc-server — Zero Day Document Control</title>
|
|
<meta name="description" content="ZDDC has two access modes: local directory mode (tools work directly on a folder) and online mode (any web server can host it). zddc-server is an optional Go binary that adds access control, a virtual archive index, and audit logging on top of online mode.">
|
|
<meta property="og:type" content="website">
|
|
<meta property="og:url" content="https://zddc.varasys.io/zddc-server.html">
|
|
<meta property="og:title" content="zddc-server — Zero Day Document Control">
|
|
<meta property="og:description" content="ZDDC has two access modes: local directory mode (tools work directly on a folder) and online mode (any web server can host it). zddc-server is an optional Go binary that adds access control, a virtual archive index, and audit logging on top of online mode.">
|
|
<meta name="theme-color" content="#2a5a8a">
|
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
|
<link rel="stylesheet" href="css/style.css">
|
|
<style>
|
|
code.inline { background: var(--color-bg-subtle); padding: 0.1rem 0.35rem; border-radius: 4px; font-size: 0.9em; }
|
|
.feature-list { line-height: 1.8; padding-left: 1.5rem; color: var(--color-text); }
|
|
.feature-list li { margin-bottom: 0.4rem; }
|
|
.feature-list li strong { color: var(--color-text); }
|
|
.ascii-tree { background: var(--color-bg-subtle); padding: var(--spacing-md); border-radius: 6px; font-family: ui-monospace, monospace; font-size: 0.85rem; line-height: 1.5; overflow-x: auto; color: var(--color-text); white-space: pre; }
|
|
.mode-card { padding: var(--spacing-md); border: 1px solid var(--color-border); border-radius: 8px; }
|
|
.mode-grid { display: grid; grid-template-columns: 1fr; gap: var(--spacing-md); margin-top: var(--spacing-md); }
|
|
@media (min-width: 720px) { .mode-grid { grid-template-columns: 1fr 1fr; } }
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<!-- Header -->
|
|
<header class="site-header">
|
|
<div class="container header-content">
|
|
<a href="/" class="brand">
|
|
<div class="brand-logo">
|
|
<svg viewBox="0 0 24 24">
|
|
<path d="M3 5h18v2H3V5zm0 6h12v2H3v-2zm0 6h6v2H3v-2z" />
|
|
</svg>
|
|
</div>
|
|
<span class="brand-name">ZDDC</span>
|
|
</a>
|
|
<nav class="header-nav">
|
|
<div class="dropdown">
|
|
<button class="dropdown-toggle" type="button" aria-haspopup="true">
|
|
<span>Tools</span>
|
|
<svg viewBox="0 0 24 24" style="width: 14px; height: 14px; fill: currentColor;">
|
|
<path d="M7 10l5 5 5-5z"/>
|
|
</svg>
|
|
</button>
|
|
<div class="dropdown-menu">
|
|
<div class="dropdown-menu__inner">
|
|
<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_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_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_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>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<a href="reference.html" class="nav-link">Docs</a>
|
|
<a href="zddc-server.html" class="nav-link active">Server</a>
|
|
</nav>
|
|
</div>
|
|
</header>
|
|
|
|
<!-- Hero -->
|
|
<section class="hero">
|
|
<div class="container">
|
|
<h1>zddc-server</h1>
|
|
<p class="hero-subtitle">ZDDC has two access modes over the same on-disk archive. <strong>Online mode</strong> is what you get when you put a local directory behind a web server. <code class="inline">zddc-server</code> is an optional Go binary that adds access control, a virtual archive index, and audit logging on top.</p>
|
|
</div>
|
|
</section>
|
|
|
|
<main class="container" style="margin-bottom: var(--spacing-2xl);">
|
|
|
|
<section style="margin-top: var(--spacing-xl);">
|
|
<h2>Two modes, one archive</h2>
|
|
|
|
<div class="mode-grid">
|
|
<div class="mode-card">
|
|
<h3 style="margin-top: 0;">Local directory mode</h3>
|
|
<p>Open a tool, click <em>Add Directory</em>, point it at a folder. The tool reads files directly via the File System Access API. No upload, no server, no account.</p>
|
|
<p>Enough for individual users and small teams on a shared drive (network share, Dropbox, OneDrive, syncthing).</p>
|
|
</div>
|
|
<div class="mode-card">
|
|
<h3 style="margin-top: 0;">Online mode</h3>
|
|
<p>Take the same local directory and put it behind any web server (nginx, Caddy, Apache, even <code class="inline">python -m http.server</code>). The Archive Browser tool talks to the server's directory listings instead of the local filesystem.</p>
|
|
<p>Read-only, no special server software, works in any browser.</p>
|
|
</div>
|
|
</div>
|
|
|
|
<p style="margin-top: var(--spacing-md);">That's it. Same on-disk layout, two access mechanisms. The convention is the contract; the mode is an access decision.</p>
|
|
</section>
|
|
|
|
<section style="margin-top: var(--spacing-2xl);">
|
|
<h2>What zddc-server adds</h2>
|
|
<p><code class="inline">zddc-server</code> is a small Go binary built specifically to serve ZDDC archives. It <em>is</em> a web server, so it gives you online mode out of the box — but it adds things a generic web server can't:</p>
|
|
|
|
<ul class="feature-list">
|
|
<li><strong>If the server reads email headers, it can enforce access control.</strong> Behind any reverse proxy that authenticates users (Authelia, oauth2-proxy, your own SSO) and sets an <code class="inline">X-Email</code> request header, zddc-server consults <code class="inline">.zddc</code> YAML files in directories. Cascading bottom-up; deeper rules override shallower ones. No database, no admin UI — edit the files with any text editor.</li>
|
|
<li><strong>Virtual <code class="inline">.archive</code> URL space.</strong> <code class="inline">GET /Project/.archive/123-XYZ.html</code> resolves to the canonical revision file (the one in the chronologically earliest transmittal that contains it). Computed from filenames at request time — no cache, no separate index file. Restart the server and it rebuilds.</li>
|
|
<li><strong>Per-request access logging</strong> keyed to the authenticated user's email — method, path, status, bytes, duration.</li>
|
|
<li><strong>TLS, ETags, conditional GET, CORS, autoindex.</strong> The mundane glue that makes a directory pleasant to serve.</li>
|
|
</ul>
|
|
|
|
<p>In short: any web server can do online mode for reads. <code class="inline">zddc-server</code> adds ACL, a virtual archive index, and audit logging while remaining a thin wrapper around the same directory.</p>
|
|
</section>
|
|
|
|
<section style="margin-top: var(--spacing-2xl);">
|
|
<h2>Still just files in folders</h2>
|
|
<p>The on-disk layout is the same whether you access locally or online. The server doesn't transform the archive — it serves it. Stop the server and the directory is still a perfectly valid ZDDC archive that opens in local-directory mode.</p>
|
|
|
|
<pre class="ascii-tree">ZDDC_ROOT/
|
|
index.html ← landing tool
|
|
archive.html ← archive browser
|
|
transmittal.html
|
|
…
|
|
Project-001/
|
|
.zddc ← ACL (optional, YAML)
|
|
2025-10-31_123456-EM-MDL-0001 (IFR) - Master Deliverables List/
|
|
123456-EM-MDL-0001_A (IFR) - Master Deliverables List.pdf
|
|
2025-11-12_123456-EL-SPC-2623 (IFR) - Specification For Switchgear/
|
|
123456-EL-SPC-2623_A (IFR) - Specification For Switchgear.pdf
|
|
Project-002/
|
|
…</pre>
|
|
|
|
<p>This keeps the "Zero Day" promise: <strong>the server is convenience, not lock-in</strong>. Walk away from <code class="inline">zddc-server</code> tomorrow and the archive is still a perfectly valid convention-named folder tree, fully usable with nothing more than a file manager.</p>
|
|
</section>
|
|
|
|
<section style="margin-top: var(--spacing-2xl);">
|
|
<h2>Get it</h2>
|
|
<p>The server lives at <a href="https://codeberg.org/VARASYS/ZDDC/src/branch/main/zddc"><code class="inline">codeberg.org/VARASYS/ZDDC</code> under <code class="inline">zddc/</code></a>. Operations and configuration — environment variables, TLS modes, the <code class="inline">.zddc</code> ACL syntax, the virtual archive index URL patterns, container vs native binary deployment — are documented in <a href="https://codeberg.org/VARASYS/ZDDC/src/branch/main/zddc/README.md">zddc/README.md</a>.</p>
|
|
|
|
<p>Quick start (with <code class="inline">podman</code> available):</p>
|
|
<pre class="ascii-tree">git clone https://codeberg.org/VARASYS/ZDDC.git
|
|
cd ZDDC/zddc
|
|
ZDDC_DATA_DIR=/path/to/your/archive podman-compose up --build</pre>
|
|
|
|
<p>For the deployment-side install of the tools onto a <code class="inline">zddc-server</code> instance — including the level-1/level-2 bootstrap pattern, <code class="inline">install.zip</code>, and the channel-tracking <code class="inline">track-*.zip</code> bundles — see <a href="https://codeberg.org/VARASYS/ZDDC/src/branch/main/bootstrap/README.md">bootstrap/README.md</a>.</p>
|
|
</section>
|
|
|
|
</main>
|
|
|
|
<!-- Footer -->
|
|
<footer class="site-footer">
|
|
<div class="container footer-content">
|
|
<span>ZDDC is open source — <a href="https://codeberg.org/VARASYS/ZDDC">codeberg.org/VARASYS/ZDDC</a></span>
|
|
</div>
|
|
</footer>
|
|
|
|
<script src="js/layout.js"></script>
|
|
</body>
|
|
</html>
|