Files
paperspec/spec/02-model.md
T
alexmandClaude a09d158e16 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>
2026-10-14 23:21:57 -04:00

7.5 KiB

2. Works, versions, witnesses and documents

2.1 Four objects

Object Is Identified by
Work The intellectual work, across all its versions. A work key (2.4), 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-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.

Keys are immutable once a document is shared. A renamed document keeps its old keys in aliases.

2.2 document.json

Property Required Holds
format Yes scienting-doc/1.
key Yes The document key.
store No The store that holds it, when the package says so.
aliases No Earlier keys.
kind Yes article, supplement, chapter, book, thesis, report, draft, course-material or other.
work Yes {key, same_as}.
version Yes {type, seq?, date?}, where type is preprint, submitted, accepted, version-of-record, erratum, retraction, supplement, draft or other.
relations Yes A list of {type, target}; type is supplement-of, part-of, version-of, erratum-of, retraction-of or translation-of, and target a key, optionally store-qualified.
meta Yes The version's bibliographic record, as one CSL-JSON item.
language Yes A BCP 47 tag.
license No The document's license as stated: {spdx?, text?, url?}. Rights are per witness (14).
policy Yes The text policy: full, or checks-only (12.5).
hashing Yes How content values are computed: {scheme: "plain"}, a team HMAC or a page-derived key (5.8).
root Yes The root node's node_hash.
meta_hash Yes The metadata hash (5.9).
history Yes The history root: the root of the tree over the package's corrections (11.5).
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 defines.

The schema is document.schema.json.

2.3 witnesses.json

witnesses.json is an object with one property, witnesses, a non-empty list in which each witness is:

Property Required Holds
id Yes The witness ID: seven letter-first base32 characters encoding the SHA-256, as 4.6 defines.
sha256 Yes The SHA-256 of the file.
size Yes Its size in bytes.
kind Yes pdf, jats, latex, html, epub, typst, xml, image or other.
media_type Yes Its media type.
pages No The number of pages, for a witness that has pages.
text_layer No Whether a PDF has a text layer; a scan has none.
version_label No The version as the witness labels it.
origin Yes {source, url?, doi?, retrieved_at?, note?}, where source is publisher, repository, preprint-server, author, team, licensed-delivery, library or other.
rights Yes The rights record, scienting-rights/1 (14).

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).

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.

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.