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
+33
-2
@@ -4,12 +4,12 @@
|
||||
|
||||
| Object | Is | Identified by |
|
||||
| --- | --- | --- |
|
||||
| Work | The intellectual work, across all its versions. | A key, and `same_as` identifiers: `doi:`, `arxiv:`, `isbn:`, `pmid:`, `pmcid:`, `url:` or `lode:`. |
|
||||
| Work | The intellectual work, across all its versions. | A work key ([2.4](#24-work-and-document-keys)), and `same_as` identifiers: `doi:`, `arxiv:`, `isbn:`, `pmid:`, `pmcid:`, `openalex:`, `url:` or `lode:`. |
|
||||
| Version | One expression of the work: a preprint, an accepted manuscript, the version of record, an erratum, Supporting Information, a draft. | The work's key and a version type, with an optional sequence number and date. |
|
||||
| Witness | One file of a version: a PDF, JATS XML, a LaTeX source archive, an HTML page, an EPUB, a Typst project. | The SHA-256 of its bytes. |
|
||||
| Document | The text established for one version from one or more witnesses. | A key, and a root hash per revision. |
|
||||
|
||||
A document's key is its work's key, with a suffix for anything other than the version of record: `cornell1995second`, `cornell1995second.si`, `dong2026machine.v2`.
|
||||
A document's key is its work's key, with a suffix for anything other than the version of record: `cornell1995second-saqk`, `cornell1995second-saqk.si`, `dong2026machine-1ard.v2`.
|
||||
Supporting Information is its own document, with its own pages, numbering and references, related to its article by `supplement-of`.
|
||||
A textbook is a work whose chapters are documents related by `part-of`.
|
||||
A draft is a document of kind `draft`.
|
||||
@@ -36,6 +36,7 @@ A renamed document keeps its old keys in `aliases`.
|
||||
| `hashing` | Yes | How content values are computed: `{scheme: "plain"}`, a team HMAC or a page-derived key ([5.8](05-hashes.md#58-keyed-hashes)). |
|
||||
| `root` | Yes | The root node's `node_hash`. |
|
||||
| `meta_hash` | Yes | The metadata hash ([5.9](05-hashes.md#59-the-metadata-hash)). |
|
||||
| `history` | Yes | The history root: the root of the tree over the package's corrections ([11.5](11-corrections.md#115-the-history-root)). |
|
||||
| `rev` | Yes | The revision: the index of the last correction applied, or 0. |
|
||||
| `counts` | Yes | `{nodes, leaves}`. |
|
||||
| `fidelity` | Yes | `{lowest, counts}`: the lowest level among leaves, or null when there are none, and the number of leaves at each level, computed as [8.2](08-fidelity.md#82-levels) defines. |
|
||||
@@ -62,3 +63,33 @@ The schema is `document.schema.json`.
|
||||
The witness's bytes are not part of the package; they live in the team's asset store, by SHA-256.
|
||||
The SHA-256 is the exact identity of one file.
|
||||
Because publishers stamp each download, two copies of one paper rarely share it; page fingerprints identify their pages instead ([7](07-geometry.md)).
|
||||
|
||||
## 2.4 Work and document keys
|
||||
|
||||
A work key names a work the way a reader would, and never collides: a Scholar-style citation key, a hyphen, and the first characters of a hash of the work's identity.
|
||||
|
||||
```text
|
||||
vaswani2017attention-a241
|
||||
└─── Scholar part ──┘ └hash┘
|
||||
```
|
||||
|
||||
**The Scholar part** is built as Google Scholar builds its BibTeX keys, from the CSL-JSON `meta` of the version:
|
||||
|
||||
1. the first author's family name: `family`, or the part of a `literal` name before a comma, else its last word that is not a suffix such as Jr. or III; folded to ASCII with NFKD, lower-cased, letters only, so `Müller` gives `muller` and `O'Brien` gives `obrien`; no author, or a name with no Latin letters, gives `anon`;
|
||||
2. the year of `issued`, when it has four digits, else nothing;
|
||||
3. the first word of `title` that is not a stop word, folded the same way, letters and digits only, with apostrophes removed and other punctuation splitting words; no such word gives nothing.
|
||||
|
||||
The stop words are `a an the of on in for to and or at by with from as into onto about toward towards via is are be its it this that these those`.
|
||||
|
||||
**The identity** is the work's first identifier among `doi`, `arxiv`, `isbn`, `pmid`, `pmcid` and `openalex` in `same_as`, in that order, written `<kind>:<value>` with a DOI's ASCII letters lower-cased.
|
||||
A work with none has the identity `meta:<title words>|<year>|<family>` from the same folded parts.
|
||||
`url:` and `lode:` identifiers name copies and claims, not the work, and never enter the identity.
|
||||
|
||||
**The hash part** is the leading bits of SHA-256 of `scienting-key/1:` followed by the identity, in UTF-8, written in lowercase Crockford base32, five bits a character: four characters, or, when another work in the store already holds that key, six, eight and so on until the key is free.
|
||||
A key is minted once, when the work enters a store, and never recomputed: a corrected title or a year revised later leaves it alone, while the hash of an identifier still shows which work the key names.
|
||||
A work key matches `^[a-z][a-z0-9]*-[0-9a-hjkmnp-tv-z]{4,51}$`.
|
||||
|
||||
**The document key** is the work key for the version of record, and the work key with a suffix for any other version: `.si` for Supporting Information, `.v<seq>` for a preprint, submitted, accepted or draft version with a sequence number, else a dot and the version type: `cornell1995second-saqk`, `cornell1995second-saqk.si`, `dong2026machine-1ard.v2`.
|
||||
A validator checks that the document key is the work key with the version's suffix (`doc.key.work`), and that a key whose identity is an identifier carries that identifier's hash (`doc.key.suffix`); a metadata identity may have been corrected since the key was minted, so it is not held to the key.
|
||||
Store, project and source keys keep the form `^[a-z0-9][a-z0-9._-]*$`, as do legacy document keys kept in `aliases`.
|
||||
`keys.jsonl` pins the Scholar parts, identities, hashes and document keys, with accented names, name suffixes, missing years and authors, and the lengthening that settles a collision.
|
||||
Reference in new issue
Block a user