The first registry
Make the key, initialise the registry, ask it what it holds, and read files again.
The wizard does this for you. This page is what it does, for when you would rather do it yourself.
A registry is a directory. It holds nils.toml, the databases (on SQLite), and the key store.
The key
Pseudonyms are derived from a key. The same subject digested twice under the same key gets the same code; under another key, another code. That is what makes two registries agree or disagree, so the key is the one secret that matters.
mkdir -p /srv/nils/registry
nils --registry /srv/nils/registry key add nils
The passphrase is read from standard input, one line. Choose it the way you choose a password and keep it where you keep passwords: without it you cannot rebuild the key store from a backup. The command prints the key’s name, its length and a fingerprint, and never the key itself. nils key list lists the keys the same way, as the desk’s Keys panel on Backups does.
Initialise
nils --registry /srv/nils/registry init --key nils
It prints the registry’s id, its schema version and its pseudonym scheme:
initialised /srv/nils/registry on sqlite: registry 2caa20b0-..., schema version 106,
pseudonyms blake2b-8 from key nils
blake2b-8 is the subject code generator: a person’s code is the keyed 8-byte BLAKE2b of their identifier (of a personnummer, its twelve digits) under the registry’s key, written as 16 hex characters. --scheme blake2b-32 makes a longer code instead. A registry keeps the scheme it was made with.
Ask it what it holds
nils --registry /srv/nils/registry status
A fresh registry says so plainly: epoch 0, no jobs, no batches. The epoch is the registry’s own clock; it moves when something changes what a question would answer.
NILS_REGISTRYin the environment saves typing--registryevery time. The engine also accepts the flag after the subcommand forserve.
Reading a manufacturer’s files again
A newer engine may read more of a file than the one that digested it, such as PulseSequenceName (0018,9005) since 1.0.0-alpha.57, or a pack may come to read private elements it did not before. Rather than digest the whole archive again, re-read one manufacturer’s MR files:
nils digest /data/source --reread "GE MEDICAL SYSTEMS"
nils digest /data/source --reread "Siemens Healthineers" --reread-exact Siemens
It reads, without walking the tree, only the files the registry holds for that manufacturer’s MR series, every file of each series, a series at a time. Nothing is marked gone, and the fingerprints of those series are derived again. --reread compares the manufacturer without its case and --reread-exact with it, which matters for Siemens: its XA scanners write Siemens and its older ones SIEMENS, so --reread-exact Siemens takes the XA fleet alone. Both repeat.
A re-read that was stopped, failed or was killed is continued by the next one, which counts the files already written as unchanged and does not read them again; --restart starts over. It runs at the rate the parsers and the storage allow, so on a large archive it takes hours: some 17 million files took about seven hours at 670 files a second. Reclassify afterwards to let the pack read what was added.
Postgres instead of SQLite
For more than one machine, or for a registry that outgrows a file:
nils --registry /srv/nils/registry init \
--backend postgres --dsn "postgres://nils@db.example.org/nils" --schema nils
The linkage store goes into <schema>_linkage. Everything else in this documentation is unchanged. The dsn may be left out of nils.toml and given as NILS_DSN at run time, so the password is not in a file.
Next: run it.
Updated 17 October 2026