# 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](https://www.w3.org/TR/annotation-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: ```json {"@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`](../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: ```json {"@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](https://www.w3.org/TR/json-ld11-api/#alg-expand-each-key-value)) and would give its arrays no order ([JSON-LD 1.1 §4.3](https://www.w3.org/TR/json-ld11/#sets-and-lists)). ## 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](https://www.w3.org/TR/annotation-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](../spec/06-anchors.md#62-the-anchor)). 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](../spec/06-anchors.md#65-resolution)). 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](../spec/18-layers.md#183-the-annotation)). 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 `@context` of `layer.json` and of every line of `annotations.jsonl`. [Chapter 18](../spec/18-layers.md) defines layers (§18.2), annotations (§18.3) and bodies (§18.4). - Reader: Follow [chapter 6](../spec/06-anchors.md) to resolve an anchor. The file `vectors/resolve.jsonl` resolves seventeen anchors against `fixtures/packages/hale2026harmonic-damb` and gives every outcome. - JSON-LD processor: Use a JSON-LD 1.1 processor; the context relies on `@json` and `@version` 1.1. - Checker: `schemas/annotation.schema.json` and `schemas/layer.schema.json` validate the files. `paperspec check` also checks that each annotation's ID derives from its content and that the receipt at `fixtures/records/layer/receipt.json` covers each `confirmed` annotation. The traps: - No test vector pins the context, and nothing in `tools/` reads `scienting-1.jsonld`. The schemas require only that `@context` be 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. - `@context` is part of an annotation's content hash (the hash covers everything except `status`, `receipt` and `modified`). Rewriting or reordering the array changes the hash that a receipt covers. - `format` is one term for two jobs: the layer's `format` (`scienting-layer/1`) and a text body's `format` (`text/markdown`). The scienting context maps it to `sct:format`. The Web Annotation context maps `format` to `dc:format` and protects none of its terms, and in an array of contexts the later definition wins ([JSON-LD 1.1 §4.1](https://www.w3.org/TR/json-ld11/#advanced-context-usage)), so listing this context second makes `format` mean `sct: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](../spec/00-introduction.md)). - The `TextQuoteSelector` repeats the anchor's plain quotation, and is left out when the quote is hashed (over 200 code points) or keyed ([spec/18 §18.3](../spec/18-layers.md#183-the-annotation)), 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`](../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](../spec/00-introduction.md)). 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](https://www.w3.org/TR/annotation-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](https://web.hypothes.is/blog/fuzzy-anchoring/), 2013). These formats store a hash pin and define the outcomes exactly. The full comparison is in [docs/comparison.md](../docs/comparison.md). [Chapter 18](../spec/18-layers.md) defines layers and annotations.