feat: harden reviewed registry releases
All checks were successful
Standalone registry checks / check (push) Successful in 3m43s

This commit is contained in:
Nic Weyand 2026-09-13 01:19:27 -04:00
commit e83f43d00f
Signed by: nicweyand
SSH key fingerprint: SHA256:2te+ycJIQON/Wo/dH6+ZkFSQ4HnHWpetV2azx9E65dQ
37 changed files with 2856 additions and 286 deletions

75
docs/PUBLISHING.md Normal file
View file

@ -0,0 +1,75 @@
# Dataset publisher runbook
This runbook creates a reviewable candidate and a signed activation. Source update,
review and release keys are separate authorities. Scheduled jobs may acquire,
import and build candidates; they do not approve, sign or activate destinations.
## Trust roots and local state
Keep cache, mutable store, immutable generations, reviewer keys, release keys and
consumer trust files outside the checkout. An OpenSSH reviewer trust file contains
one accepted principal and public key per line:
```text
operator@example.org ssh-ed25519 REVIEWER_PUBLIC_KEY
```
Distribute the release publisher public key to consumers through an independent
authenticated channel. Do not put private keys, production trust files or source
datasets in Git or CI. The isolated source CI runner has none of these files.
## Candidate acceptance
Run `update` or the explicit download/import/build commands from the operator guide.
For every candidate generation:
1. Verify its externally recorded receipt pin with `verify`.
2. Run `stats` and compare source snapshots, selected sources, facts, rejections,
reviews, database bytes and upcoming expiry with the prior accepted generation.
3. Run `diff` against the prior pin. Investigate every source-selection, identity,
name, property, edge, popularity, review and equivalence change.
4. Use `lookup`, `entity`, `lookup-web`, `popularity` and `category` to inspect exact
source evidence and conflicts. Popularity never proves ownership.
5. Replay the maintained evaluation corpus with `evaluate`; require zero judgment
mismatches and compare latency with a documented hardware/process baseline.
## Authenticated decisions
Create a bounded review JSON from the exact candidate fingerprint and evidence.
Sign its exact bytes and append it through the CLI:
```bash
ssh-keygen -Y sign -n argand-site-registry-review \
-f /secure/reviewer-key review.json
argand-site-registry review --database /data/registry/import.sqlite \
--generation /data/registry/candidate --pin "$CANDIDATE_PIN" \
--decision review.json --signature review.json.sig \
--allowed-reviewers /secure/reviewer-allowed-signers \
--identity operator@example.org
```
Identity equivalence decisions use the same signed JSON and reviewer namespace.
Rebuild after appending decisions, then repeat the complete diff and evaluation.
The release command re-verifies every retained reviewer signature against the
current reviewer trust file. Missing, altered or no-longer-trusted proofs stop it.
## Sign and activate
```bash
argand-site-registry sign --generation /data/registry/reviewed \
--pin "$REVIEWED_PIN" --key /secure/release-key \
--allowed-reviewers /secure/reviewer-allowed-signers
argand-site-registry activate --generation /data/registry/reviewed \
--current /data/registry/current.json \
--allowed-signers /secure/release-allowed-signers \
--identity registry-publisher
```
Record the source commit, candidate and accepted receipt pins, typed diff, evaluation
report, reviewer trust-file digest, release signer identity and activation receipt
in an immutable operator log. Activation refuses a rollback that drops a distributed
revocation. Deliver a new current pointer/pin to every consumer and bound their caches.
For an incident, append a signed revocation, rebuild with full history, inspect,
evaluate, sign and activate. Preserve the suspect source bytes, generation and proofs.
Follow [SECURITY.md](../SECURITY.md) for private reporting and key compromise.