diff --git a/index.html b/index.html index 52d4a14..ebabf23 100644 --- a/index.html +++ b/index.html @@ -175,9 +175,21 @@
zddc-server is a small Go binary purpose-built to serve ZDDC archives. Any web server gives you online mode; zddc-server adds things a generic web server can't:
.zddc files. Behind a reverse proxy that authenticates users and sets an X-Auth-Request-Email request header, zddc-server consults YAML .zddc files in directories — cascading bottom-up; deeper rules override. Common shapes (paired open/closed projects + third-party-restricted vendor folders) are documented with worked examples in the access-control reference. No database, no admin UI.ZDDC_OPA_URL and the same .zddc files become inputs to your engine instead of ours. Wire format is OPA-canonical (POST /v1/data/zddc/access/allow). Default mode adds zero new dependencies; external mode is a configuration flip..zddc files. Behind a reverse proxy that authenticates users and sets an X-Auth-Request-Email request header, zddc-server consults YAML .zddc files at every directory along the path. The cascade walks root→leaf; the closest match wins. Five verbs (r read, w overwrite, c create, d delete, a admin / edit ACL) gate every operation. An empty grant (e.g. "*@vendor.com": "") is an explicit deny. Common shapes (paired open/closed projects, third-party-restricted vendor folders) are documented with worked examples in the access-control reference. No database, no admin UI..zddc may declare named roles whose members are email patterns; permissions then reference the role name instead of pasting the same wildcard everywhere:
+roles:
+ qc-reviewers:
+ members: ["*@quality.org", "alice@example.com"]
+acl:
+ permissions:
+ qc-reviewers: rwd
+ "*@example.com": r
+Role definitions cascade like everything else; a child .zddc redefining the same role name shadows the ancestor for that subtree.archive/<party>/issued/ or archive/<party>/received/ enforces write-once via a verb mask: ancestor grants are reduced to r only, while a .zddc placed at the WORM folder itself can still grant rc (create-but-not-overwrite) to specific principals — that's how a doc controller drops a fresh transmittal into the immutable record. Root admins (the admins: list in the root .zddc) bypass the mask as the deliberate escape hatch for mis-filed documents..zddc file into an empty directory and the canonical project layout (working/, staging/, archive/<party>/{mdl,incoming,received,issued}/) materialises on the first write into each path — never on bare reads. Folder names are matched case-insensitively, so an existing Working/ is reused rather than shadowed by a new working/ sibling. Each authenticated viewer sees a virtual working/<your-email>/ entry; first write makes it real.ZDDC_OPA_URL and the server POSTs the request's user, path, action, and the full .zddc cascade chain to /v1/data/zddc/access/allow. Decisions are cached per (user, path, action) with a configurable TTL (ZDDC_OPA_CACHE_TTL); failures fail closed by default (ZDDC_OPA_FAIL_OPEN=1 flips it). The bundled NIST AC-6 strict-cascade preset is dumpable via --print-rego=federal. Default mode adds zero new dependencies; external mode is a configuration flip./.profile/effective-policy?path=<url> to see the resolved ACL chain at any path — every level's grants, the role evaluation, the final verb-set. Useful when a permission isn't behaving the way the operator expected..archive URL space. GET /Project/.archive/123-XYZ.html resolves to the canonical revision file at request time. Computed from filenames; no cache, no separate index file.The binary has the current-stable build of all five tools baked in at compile time. They appear automatically at the right paths under ZDDC_ROOT:
Incoming, Working, or Staging directory and its subtreeWorking directory and its subtreeStaging directory and its subtreeworking/ directory and its subtreestaging/ directory and its subtreeworking/, staging/, or archive/<party>/incoming/ subtreearchive/<party>/ — the per-party Master Deliverables List, served from a built-in default schema unless the party's .zddc declares a custom oneFolder names are case-insensitive — Working/, working/, and WORKING/ all match the working/ rule.
ZDDC_ROOT=/srv/zddc ./zddc-server
To override a tool at any path: drop a real .html file there — that file wins over the baked-in version. To pin a different version, write an apps: entry in any .zddc file along the path:
# <project>/.zddc
diff --git a/reference.html b/reference.html
index a001667..bf96489 100644
--- a/reference.html
+++ b/reference.html
@@ -914,19 +914,46 @@ date = 4DIGIT "-" 2DIGIT "-" 2DIGIT
Search the deliverable's own tracking number across all transmittal folders in issued/ and received/. Every folder containing that number is part of its history: which package first carried it, what the response was, which resubmittal carried the revision, and what the final outcome was.
-
+
- 9. Transmittal workflow
- Each third party (client, contractor, vendor, etc.) has a separate subfolder. All communication with that party lives in one place.
+ 9. Project layout & transmittal workflow
+ A project is a directory containing a single .zddc file. The server materialises the canonical folders below on the first write into them — drop a .zddc in an empty directory, point zddc-server at it, and the layout comes to life as content arrives. Folder names are matched case-insensitively, so a manually-created Working/ is reused rather than shadowed by a new working/.
project/
- {party-name}/
- incoming/ ← transmittals received from party, awaiting acceptance
- received/ ← permanent record of accepted transmittals from party
- issued/ ← your copies of transmittals sent to party
+ .zddc ← the only file an operator must create
+ working/ ← user-owned drafting workspace; mdedit
+ for markdown, browse for uploads.
+ Each authenticated user with access
+ sees a virtual <your-email>/
+ subfolder; first write materialises it.
+ staging/ ← outbound-transmittal preparation. A
+ transmittal-named mkdir here also
+ creates a same-named drafting folder
+ under working/ as a sibling space.
+ reviewing/ ← virtual cross-reference of in-progress
+ review responses; never on disk.
+ Notes live in working/<rs-name>/.
+ archive/ ← formal record of issued/received
+ transmittals, organised by party.
+ {party-name}/ ← one per counterparty AND one for
+ ourselves; self-folder is symmetric.
+ mdl/ ← Master Deliverables List for that
+ party. Visiting the folder opens the
+ table editor (mdl.table.html).
+ Default schema is built into the
+ server; per-party overrides via a
+ tables: { mdl: ./mdl.table.yaml }
+ entry in the party's .zddc.
+ incoming/ ← that party's drop point. Auto-own
+ .zddc grants the creator of each new
+ subfolder full control.
+ received/ ← permanent record of incoming we've
+ accepted (WORM — write-once read-many).
+ issued/ ← permanent record of what we sent to
+ that party (WORM).
- 5-step workflow:
+ 5-step transmittal workflow:
@@ -974,6 +1001,15 @@ project/
What SHA-256 gives you: Mathematical fingerprint of file contents. Single byte change → hash changes. When acknowledgment records hashes, you can verify years later that the file is identical to what was transmitted.
+
+ Drafting a response transmittal
+ Submittals from counterparties (tracking numbers containing -SUB- at status IFR or IFA) require a response transmittal whose status starts with RS (RSA, RSB, RSC, …). The drafting flow uses the same staging↔working pairing as a fresh outbound:
+
+ - Create
staging/<YYYY-MM-DD>_<tracking> (RSA) - <title>/. The date is the planned issue (response-due) date.
+ - The server mirrors the folder name into
working/; reviewer notes and the response payload are drafted there.
+ - The
reviewing/ virtual surface lists each in-progress response paired with the source submittal in archive/<party>/received/.
+ - When the response is ready, files move from
working/ into staging/ for sign-off, then through the standard 5-step transmittal flow into archive/<party>/issued/. Both the staging and working folders are deleted at issue time.
+