Implementing ZDDC

The specification set, how its pieces are versioned, and what it takes to write software that interoperates with other ZDDC archives.

Most people never need this page. ZDDC is designed so that a party can take part using nothing but a file browser and the naming convention — that is the whole point of encoding a deliverable's identity in its filename. If you are adopting ZDDC on a project, the Technical Reference is the document you want.

This page is for someone building software that reads or writes ZDDC archives.

The tools are a reference implementation

zddc-server and the single-file HTML tools are a ZDDC implementation. They are not the definition of ZDDC. The on-disk conventions are the contract: the naming convention, the folder layout, the signature envelopes. Anything that follows those conventions interoperates, whoever wrote it and in whatever language.

That is a deliberate constraint rather than an accident of how the project grew. An archive is supposed to outlive the software that made it — a record you cannot read in twenty years without a specific vendor's program is not a record, it is a hostage. Keeping the conventions independently specified is what makes the tools optional.

Three things are versioned, separately

One version number cannot say whether a naming rule changed or a button moved. So there are three lines, and they move independently:

Layer What it covers What a change means
Core Filenames and folder names — the Technical Reference, §2–§8 A migration. Core is baked into files already sitting on disk, so changing it makes existing archives retroactively wrong.
Extensions Optional on-disk formats layered on Core — custody signatures, project workflow, history, configuration, registers Only affects implementations that chose to support that extension.
Software zddc-server and the HTML tools Nothing about the convention. An implementation states which Core and extension versions it implements.

Within Core, the split runs one level deeper. The grammar — the shape of a filename — is the frozen part. The code tables (disciplines, types, statuses) are registries: separately versioned vocabulary that a project adds to where it has a gap, under the harmonization rule in Core §1. Adding a status code for your project does not fork the convention, and a new code in the base registry does not change the grammar.

What a version number means

Specifications carry two numbers, MAJOR.MINOR. The software carries three (vX.Y.Z), because software has bug-fix releases and a specification does not: a published specification version is never edited, and corrections to it are recorded as errata rather than as a new patch version.

A version written with ZDDC's own draft prefix — ~1.0 — is a draft of that version, exactly as ~A is a draft of revision A (Core §5): the version it will become is fixed, but its text and vectors may still change without notice. Finalising drops the ~. From then on 1.0 is stable: the text and vectors are frozen under the rules above, and corrections are errata. A draft is published at the address its final version will have, so a link saved today still works after it is finalised.

The specification set

Document Version Status Covers
Core ~1.0 Draft Filename grammar, tracking numbers, revisions, draft prefix, modifiers, status registry, folder names
Custody Extension ~1.0 Draft Signed manifests, DSSE envelopes, key files, the ledger — verifying who issued a record, decades later
Workflow Extension ~0.1 Draft Project layout, the staging/-to-archive/ commit, the transmittal workflow

Other on-disk formats the reference implementation defines — history storage, the .zddc configuration cascade, register and form definitions — are documented in the source repository but are not published specifications yet. They are not listed above because an unfinished specification is worse than an honest absence: it invites someone to build against something that is still moving.

Conformance is a test suite, not a claim

Each published specification ships conformance vectors: language-neutral JSON cases with an input, a required result, and a citation back to the prose rule they pin. They are the executable half of the specification.

Prose alone is not enough, and we have the evidence in-house. ZDDC's Go and browser custody implementations were written independently from the same written specification, by the same team, and still diverged in twelve places before vectors closed them. A stranger reading the same prose will do no better.

Vectors alone are not enough either. A vector says what, never why; anything it does not cover is undefined, and an implementation can pass by coincidence without understanding intent. That is what each vector's description field is for. The two halves are load-bearing together.

If an implementation passes the vectors, it interoperates. That is the entire conformance claim, and it is deliberately the only one. There is no certification, no registry of approved implementations, and nothing to sign.

Conformance levels

A specification may define levels, so an implementation can support part of it honestly rather than claiming all of it.

Core declares two — reader and writer. A reader parses names and orders revisions, and tolerates a status that breaks the grammar so the file can still be found and repaired; a writer composes names and refuses to produce one that breaks it. Every Core vector names the level it tests.

The Custody Extension declares four; they compose, and nothing requires all of them:

Two composition rules come with them, and they are worth reading as a model for what a real conformance section does: a verifier may not ship without a hasher, because verifying a manifest you cannot recompute is not verification; and a producer must be a verifier of its own output, because the cheapest way to emit a broken payload is to never read one back.

Writing your own implementation

The short version: download the vectors, run them offline, pass every valid case and reject every invalid one.

For the Custody Extension, everything is in one archive — the specification sources, the vectors and the vendored Ed25519 corpora: zddc-custody-1.0.tar.gz (SHA-256). The runner contract is its conformance document.

Vectors are designed to be runnable with no clock, no network and no source of randomness, so a conformance run is reproducible and can be part of your own test suite rather than a one-time exercise. Load each JSON file, dispatch on its kind, compare against expect.

Mutation-check your runner before you trust it. A suite that has never failed is not evidence that it checks anything. Corrupt each vector's expectation in a copy of the tree and confirm your runner fails on every one. This is not hypothetical advice — doing exactly this caught a path bug in ours that was silently rewriting the vectors in place instead of the copies, which would have made a broken runner look green.

What not to do

Extensions are additive. If something you need can be expressed as a new extension, or as codes added to a registry where a gap exists, that is the supported path and it requires nobody's permission.

Some limits are permanent rather than deferred, and a proposal that requires breaking one is a redesign of the system rather than an extension of it. That is allowed — but it should say so plainly instead of arriving as a small compatible-looking change. The bar is not that the idea is wrong; it is that a change to the contract has to be visible as one.

And if your implementation disagrees with a vector, the vector may be the thing that is wrong. Two of ours turned out to be unsatisfiable and were repaired during the cross-implementation pass. Report it rather than working around it locally — a private workaround is how two implementations quietly stop interoperating.

Specification defects, vector disputes and extension proposals all go to the issue tracker: codeberg.org/VARASYS/ZDDC.

Errata

A finalised specification version (one without the ~) is immutable. Corrections are recorded here and in the specification's own errata list; they never rewrite a published version in place, because someone has already built against those exact bytes.

No errata recorded.

← ZDDC Core (Technical Reference)