JSON-LD context
Three readers use this page. A newcomer, such as a student who has not met these formats, can read it from the top. Each term is defined where it first appears, and the example comes from the fixtures. An implementer who is writing a reader, writer, converter or checker will find the exact behavior, the defining chapter, the files that pin it, and the traps in "Using the context". An expert who knows the neighboring standards will find the status of the formats and a short comparison in "Status and comparison".
What the context is
Annotations are notes attached to a passage of a paper, such as a plain-language explanation of a term or a question for a study group. Annotation layers store them as JSON, a text format for structured data, one annotation per line. A shared standard, the World Wide Web Consortium (W3C) Web Annotation Data Model, says what an annotation contains: a body (the note), a target (what it is about) and a selector (how to find the passage inside the target).
JSON-LD is JSON plus a rule that gives every field name a global meaning, written as an IRI (an identifier shaped like a web address).
The rule lives in a context, a file that maps short field names to IRIs.
Two tools that read the same context agree on what target or status means, even if they know nothing else about each other.
scienting-1.jsonld is the context that makes every annotation layer valid JSON-LD, together with the W3C Web Annotation context.
The Web Annotation context supplies Annotation, body, target and selector.
This one supplies the terms the formats add.
Its address is https://paperspec.scient.ing/context/scienting-1.jsonld, which is this file as the project's website serves it, with the media type application/ld+json and a header that lets a browser fetch it from any page.
The terms it maps are listed at https://paperspec.scient.ing/vocab, and each term's IRI is a fragment of that page.
A processor that cannot reach the site loads the copy in this folder in its place.
Every layer and every annotation lists both contexts, Web Annotation first:
{"@context": ["http://www.w3.org/ns/anno.jsonld", "https://paperspec.scient.ing/context/scienting-1.jsonld"]}
The scienting- prefix is the formats' namespace, as in scienting-layer/1 and scienting-anchor/1.
The repository's name, paperspec, is a separate matter.
An example from the fixtures
fixtures/records/layer/annotations.jsonl holds nine annotations on the example paper hale2026harmonic-damb.
The first is a gloss, an explanation for a novice, of the phrase "bond force constant".
Shortened, it reads:
{"@context": ["http://www.w3.org/ns/anno.jsonld", "https://paperspec.scient.ing/context/scienting-1.jsonld"],
"type": "Annotation", "motivation": "describing", "status": "confirmed",
"body": {"type": "TextualBody", "kind": "gloss", "audience": "novice",
"value": "A *harmonic* term treats a bond like a spring: ..."},
"target": {"type": "SpecificResource",
"source": "tag:scient.ing,2026:doc:smithlab/hale2026harmonic-damb",
"selector": [
{"type": "AnchorSelector",
"anchor": {"format": "scienting-anchor/1", "node": "rr20tev",
"span": [111, 130], "quote": {"exact": "bond force constant", "...": "..."}, "...": "..."}},
{"type": "TextQuoteSelector", "exact": "bond force constant",
"prefix": "rm{eq}})^2$$ where $K_r$ is the ", "suffix": " and $r_\\mathrm{eq}$ the equilib"}]}}
The Web Annotation context defines type, motivation, body, target, source, selector, exact, prefix and suffix.
This context defines kind, status, audience, AnchorSelector and anchor.
What it defines
The file defines 23 terms.
Twenty-two map to IRIs under https://paperspec.scient.ing/vocab#: format, kind, status, receipt, layer, audience, visibility, purpose, project, docs, pin, role, symbol, verdict, reason, reference, for, generator, exercise, anchor, rights_use and the class AnchorSelector.
Three are renamed: for is sct:questionFor, generator is sct:generatedBy, and rights_use is sct:rightsUse.
The twenty-third, total, maps to totalItems in the ActivityStreams namespace.
Two terms carry a type rule.
A processor reads layer as an IRI, and it always reads docs as a set, so a one-element list stays a list.
The file declares anchor and exercise as JSON literals ("@type": "@json", a JSON-LD 1.1 feature, which is why the file sets "@version": 1.1).
A JSON-LD processor then keeps a scienting-anchor/1 record intact instead of expanding it.
An anchor holds hashes (fixed-length fingerprints of text) and a span, a pair of character offsets whose order carries meaning.
Expansion would drop the anchor's unmapped field names (JSON-LD 1.1 API, expansion step 13.3) and would give its arrays no order (JSON-LD 1.1 §4.3).
The anchor selector and its fallback
A selector says how to find a passage inside a source.
The standard selectors work from the passage's text or its position.
TextQuoteSelector holds the quoted text (exact, required) and optionally some text before and after it (prefix, suffix).
TextPositionSelector holds start and end offsets, which the model itself calls "very brittle with regards to changes to the resource" (Web Annotation Data Model).
AnchorSelector is the custom selector of these formats.
It carries a scienting-anchor/1 record: the document key, the node ID, the node's own_hash and node_hash as they were when the anchor was made, an optional span in Unicode code points, a quote, and the document revision rev (spec/06 §6.2).
A reader can use the hashes to resolve the anchor against a corrected document and report one of five outcomes: current, changed-below, moved, reattached or stale (spec/06 §6.5).
A standard selector cannot do that.
A tool that does not know AnchorSelector cannot use it.
An annotation's selector list puts the AnchorSelector first and, where the anchor has a quote, a standard TextQuoteSelector after it, for tools that do not know ours (spec/18 §18.3).
The formats use no TextPositionSelector and no FragmentSelector.
Such a tool still reads the annotation's body and its TextQuoteSelector; the context matters only to tools that process the data as linked data.
That is the repository's statement; no Web Annotation client has been tested against these files.
The fallback is not always there.
Three of the nine fixture annotations have only an AnchorSelector (the section-level question, the generated annotation on a figure and the exercise on a table), because the anchor points at a container and has no quote.
Using the context
- Writer: Put both URLs (web addresses), in the order shown, in
@contextoflayer.jsonand of every line ofannotations.jsonl. Chapter 18 defines layers (§18.2), annotations (§18.3) and bodies (§18.4). - Reader: Follow chapter 6 to resolve an anchor.
The file
vectors/resolve.jsonlresolves seventeen anchors againstfixtures/packages/hale2026harmonic-damband gives every outcome. - JSON-LD processor: Use a JSON-LD 1.1 processor; the context relies on
@jsonand@version1.1. <<<<<<< HEAD - Checker:
schemas/annotation.schema.jsonandschemas/layer.schema.jsonvalidate the files.paperspec checkalso checks that each annotation's ID derives from its content and that the receipt atfixtures/records/layer/receipt.jsoncovers eachconfirmedannotation.
The traps:
- No test vector pins the context, and nothing here runs a JSON-LD processor on it;
paperspec checkandpaperspec siteread only its term IRIs. ||||||| parent of4fa326d(First implementation (#1)) ======= - Checker:
schemas/annotation.schema.jsonandschemas/layer.schema.jsonvalidate the files.tools/check.pyalso checks that each annotation's ID derives from its content and that the receipt atfixtures/records/layer/receipt.jsoncovers eachconfirmedannotation.
The traps:
- No test vector pins the context, and nothing in
tools/readsscienting-1.jsonld.
4fa326d(First implementation (#1)) The schemas require only that@contextbe an array of at least two non-empty strings; they do not check the URLs. A file with a wrong context can pass the checker and still expand wrongly.
@contextis part of an annotation's content hash (the hash covers everything exceptstatus,receiptandmodified). Rewriting or reordering the array changes the hash that a receipt covers.formatis one term for two jobs: the layer'sformat(scienting-layer/1) and a text body'sformat(text/markdown). The scienting context maps it tosct:format. The Web Annotation context mapsformattodc:formatand protects none of its terms, and in an array of contexts the later definition wins (JSON-LD 1.1 §4.1), so listing this context second makesformatmeansct:format.- A consumer that does not use a field must still preserve it when it rewrites a file. A tool that rewrites layers must not drop the scienting terms (spec/00 §0.4).
- The
TextQuoteSelectorrepeats the anchor's plain quotation, and is left out when the quote is hashed (over 200 code points) or keyed (spec/18 §18.3), so a public layer never shows text that a keyed anchor withholds.
Status and comparison
The specification is version 0.1.0.
scienting-layer/1, scienting-anchor/1 and scienting-exercise/1 are candidate in registry/formats.json.
The specification defines candidate as "Complete, with vectors and fixtures, and ready to implement."
The context file is normative (spec/00 §0.5).
The W3C Web Annotation Data Model is a 2017 W3C Recommendation and the general standard for annotating web resources, with existing clients that form an ecosystem these formats do not have (Web Annotation Data Model).
Its standard selectors carry no content hash of the target text and define no outcomes such as moved or stale.
Its remedy for a changing resource is to record a state of the whole resource.
Hypothesis stores a quote selector with 32 characters of context and reattaches by fuzzy matching (Hypothesis, fuzzy anchoring, 2013).
These formats store a hash pin and define the outcomes exactly.
The full comparison is in docs/comparison.md.
Chapter 18 defines layers and annotations.