Files
alexmandClaude 516148146f feat: publish the package from CI, and clean up its references
Publishing
- .gitea/workflows/publish.yml publishes paperspec to the instance's PyPI
  registry (/api/packages/infra/pypi) when a v* tag is pushed: it checks
  the repository, builds the sdist and wheel, refuses to upload unless the
  built version equals the tag, runs twine check --strict, and uploads
  with the secrets PACKAGE_USER and PACKAGE_TOKEN (--skip-existing, so a
  rerun on the same tag is safe). Run by hand, it refuses anything but a
  tag.
- pixi dev environment: twine >= 6.1 (the first that reads Metadata 2.4),
  and `dist` (sdist and wheel) replaces the `wheel` task.
- deploy/README.md: how to set up the secrets, release a version, and
  install from the registry with pixi, uv or pip, tying paperspec to the
  registry where the installer allows it.
- CONTRIBUTING.md "Releasing": a tag versions the package; a format
  change takes the new format version as the top CHANGELOG heading, and a
  code-only release takes the next patch as a subsection, as 0.1.1 does.
- pyproject: fallback_version 0+unknown for source trees without git; the
  license expression is Apache-2.0 AND CC0-1.0, for the code and the data
  the wheel carries.

Cleanup (from an audit of every reference to the package)
- spec/00 lists src/ (the package) and tools/ (how to run it), and no
  longer says the reference implementation is not a library.
- Stale explanations fixed in pixi.toml, .gitignore, the Caddyfile, the
  vectors, context, sql and tools READMEs, docs/examples.md, docs/faq.md,
  spec/01, docs/rationale.md and docs/comparison.md: the commands, what
  they need (the tools extra), the fixture folder hale2026harmonic-damb,
  and three lines that held two sentences.
- tools/README.md counts all six commands, says what needs which extra
  (package.validate and corrections.gate need [schema]), and that the
  vectors ship but the fixtures they name do not.
- The CLI's install and clone hints point at the registry instructions and
  an https clone URL; schema.py raises an ImportError naming
  paperspec[schema], as crypto.py does for [crypto].
- check's Unicode check now guards the package's pinned constant.
- site skips build/, dist/ and *.egg-info.
- CHANGELOG 0.1.1 describes the final state.

pixi run check passes (as `python -m paperspec check`); the rebuild is
byte-identical. pixi.lock needs `pixi lock` for twine before pushing: the
publish workflow installs with --locked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 09:41:26 -04:00

133 lines
9.9 KiB
Markdown

# FAQ
This page answers questions about paperspec, a set of file formats that give every sentence and table cell of a scientific paper a permanent address.
Newcomers, implementers of a reader, writer, converter or checker, and experts who know JATS (Journal Article Tag Suite), TEI (Text Encoding Initiative) or W3C Web Annotations can all use it.
Each answer gives the plain statement first, then the precise one, then the chapter that defines it.
The repository is <https://git.scient.ing/infra/paperspec>, and the formats are at version 0.1.0.
## Can I read these files without special software?
Yes.
Every file is JSON or JSON Lines (one JSON value per line), and [spec/](../spec/README.md) specifies every format. [The examples](examples.md) read a package with a few lines of Python.
## 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-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.
Canonical JSON, the byte-exact form used for hashing, writes numbers as ECMAScript writes a double, so it would erase the same difference.
A decimal that carries meaning is a string.
JSON numbers are for counts, indexes, offsets, sizes and geometry ([spec/01 §1.2](../spec/01-conventions.md#12-numbers)).
## What happens when a better converter comes along?
The system aligns the new reading with the established document, sentence by sentence.
A sentence the alignment pairs keeps its ID even where the readings disagree, which catches a lost superscript instead of accepting it.
Every disagreement, and every sentence found in only one reading, becomes a suspect, a doubtful reading raised for review.
Nothing changes until a correction passes the gate, the rules that refuse, for example, a digit change with no crop of the page image as evidence.
Converting the same input again with the same converter mints the same IDs ([spec/05 §5.6](../spec/05-hashes.md#56-alignment), [spec/11 §11.4](../spec/11-corrections.md#114-the-gate), [spec/04 §4.2](../spec/04-identity.md#42-minting-node-ids)).
## Do I need receipts, rights records and spot-checks for a personal library?
You need no receipts and no spot-checks.
A receipt is a signed record that a named person compared nodes with the page image, and a spot-check is a second reviewer's sample of that work.
One person can leave both out.
Each source file still carries a rights record, though the record can say little: the license as printed, a `basis` of `unknown`, and no uses, each of which then counts as unknown ([spec/14 §14.1](../spec/14-rights.md)).
The fields are defined so that a personal library loads into a team's store later without conversion ([spec/00 §0.4](../spec/00-introduction.md#04-status)).
## Is a model allowed to correct a document?
A model may propose corrections and answer suspects, under the same gate as a person, and its corrections record the model and the run as author.
Only a named person can sign a receipt, and a model's annotation stays `proposed` until a person confirms it ([spec/11 §11.2](../spec/11-corrections.md#112-every-correction-records), [spec/18 §18.3](../spec/18-layers.md#183-the-annotation)).
## Why are annotations W3C Web Annotations?
Tools that follow the W3C Web Annotation model can read the standard parts of these annotations.
A layer, the file that groups annotations, follows the [W3C Web Annotation Data Model](https://www.w3.org/TR/annotation-model/), a W3C Recommendation of 2017.
Each target holds an `AnchorSelector` carrying a `scienting-anchor/1` record, followed by a standard `TextQuoteSelector` for tools that do not know the anchor selector.
(The `scienting-` prefix is the formats' namespace, separate from the repository's name.)
The formats use no `TextPositionSelector` or `FragmentSelector`.
The anchor adds what the standard selectors lack: the node's ID, its hashes, and a defined outcome (`current`, `changed-below`, `moved`, `reattached` or `stale`) when the text has changed.
The Web Annotation model alone is the better-established choice where an annotation needs none of that.
Whether a generic Web Annotation client displays an `AnchorSelector` is untested.
See [the comparison](comparison.md).
## What is the difference between a claim and an annotation?
A statement true independently of the paper, such as "K_r is the bond force constant of the AMBER energy", is a claim.
A claim has to be checked against evidence, so it belongs in a store of checked claims outside these formats, which define no claim semantics.
A statement about reading the paper, such as "the authors pass quickly over the scaling here", is an annotation in a layer, attributed and unchecked ([spec/18 §18.1](../spec/18-layers.md#181-one-rule-decides-what-is-a-claim-and-what-is-a-layer)).
## Can a team share notes on a paywalled paper?
Yes, without sharing the paper.
A checks-only package withholds all text and keeps IDs, labels, pages, boxes and keyed hashes.
A public layer swaps each quotation for keyed hashes, under a key derived from the paper's page fingerprints, so a reader checks and shows it only over their own copy.
The hash must be keyed because anyone can recover a plain hash of a short text such as `310.0` by hashing guesses ([spec/12 §12.5](../spec/12-package.md#125-text-policies), [spec/05 §5.8](../spec/05-hashes.md#58-keyed-hashes), [spec/06 §6.3](../spec/06-anchors.md#63-keyed-anchors)).
Whether a team may share notes on a paper this way is a question for its own counsel; nothing here is legal advice.
## How does this differ from JATS or TEI?
They overlap in subject, not in job.
JATS, the [Journal Article Tag Suite](https://www.niso.org/publications/z3996-2024-jats) (ANSI/NISO Z39.96-2024), is an XML format for publishers and archives to exchange journal content. paperspec does not replace it.
A JATS file is one kind of witness (a source file), an input from which a document is established.
None of the 312 elements in the [JATS 1.4 Archiving tag library](https://jats.nlm.nih.gov/archiving/tag-library/1.4/) marks a sentence; its smallest text unit is the paragraph, `<p>`.
TEI, the Text Encoding Initiative, has a sentence-like [`<s>` element](https://tei-c.org/release/doc/tei-p5-doc/en/html/ref-s.html) and keeps both readings of a corrected passage with [`<corr>` and `<sic>`](https://tei-c.org/release/doc/tei-p5-doc/en/html/ref-corr.html).
The encoder assigns its `xml:id`, and the guidelines [recommend it for durability](https://tei-c.org/release/doc/tei-p5-doc/en/html/SA.html).
paperspec mints and retires IDs by rule, keeps corrections as separate records with evidence, and hashes each node.
Keep JATS for publisher and archive exchange and TEI for general scholarly text encoding.
A TEI file is a witness of kind `xml` ([spec/02 §2.3](../spec/02-model.md)).
The full comparison is [docs/comparison.md](comparison.md)
## What is its status and maturity?
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, checklist, log-entry and checkpoint.
The repository holds a reference checker (`paperspec check`), 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?
It is built for a team-scale corpus of hundreds of documents, not hundreds of millions of papers.
It does not replace publisher interchange formats; it reads JATS as a witness.
It does not fix what a converter reads wrongly.
It records the reading and raises disagreements as suspects, and a correction is checkable.
It is not a search engine, a citation index or a recommendation feed ([docs/overview.md](overview.md)).
## How do I add a node kind or a run kind?
A node kind is a type of document part, such as `sentence`; a run kind is a type of inline content within a sentence, such as `math`.
Propose either with the vector or fixture that shows it.
A new kind is a minor version ([spec/00 §0.3](../spec/00-introduction.md#03-format-identifiers-and-versions)).
See [CONTRIBUTING.md](../CONTRIBUTING.md).
## What are the `paperspec` commands for?
`paperspec build` builds the fixtures and vectors.
`paperspec check` recomputes and checks every one, and `paperspec load` loads packages into SQLite.
The oracle's modules in `src/paperspec/` compute every expected value, so that none is typed by hand.
The other repositories of the project install them as the Python package `paperspec`; independent implementations follow the specification ([tools/README.md](../tools/README.md)).