Renders the declaration as a sorted, escaped, line-oriented text form and
returns its lines. registry_digest() hashes exactly these bytes, so a
digest is never a black box: two registries that disagree can be diffed on
the text that produced the disagreement.
Arguments
- registry
A
registry()object.
Details
Hashing the R object directly is not an option. A resource() may carry a
processor(), which holds a closure, and a closure digests differently
across machines and builds because its environment, bytecode and source
references travel with it. A registry declaring a processor would appear to
change identity on every machine. The manifest reduces a processor to its
id, which is what the declaration actually promises.
Format
The first line names the format version, which moves independently of
schema_version because the two change for different reasons: a new field
in the stored form need not change how existing fields are rendered.
getaca-manifest 1
package yourpkg
remote https://yourpkg.example.org/registry.rds
key ed25519:9f8a...
auth data.example.org bearer EXAMPLE_TOKEN
register https://data.example.org/register
current backbone 2026-09
resource backbone 2026-06
sha256 3f9ac2...
size 1048576
license CC-BY-4.0
doi 10.5281/zenodo.123
url https://zenodo.org/record/123/backbone-2026-06.parquet
url https://mirror.example.org/backbone-2026-06.parquet
upstream release 2026-06
processor unzip-v2
resource backbone 2026-09
sha256 b104e7...
file backbone.parquet
part 91cc0d... 1048576
url https://zenodo.org/record/456/backbone-base.bin
part 4e77a1... 20481
url https://zenodo.org/record/456/backbone-2026-09.bin
combiner concatResources are sorted by name@version in the C locale, so the same
declaration renders identically wherever it is read. URLs keep declaration
order, which is load-bearing: mirrors are tried in the order given. Parts
keep it for a stronger reason, since the order is the one they are combined
in. Signing keys are sorted, since which one signs is a fact about the
signature rather than about the declaration. Absent and NA fields are
omitted rather than rendered as empty, since a key that is present carries a
value by construction.
Rendering an absent field as nothing is what let signing keys join the
manifest without a new format version, and then file, part, combiner,
auth and doi after them. A registry declaring none of them renders
exactly the bytes it always did, so every digest recorded before they existed
still identifies the state that produced it.
What is left out
created and policy are not part of the declaration. created says when
a state was written and policy supplies a default; neither changes which
bytes a name resolves to, and including either would mean an unchanged
registry took on a new identity for writing it out again. description is
prose, so a typo fix would invalidate a digest already recorded in
provenance.