release: implement site registry v0.4 trust pipeline

This commit is contained in:
Nic Weyand 2026-09-13 12:22:05 -04:00
commit e26efc19fa
Signed by: nicweyand
SSH key fingerprint: SHA256:2te+ycJIQON/Wo/dH6+ZkFSQ4HnHWpetV2azx9E65dQ
67 changed files with 10698 additions and 640 deletions

View file

@ -1,65 +1,100 @@
# Consumer and compatibility contract
## Rust library
## Use the policy-enforced reader
Use `release::verify_signed(generation, publisher_signers, publisher_identity,
reviewer_signers)` once per production generation and reuse the returned reader.
`Registry::open(generation, trusted_pin)` is the lower-level path when the pin
distributor is also trusted for the complete review decision. `lookup(query,
limit)` returns evidence and complete ambiguity counts; `resolve_explained` returns a reviewed candidate or
a typed abstention reason with counts. Exact reverse views cover entity IDs,
URLs/domains, popularity and Curlie categories. Check the compiled example and API
docs for exact types. `selection_context` binds the full alternative set for
downstream query review. Preserve returned provenance, scopes, counts and attribution.
For a production generation, call
`release::verify_signed(generation, publisher_signers, publisher_identity,
reviewer_signers)` once and reuse the returned `Registry`. `Registry::open` is the
lower-level API for deployments that already trust an exact `COMPLETE.json`
SHA-256 for the whole publication decision.
For local integration, point a Cargo dependency at
`crates/argand-site-registry` inside an extracted standalone source tree. Once an
upstream repository is published, use its actual Git URL and a full reviewed `rev`
pin. Do not invent a crates.io version or track a mutable branch in production.
Both crates remain in this workspace; the atomic helper is a relative dependency.
`lookup` returns source evidence, candidates, ambiguity counts and attribution.
`resolve_explained` returns either one policy-qualified destination or a typed
abstention. It requires an approved name binding and approved edge under the
receipt's policy. Preserve the full response, especially `destination: null`,
`status`, counts, selected scope, evidence and attribution.
Reverse views cover entity IDs, exact URLs, hostnames, registrable domains,
source-specific popularity, Curlie categories and observations. They are audit
operations and do not imply ownership or admission.
## CLI and other languages
`lookup`, `resolve`, `entity`, `lookup-web`, `popularity`, `category`, `stats`,
`evaluate`, `verify` and the other commands emit JSON. The Python example
passes arguments directly to the native executable, preserving query text and the
entire response. A nonzero exit is an error. `destination: null` is a successful
abstention, not a request to pick the first lookup candidate. Render source names
as untrusted text and satisfy their source-specific attribution requirements.
Every CLI command emits one JSON value to stdout; typed export and diff commands
write bounded JSONL files. A nonzero exit is an error. A successful resolution
with a null destination is an intentional abstention, not an instruction to use
the first lookup result.
Use a bounded process or service wrapper appropriate to your workload. The Python
example has a 60-second timeout and invokes a fresh reader per request; for repeated
low-latency queries, use the reusable Rust reader. No hosted API or Python package
registry publication is claimed by this repository.
The Python example passes an argument array directly to the native CLI and keeps
its 60-second timeout and complete JSON response. Use the Rust reader for repeated
low-latency queries. No hosted API, crates.io release or Python package is claimed.
## SQLite, JSONL and license scope
Render all imported names, categories, URLs and evidence as untrusted data. Apply
source attribution and application-specific malware/content policy.
Distribute `registry.sqlite`, `COMPLETE.json`, `LICENSE_SOURCES.md` and
`ATTRIBUTION.json` together, plus the publisher signature when applicable. The
database contains audit records and source descriptions. Default JSONL export
omits descriptions and includes fact provenance plus an attribution envelope.
It is an assertion export, not a self-contained signed list of admitted routes.
Raw SQL inspection is useful for audit; it does not implement resolution policy.
## Current contracts
Code version 0.3.0 uses schema version 3 and `argand.site-rules/v3`.
It adds reviewer-trust enforcement for consumers, private authenticated SQLite
snapshots, exact-stream import checks, bounded outputs and metadata-bound identity
decisions. Schema/rule contracts remain versioned independently in
receipts. Unsupported contracts fail closed. Pin source releases,
compile consumers and replay fixed fixtures before upgrades. Preserve import and
review history; never mutate complete generations to migrate them.
Code version 0.4.0 uses writer schema 5 and `argand.site-rules/v4`.
`COMPLETE.json` uses `argand.site-registry/v2` and binds:
- authenticated `registry.sqlite` bytes;
- the active source coverage graph and exact PSL source;
- review policy and exact reviewer trust-root bytes;
- decision-time policy;
- source license and machine-readable attribution files; and
- entity, property, edge and rejection counts.
Normal `export` uses `argand.site-export/v2`, contains selected active nonrejected
facts, and marks every assertion `active`. `export-audit` uses the same schema with
mode `audit` and includes superseded/rejected states and rejection reasons. Neither
contains a list of resolver-approved routes.
Votes use `argand.site-vote/v1` and the OpenSSH namespace
`argand-site-registry-vote`. Consumers compile them under the exact receipt-bound
policy and trusted query time. Unknown schema or rule versions fail closed.
Emergency feeds use `argand.site-revocations/v1` and the separate
`argand-site-registry-revocations` namespace. Call `revocation::verify` against
the cached `Registry` and publisher trust root, then use
`resolve_explained_with_revocations`. The CLI accepts the same four feed arguments
on `resolve`. It blocks exact revoked names, edges, and equivalences before route
selection and can choose another approved edge. Verify each replacement against
the previously accepted feed to enforce cumulative continuity. Feeds expire after
seven days. A feed from a newer compatible generation may add blocks to a cached
generation, but reinstatement requires installing the exact full generation so
the consumer can recompute the authenticated superseding quorum.
CLI consumers pass the last feed and signature as `--previous-revocations` and
`--previous-revocation-signature` on subsequent `resolve` calls. The Rust API
passes the last `VerifiedRevocations` to `revocation::verify` before resolution.
Distribute `registry.sqlite`, `COMPLETE.json`, `LICENSE_SOURCES.md`,
`ATTRIBUTION.json`, and `COMPLETE.json.sig` together. Obtain publisher and reviewer
trust roots independently. Raw SQL copies and JSONL extracts do not implement
resolution policy, expiry, revocation continuity or signature verification.
## Compatibility
V1 source manifests remain readable as isolated legacy provider/scope streams.
A deliberate legacy-compatible build policy can replay v0.3 reviews, but strict
0.4 builds require votes and reviewer trust. Current readers accept v2 receipts;
rollback checks may open pinned v1 receipts with rules v1-v3 only to compare
revocation history.
Before upgrading, pin the source release by full signed Git revision, compile the
consumer and replay fixed fixtures. Preserve import, vote, observation and
revocation history. Never mutate a complete generation to migrate it. See
[MIGRATING-0.4.md](MIGRATING-0.4.md) and [FORMATS.md](FORMATS.md).
## Argand integration
UPSTREAM.json pins the exact Argand source baseline, including the beta agent's
selection-context API. The first standalone extraction preserves runtime Rust and
migration bytes. Argand main commit
`d9dfd1585ce21d9c4136bcc24fa01fe3bfb8ed6e` replaced its embedded workspace
crate with this signed `v0.3.0` release at full Git revision
`ac8282093d8a815c6227cff86e1f40714d510bcd`.
`UPSTREAM.json` records the original Argand extraction baseline and file hashes.
The last recorded downstream integration replaced Argand's embedded crate with
signed v0.3.0 revision `ac8282093d8a815c6227cff86e1f40714d510bcd` at Argand
commit `d9dfd1585ce21d9c4136bcc24fa01fe3bfb8ed6e`.
Develop the library here and update Argand through explicit reviewed revision-pin
changes. Each update must compare the old and new contracts and rerun Argand's
navigation compiler and API gates. Preserve existing registry receipts and public
navigation admission; a source dependency change does not activate a registry
generation or approve a destination.
Version 0.4 is handed off as a signed standalone revision. Argand should update its
full Git `rev` in a separate coordinated source/build window, compare contract
changes, and rerun navigation compiler, native resolver, API, abstention,
revocation and clean-process gates. Changing the code dependency does not activate
a registry generation or approve a public destination.