feat: minted keys, VRF seeds, RFC 9162 proofs, history roots, tag URIs and a transparency log
Keys (spec/02 §2.4), the rule paperstack settled on:
- A work key is a Scholar-style citation key, a hyphen and the first four
Crockford base32 characters of SHA-256("scienting-key/1:" + identity),
where the identity is the first of doi, arxiv, isbn, pmid, pmcid and
openalex in same_as, else the folded title, year and family name. A
collision lengthens the later key by two characters; a key is minted
once and never recomputed. A document key adds .si, .v<seq> or .<type>
for versions other than the version of record.
- Every fixture key is now minted (hale2026harmonic-damb,
okafor2025solvent-acth, writer2027fixed-ynr7.v3, tiny2026tiny-j4qm), so
every node and record ID was re-minted and the docs rewritten to match.
The validator checks the document key against the work key and version
(doc.key.work) and the hash part against the identifier (doc.key.suffix).
vectors/keys.jsonl pins the cases paperstack's tests pin.
Review:
- Spot-check seeds are ECVRF-EDWARDS25519-SHA512-TAI proofs (RFC 9381),
implemented in tools/oracle/vrf.py in plain Python and reproduced
against the RFC's Example 16; the sample ranks by the VRF output. The
earlier Ed25519 seed could be ground by a dishonest checker.
- RFC 9162 inclusion and consistency proofs (crypto.inclusion_path,
verify_inclusion, consistency_proof, verify_consistency) with
scienting-proof/1, vectors/proofs.jsonl and two fixture records.
- document.json carries `history`, the root over the corrections, with
the empty-tree hash for none (spec/11 §11.5, rule doc.history).
- A provisional transparency log (spec/23): log entries, signed-note
checkpoints with key hashes as transparency logs share them, the rule
that a logged revocation beats a self-asserted time, and vectors.
- Reserved signature schemes cose and ml-dsa-65 (spec/08 §8.4).
Identifiers and text:
- urn:scienting: becomes tag:scient.ing,2026: (RFC 4151), since the URN
namespace was never registered.
- Unicode 16.0 is pinned for normalization and categories (spec/01 §1.4);
the checker refuses another version.
Checking:
- check.py: keys, proofs, VRF and checkpoint vectors; the proof and
checkpoint records; a check that every ID and hash the prose quotes
exists in the fixtures or vectors; three more broken packages
(history-wrong, key-suffix, key-work).
- stress.py: key, VRF, proof and checkpoint properties.
- Docs: a keys section in the concepts and FAQ, rationale entries for
keys, VRF, proofs, tag URIs and the Unicode pin, a "Looking ahead"
section, media-type registration and OCI distribution notes.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
307 files changed
+2698
-1497
No files matched your search
+10
-4
@@ -13,12 +13,18 @@ Every file is JSON or JSON Lines (one JSON value per line), and [spec/](../spec/
|
||||
## Why not keep using PDFs and page numbers?
|
||||
|
||||
A page number names a region, not a statement, and it changes between a preprint and the version of record.
|
||||
An address names a sentence or a cell by its ID, such as `hale2026harmonic#j06tfhn`.
|
||||
An address names a sentence or a cell by its ID, such as `hale2026harmonic-damb#v3063qv`.
|
||||
It can add a pin (the first six hex digits of the node's hash) and character offsets, which lets a reader check the address against the exact text ([spec/06 §6.1](../spec/06-anchors.md#61-addresses)).
|
||||
|
||||
An ID encodes no page, position or kind.
|
||||
The system mints it once from the document key, kind, text hash and occurrence, then freezes it ([spec/04 §4.2](../spec/04-identity.md#42-minting-node-ids)).
|
||||
|
||||
## Why does a key end in four odd characters?
|
||||
|
||||
`hale2026harmonic-damb` is the paper's key: the citation key a reader would use, then four characters of a hash of its DOI.
|
||||
Citation keys alone collide, between a preprint and its published version or two papers by one author in one year; the hash settles that, and any tool that knows the DOI can recompute it.
|
||||
A key is minted once and never recomputed, so a corrected title does not change a key someone has cited ([spec/02 §2.4](../spec/02-model.md#24-work-and-document-keys)).
|
||||
|
||||
## Why are numbers stored as strings?
|
||||
|
||||
Databases and JSON libraries rewrite numbers: `310.0` becomes `310` and `1.5260` becomes `1.526`, and the printed digits are part of what a paper says.
|
||||
@@ -96,12 +102,12 @@ The full comparison is [docs/comparison.md](comparison.md)
|
||||
|
||||
## What is its status and maturity?
|
||||
|
||||
Version 0.1.0 has 29 formats: 18 are `candidate` and 11 are `provisional`, as [registry/formats.json](../registry/formats.json) lists.
|
||||
Version 0.1.0 has 32 formats: 19 are `candidate` and 13 are `provisional`, as [registry/formats.json](../registry/formats.json) lists.
|
||||
A `candidate` format is complete, with vectors and fixtures, and ready to implement.
|
||||
A `provisional` one is complete and expected to change as implementations gain experience.
|
||||
The provisional formats are dataset, digitization, view, project, bundle, snapshot, draft-ids, exercise, submission, grade and checklist.
|
||||
The provisional formats are dataset, digitization, view, project, bundle, snapshot, draft-ids, exercise, submission, grade, checklist, log-entry and checkpoint.
|
||||
|
||||
The repository holds a reference checker (`tools/check.py`), 21 vector files, five valid packages, one of them also as a zip, and 28 deliberately broken packages ([spec/00 §0.4](../spec/00-introduction.md#04-status), [spec/22](../spec/22-conformance.md)).
|
||||
The repository holds a reference checker (`tools/check.py`), 25 vector files, five valid packages, one of them also as a zip, and 31 deliberately broken packages ([spec/00 §0.4](../spec/00-introduction.md#04-status), [spec/22](../spec/22-conformance.md)).
|
||||
|
||||
## What does it not do?
|
||||
|
||||
|
||||
Reference in new issue
Block a user