feat: scienting-math/1 sources and derived/math.jsonl; lode references; stress fixes

Math content may say its source is in scienting-math/1's canonical TeX (form,
in no hash); derived/math.jsonl holds papermath's tree, symbols and issues,
and the validator now checks derived files. A symbol annotation names its
symbol by key; lode claim references use lode's tag and pin syntax. The zip
reader refuses entries zipfile cannot read, and checkpoint lines end in LF only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017R7sgDNvUGWY2zFPCq2JH6
This commit is contained in:
alexmandClaude committed 2026-10-17 06:44:28 -04:00
1 parent 8b5ee87275
commit 17880686fa
40 files changed
+750 -63

No files matched your search

+1
View File
@@ -84,6 +84,7 @@ The stop words are `a an the of on in for to and or at by with from as into onto
**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.
A `lode:` identifier is a claim reference as a layer writes one, `lode:<tag>` or `lode:<host>/<tag>` ([18.4](18-layers.md#184-bodies)).
**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.
+21 -3
View File
@@ -79,11 +79,11 @@ Page breaks, running heads and columns are not nodes: they are geometry ([7](07-
| Content | Kinds | Shape |
| --- | --- | --- |
| Runs | `sentence`, `cell`, `reference`, `authors`, `keywords` | A non-empty list of inline runs ([3.5](#35-inline-runs)). |
| Math | `equation`, `equation-line` | `{notation, source}`: `tex` or `typst`, and the source as written. |
| Math | `equation`, `equation-line` | `{notation, source, form?}`: `tex` or `typst`, the source as written or as a form spells it, and that form ([3.7](#37-math-forms)). |
| Verbatim | `code`, `algorithm` | `{language?, text}`. |
Other kinds have no `content`.
Derived renderings, such as MathML, are not content; they live in `derived/` ([12.7](12-package.md#127-derived-files)).
Derived renderings and readings, such as MathML and a formula's tree, are not content; they live in `derived/` ([12.7](12-package.md#127-derived-files)).
## 3.4 Attributes
@@ -105,7 +105,7 @@ No other kind carries `attrs`, and each kind carries only its own attributes.
| Run | Properties | Plain projection |
| --- | --- | --- |
| `text` | `text`, and optional `style`: a sorted list of distinct values from `em`, `strong`, `sup`, `sub`, `sc`, `mono`, never both `sup` and `sub`. | The text. |
| `math` | `notation` (`tex` or `typst`), `source`. | `$` + source + `$` |
| `math` | `notation` (`tex` or `typst`), `source`, and optional `form` ([3.7](#37-math-forms)). | `$` + source + `$` |
| `cite` | `refs`: reference node IDs; `text`: the printed form, such as `23`, `[1,2]` or `(Smith, 2019)`. | The printed form. |
| `xref` | `target`: a node ID in this document, an address in another, or null when not yet resolved; `text`. | The printed form. |
| `fnmark` | `footnote`: a footnote's ID, or null; `text`: the mark. | The mark. |
@@ -133,3 +133,21 @@ A node's runs as printed are its runs with each run's `printed` in place of its
Its projection as printed is the plain projection of its runs as printed; an equation's or a verbatim node's is its plain projection, and any other node's joins its text leaves' projections as printed with one U+0020.
It is the text a witness of the paper holds, recovered from `nodes.jsonl` alone; for a node no emend touched it is the plain projection.
The strict and lossy projections are taken over the runs as printed ([5.3](05-hashes.md#53-the-strict-projection)), and `projections.jsonl` gives an emended sentence's projections with its projection as printed.
## 3.7 Math forms
A math form is a standard spelling of formulas, so that one formula is written alike whichever paper, converter or claim it comes from.
An equation's or equation line's content and a `math` run MAY carry `form`, which names the form its `source` is written in; a source without `form` is as the witness wrote it.
The one form is `scienting-math/1`, canonical TeX, which [9.4](09-figures-tables-equations.md#94-the-math-form) describes; a node or run with `form` has the notation `tex`.
A consumer MAY rely on these properties of a source that carries `form`:
1. It is canonical: it is the form's own spelling of the formula the witness wrote, which renders as that formula did, apart from presentation such as spacing, `\displaystyle` and delimiter sizes.
2. It is idempotent: spelling it in the form again gives it back unchanged, so a tool that rewrites it to check it, or a converter run twice, changes nothing.
3. It carries no label: the form lifts a `\tag` out of the source, and an equation keeps it as its `label`; `\label`, `\nonumber` and `\notag` are gone.
4. Everything else is derived from it: the tree, the symbol keys and the issues of [9.4](09-figures-tables-equations.md#94-the-math-form) are read from the source by a pinned tool into `derived/math.jsonl` ([12.7](12-package.md#127-derived-files)), are never content, and are the same for the same source under the same form.
A producer writes `form` only on a source it has spelled in that form.
A correction that changes such a source writes the new source in the form too, since the gate does not implement the form and cannot check it.
A validator that implements the form reports a source with `form` that is not its own canonical spelling as `doc.math.form`.
`form` enters no content value, so adding it to a source already in the form changes no hash, ID or anchor, while respelling a source in the form changes them as any edit of the source does ([5.2](05-hashes.md#52-own-content)).
+10 -2
View File
@@ -30,8 +30,8 @@ A node's own content is an object with its `kind` and these members, and nothing
| Kinds | Members |
| --- | --- |
| Kinds that take a label | `label`: the label, or null. |
| `sentence`, `cell`, `reference`, `authors`, `keywords` | `runs`: the runs as stored, except that each `equation` run is reduced to `{"kind": "equation"}`, since an ID is never content. |
| `equation`, `equation-line` | `notation`, `source`. |
| `sentence`, `cell`, `reference`, `authors`, `keywords` | `runs`: the runs as stored, except that each `equation` run is reduced to `{"kind": "equation"}`, since an ID is never content, and each `math` run is without its `form`. |
| `equation`, `equation-line` | `notation`, `source`; never `form`. |
| `code`, `algorithm` | `language` (or null), `text`. |
| `section` | `level`, and `heading`: the `text_hash` of its heading, or null. |
| `table` | `columns`, as stored. |
@@ -42,6 +42,14 @@ So paragraphs, rows, lists, items and the other containers without content have
Own content covers stored values exactly; it is not normalized.
A table's columns name header cells by ID, so fixing a header cell changes that cell, not the table.
A math form ([3.7](03-nodes.md#37-math-forms)) enters no content value.
`form` says how the source is spelled, which the source itself shows, so it is left out of own content, and no projection reads it: a source in canonical TeX is projected as the TeX it is, by the rules of [5.3](#53-the-strict-projection) and [5.4](#54-simple-notation).
So a producer that adds `form` to sources already in the form leaves every hash, ID, pin and anchor as it was, and a reading with `form` and one without agree whenever their sources do.
Respelling a source in the form is an edit of the source: it changes the `text_hash`, `own_hash` and `node_hash` of the node, and, for a complex source, its complex key ([5.3](#53-the-strict-projection)).
Simple sources such as `K_r` and `K_{r}` have one canonical linear form, so their `match_hash` and `align_key` stay; a respelling that turns a simple character into a command [5.4](#54-simple-notation) does not read, as `ħ` becomes `\hbar`, makes the source complex and changes them.
Because the complex key compares sources as stored, a producer that aligns a reading in a form with a second reading ([5.6](#56-alignment)) spells the second reading's math in the same form first, or each complex formula it respelled becomes an `equation` suspect.
`hashes.jsonl` gives the values of a small document whose equation and math runs carry `form`, which are those of the same document without it.
## 5.3 The strict projection
The strict projection folds notation to one canonical linear form and keeps structure, so that it can certify agreement.
+78 -1
View File
@@ -34,4 +34,81 @@ For people, a cell can be shown as "Table 2, row CT–CT, column K_r" from its h
An equation keeps its source as written, `tex` from a conversion or `typst` from a draft, and its printed number as its `label`, so numbering never collides with a renderer's own.
An equation that the source numbers line by line (Eq. 3a) has `equation-line` children, each with its own label and source.
MathML is derived by a pinned tool and recorded, with the tool's name and version, in `derived/mathml.jsonl`.
A converter that respells TeX in the standard form of [9.4](#94-the-math-form) stores the respelled source and says so with `form` beside it ([3.7](03-nodes.md#37-math-forms)); the source as written stays in the witness.
MathML is derived by a pinned tool and recorded, with the tool's name and version, in `derived/mathml.jsonl`, and the form's reading of each formula in `derived/math.jsonl` ([12.7](12-package.md#127-derived-files)).
## 9.4 The math form
`scienting-math/1` is the standard form of a formula in a paper: one canonical TeX spelling, a tree read from it, a key for each symbol, and the issues a reader should look at.
A converter writes a package's equations and math runs in it, a reader renders and searches it, and a claim store reads a paper's equations and its own claims through it, so the two can be matched.
papermath is its reference implementation, and what papermath computes is what the form says; this section states what the specification relies on.
The identifier names a spelling of formulas, not a file format, so [registry/formats.json](../registry/formats.json) does not list it; its readings travel in a package's `derived/math.jsonl`.
The form reads TeX only.
**Canonical TeX** respells and never reinterprets, so it renders as the source did apart from presentation:
1. Unicode NFC, and a math character a converter handed over becomes its command: `−` is `-`, `≤` is `\leq`, `α` is `\alpha`.
2. Space is dropped, except inside text and where a command needs one before a letter (`\sin x`).
3. One spelling per meaning: `\le` is `\leq`, `\dfrac` and `\tfrac` are `\frac`, `\textrm` is `\text`, `x^{\prime}` is `x'`.
4. Presentation is dropped: `\displaystyle` and the other styles, `\big` and its sizes, `\color`, and `\left` and `\right` around ordinary delimiters.
5. Every argument and script is braced, and on one base the subscript comes first: `x_i^2` is `x_{i}^{2}`, `\frac12` is `\frac{1}{2}`.
6. `\tag` is lifted out as the label, and `\label`, `\nonumber` and `\notag` are dropped.
7. An environment goes by one name: `align`, `split` and `multline` are `aligned`, `equation` and `gather` are `gathered`.
8. A command outside the form's vocabulary is kept as written and reported.
Spelling a canonical source again gives it back unchanged.
**The tree** is the canonical TeX read as JSON.
A node is an array whose first item is a string, its kind; its other items are its parts: strings, null for a part that is absent, nodes, and groups, which are arrays whose first item is not a string.
Brackets group and leave no node.
| Kind | Parts | Is |
| --- | --- | --- |
| `num` | The digits | A number as printed, a decimal comma read as `.`. |
| `sym` | The key | A symbol. |
| `text` | The words | Words in the formula. |
| `const`, `oper` | The command | A constant, such as `\infty`, or an operator, such as `\partial`. |
| `dots`, `empty` | None | An ellipsis; nothing. |
| `add` | The terms | A sum, in which a subtracted term is a `neg` node, ± a `pm` and ∓ an `mp`, each with one part. |
| `mul` | The factors | A product, by juxtaposition or `\cdot`. |
| `times`, `div`, `op` | Two operands, after the operator's command for `op` | `\times`; `/` or `\div`; any other binary operator. |
| `frac`, `binom`, `sqrt`, `root` | Numerator and denominator; the radicand, after the index for `root` | Fractions, binomials and roots. |
| `pow`, `sub`, `prime`, `fact` | The base, and the script for `pow` and `sub` | Scripts, primes and factorials on what is not a symbol. |
| `apply` | The function's command, its argument, and its subscript if any | A named function: `\cos(x)`, `\log_{2} n`, `\max_{i} x_{i}`. |
| `lim` | The command, what is under it, the body | `\lim`, `\liminf` and `\limsup`. |
| `sum`, `prod`, `coprod`, `int`, `iint`, `iiint`, `oint`, `bigcup`, `bigcap` | The lower limit, the upper limit, the body | A big operator, whose body runs to the next sign outside brackets. |
| `abs`, `norm`, `angle`, `floor`, `ceil`, `braces` | The inside | A fence. |
| `interval` | The opening and closing brackets, the inside | Brackets that do not match, as in `[0, 1)`. |
| `rel` | Operands with a relation between each two | A relation or a chain; a continued line starts with null. |
| `list` | The formulas | Formulas side by side, at `,`, `;`, `\quad` or `\qquad` outside brackets. |
| `lines` | The lines | The lines of an `aligned` or `gathered` block. |
| `cases` | A group of value and condition for each case | Cases, a condition being null when there is none. |
| `matrix` | The environment, then a group of rows, each a group of cells | A matrix or array. |
| `opaque` | Canonical TeX | What the tree does not read. |
A tree with no `opaque` node is complete.
A later minor version of the form may add a kind, and a consumer that meets a kind it does not know reads that node as it reads `opaque`; `math.schema.json` therefore takes any lowercase kind, and its description lists these.
**A symbol** is a base, which is a letter, a Greek letter, or a font or accent command on a group (`\mathbf{F}`, `\hat{H}`), with any subscript, any superscript that names rather than raises (`R^{*}`, `A^{\dagger}`, `E^{\text{LJ}}`), and primes.
A text group alone is a symbol too, unless it holds several words, is a condition in `cases`, or is the set under a big operator.
A symbol's key is its canonical TeX with `\mathrm` spelled `\text`, `\ast` spelled `*`, `\prime` spelled `'`, and no space inside text: `K_r` and `K_{r}` have the key `K_{r}`, and `r_{\mathrm{eq}}` has the key `r_{\text{eq}}`.
The key is the one a lode claim store gives a symbol, so a symbol in a paper and the same symbol in a claim have one key, and a `symbol` annotation names its symbol by it ([18.4](18-layers.md#184-bodies)).
**Issues** never stop the reading; each is `{code, message, at}`, with `at` the canonical TeX it is about.
| Code | Means |
| --- | --- |
| `unbalanced` | A brace, bracket or fence does not close; with a brace, the whole formula is one `opaque` node. |
| `unknown-command` | A command outside the vocabulary, kept as written. |
| `label-or-power` | A superscript that may be a label written without `\text`, such as `E^{LJ}`, read as a power. |
| `script-on-group` | A script on a braced group rather than on a symbol. |
| `opaque` | A part the tree does not read. |
| `infix-fraction` | `\over`, `\choose` or `\atop`, rewritten as `\frac` or `\binom`. |
A later minor version may add a code.
**In a package**, the canonical source is the equation's or the math run's `source`, with `form` beside it ([3.7](03-nodes.md#37-math-forms)), and the rest is derived: one line of `derived/math.jsonl` per formula a pinned tool read, `{node, run, tool, form, tree, symbols, complete, issues, label?}`.
`run` is the index of the math run among the node's runs, or null for an equation or equation line, as in `derived/mathml.jsonl`; `symbols` lists the keys in the order the formula first writes them; `label` is the label the tool lifted from a `\tag`, omitted when the source has none, as a canonical source never does.
The schema is `math.schema.json`.
A validator checks what it can without implementing the form: that each line names a formula of the package (`doc.derived.node`), and that the formula is TeX, `complete` is true exactly when the tree has no `opaque` node, and `symbols` holds each `sym` key of the tree once (`doc.derived.math`).
`fixtures/packages/hale2026harmonic-damb/derived/math.jsonl` holds papermath's reading of the example's equation, of a math run that is one symbol, and of the run `_2` of "H₂O", which the tree cannot read alone.
+13 -3
View File
@@ -32,6 +32,7 @@ Paths use `/`, are relative, have no empty, `.` or `..` segment, no backslash an
No two paths are the same once case-folded, so a package reads alike on every file system.
A package folder carries no symbolic links, and a consumer refuses one that does, as it refuses a package whose files exceed its own size limit.
In a zip, entries are UTF-8 named, sit under one top-level folder named by the key, are stored or deflated, carry no symbolic links, and are unique; a consumer refuses an archive that breaks any of these, or whose expanded size exceeds its own limit.
It refuses in the same way (`package.zip.entry`) an archive it cannot read, such as one whose entries need a later version of the zip format than it implements, or whose deflated data does not inflate.
A producer that wants byte-identical archives writes entries sorted by path, dated 1980-01-01 00:00, with no extra fields; `fixtures/packages/tiny2026tiny-j4qm.sct.zip` is such an archive.
## 12.3 The manifest
@@ -50,7 +51,7 @@ Every stage that uses a model or an outside service records where it ran ([14](1
| Policy | Means |
| --- | --- |
| `full` | Every leaf keeps its content. |
| `checks-only` | Every leaf has `withheld: true` and no `content`; panels drop their figure text; references keep their resolution but no CSL; there are no corrections, suspects or datasets; and the hashing scheme is keyed: `hmac-team` between the team's machines and `hkdf-pages` outside the team ([5.8](05-hashes.md#58-keyed-hashes)). |
| `checks-only` | Every leaf has `withheld: true` and no `content`; panels drop their figure text; references keep their resolution but no CSL; there are no corrections, suspects, datasets or derived files; and the hashing scheme is keyed: `hmac-team` between the team's machines and `hkdf-pages` outside the team ([5.8](05-hashes.md#58-keyed-hashes)). |
A checks-only package is how a team shares its annotations on a paywalled paper without sharing the paper.
Its text lives in the team's private asset store, and only key holders can check its values.
@@ -63,8 +64,17 @@ Bytes that live only in the asset store are listed in the manifest with `present
## 12.7 Derived files
`derived/` holds what a pinned tool makes from the package, such as `derived/mathml.jsonl`, whose lines are `{node, run, tool, mathml}` with `run` null for an equation node.
Nothing derived is content, and a consumer may delete and rebuild it.
`derived/` holds what a pinned tool makes from the package.
Each line of a derived file names a formula by `node` and `run`, the index of a math run among the node's runs, or null for an equation or equation line, and the `tool` (`{name, version}`) that made it.
| Path | Lines | Schema |
| --- | --- | --- |
| `derived/mathml.jsonl` | `{node, run, tool, mathml}`: the formula rendered as MathML. | `mathml.schema.json` |
| `derived/math.jsonl` | `{node, run, tool, form, tree, symbols, complete, issues, label?}`: the formula read in a math form ([9.4](09-figures-tables-equations.md#94-the-math-form)). | `math.schema.json` |
Nothing derived is content, and a consumer may delete and rebuild it; a validator does not recompute a derived file, since it does not run the tool, but checks its lines against their schema and that each names a formula of the package (`doc.derived.node`), and that a math line's formula is TeX and its `complete` and `symbols` agree with its tree (`doc.derived.math`).
A derived file reads the text, so a checks-only package carries none ([12.5](#125-text-policies)).
A correction can delete a formula, change it or move its run, so a producer that applies one rebuilds the derived files or leaves them out.
## 12.8 Media type and extension
+12 -3
View File
@@ -43,8 +43,8 @@ Replies are annotations that target annotations, so discussions are threads anch
| `kind` | W3C type | Adds | Says |
| --- | --- | --- | --- |
| `gloss` | `TextualBody` | `audience` | An explanation at `novice`, `student` or `expert` level. |
| `claim-link` | `SpecificResource` | `source` (`lode:<tag>`), `pin`, `role` | That the span `states`, `uses` or `disputes` a claim. |
| `symbol` | `SpecificResource` | `source`, `pin`, `symbol` | That this occurrence of a symbol is a symbol claim. |
| `claim-link` | `SpecificResource` | `source`, `pin`, `role` | That the span `states`, `uses` or `disputes` a claim. |
| `symbol` | `SpecificResource` | `source`, `pin`, `key`, `symbol` | That this occurrence of a symbol, the one whose key is `key`, is the symbol a symbol claim defines. |
| `comment` | `TextualBody` | `category` | A remark, opinion or interpretation. |
| `caveat` | `TextualBody` | `category` | A warning a reader should see. |
| `question` | `TextualBody` | `for`, `category` | A question for a `reader`, a `group` or the `authors`. |
@@ -58,6 +58,15 @@ Replies are annotations that target annotations, so discussions are threads anch
A textual body has a `value`, and optionally a `format` (`text/plain` or `text/markdown`) and a `language`.
The `source` of a `claim-link` or `symbol` body is a claim in a lode claim store, written as lode writes a reference: `lode:` and the claim's tag, eight Crockford base32 capitals (the digits and the letters without I, L, O and U), as in `lode:272XTX7C`, or `lode:<host>/<tag>` for a claim in another store, `<host>` being a domain name.
A tag never changes, while a claim's slug, such as `amber/k-bond`, may be renamed, so a slug is never a reference.
The optional `pin` fixes the claim as the annotator read it: the same reference, `@`, and the first six lowercase hex digits of the claim's statement hash, as in `lode:272XTX7C@02f47b`.
`common.schema.json` defines both, as `claimRef` and `claimPin`.
A `symbol` body names its symbol twice, as the target's span and by `key`, the symbol's key in the math form `scienting-math/1` ([9.4](09-figures-tables-equations.md#94-the-math-form)), which a claim store gives the symbol a symbol claim defines: `K_{r}` for a span `$K_r$`.
So a reader finds every occurrence of a symbol across a library by its key, however its source spaced or braced it, and a claim store matches the annotation to its claim without parsing the span.
The span is still required, since the key says which symbol and the span says where; `symbol`, optional, is the symbol as the span writes it.
A `comment`, `caveat` or `question` body MAY carry a `category`, which says what it is about, from a fixed list:
| `category` | Says |
@@ -77,4 +86,4 @@ The store's `annotations` table keeps the category beside the body's kind ([13.4
Nothing a model writes is ever stored as source text.
A model may propose a `description`, and like any annotation it stays `proposed` until a person confirms it; an accessible export uses confirmed descriptions only, and a figure with none has no description.
Other text a model writes about a span, such as a summary, is a `generated` annotation, which names its `generator`.
`fixtures/records/layer/` holds a layer with one annotation of each common kind, each comment, caveat and question with its category, and the receipt that confirms some of them.
`fixtures/records/layer/` holds a layer with one annotation of each common kind, each comment, caveat and question with its category, a claim link and a symbol that reference a lode claim and pin it, and the receipt that confirms some of them.
+1 -1
View File
@@ -7,7 +7,7 @@ A project, `scienting-project/1`, is the unit a team works in.
| `key`, `store`, `name`, `description` | Its identity. |
| `members` | People with a `role` (`owner`, `editor`, `reader` or `guest`) and the roster keys they sign with. |
| `documents` | The project's documents, each with the `reason` it is included, `tags`, and a reading `status` per member: `unread`, `reading` or `read`. |
| `paths` | Reading paths: ordered steps through documents, nodes, claims and layers, for onboarding a student or preparing a reading group. |
| `paths` | Reading paths: ordered steps through documents, nodes, claims and layers, for onboarding a student or preparing a reading group; a claim step's `ref` is a claim reference, `lode:<tag>` ([18.4](18-layers.md#184-bodies)). |
| `layers`, `datasets`, `views`, `drafts` | What the project holds. |
| `claims` | The claim namespace or bundle it uses, as the `lode` setting. |
| `settings` | The digit rule for targeted F3 ([8.10](08-fidelity.md#810-targeted-f3)), the drift threshold ([6.6](06-anchors.md#66-drift)), the spot-check rate and minimum ([8.8](08-fidelity.md#88-spot-checks)), what happens when a right is unknown (`refuse`, the default, or `warn`), the stage requirements in use, as the `id` of their stage file ([14](14-rights.md)), and the project's transparency `log`: its `origin`, the roster keys that `witness` it, and the `threshold` of witnesses a checkpoint needs ([23](23-log.md)). |
+3 -2
View File
@@ -22,7 +22,7 @@ A validator checks, in order, and reports each failure as `path:line: rule: mess
3. The tree ([3](03-nodes.md)), runs and references between nodes, the counts, and the keys ([2.4](02-model.md#24-work-and-document-keys)).
4. The policy and hashing scheme ([12.5](12-package.md#125-text-policies)).
5. The five values of every node, the root and `meta_hash`, when the text is present and the key, if any, is known.
6. The ID table, the corrections and the history root, the witnesses, pages, locations and references, and every file's order.
6. The ID table, the corrections and the history root, the witnesses, pages, locations and references, the formulas derived files name, and every file's order.
7. Receipts: IDs, roots, documents, node order, signatures against the package's roster, spot-check keys, seeds and samples, and the fidelity distribution.
## 22.3 Schemas
@@ -39,7 +39,8 @@ Rule IDs are stable: a rule's meaning never changes, and a retired rule's ID is
| Prefix | Covers |
| --- | --- |
| `package.` | The manifest, paths, files and schemas. |
| `doc.tree.`, `doc.node.`, `doc.run.`, `doc.table.` | The tree, node content and runs. |
| `doc.tree.`, `doc.node.`, `doc.run.`, `doc.table.`, `doc.math.` | The tree, node content and runs. |
| `doc.derived.` | Derived files ([12.7](12-package.md#127-derived-files)). |
| `doc.hash.` | The five values, the root and the metadata hash. |
| `doc.id.`, `doc.order.` | The ID table and file order. |
| `doc.policy.` | Text policies and keyed hashing. |
+1
View File
@@ -35,6 +35,7 @@ Q2xlYXIgdGV4dCBpcyBub3QgYSByb290IGhhc2guLi4uLi4uLi4=
The origin names the log, and a team's logs are named `scient.ing/log/<store>` or under a domain the team controls.
A signature line is an em dash (U+2014), a space, the signer's roster key, a space, and Base64 of the signer's four-byte key hash followed by the signature.
The key hash is the first four bytes of SHA-256 of the signer's name, a newline, the byte 0x01 and the Ed25519 public key; the signature is Ed25519 over the note's first three lines, each ending in a newline.
Every line of a note, the last signature line included, ends in one U+000A LINE FEED; a note that ends a line with anything else, such as U+000B, U+0085 or U+2028, which some libraries also take for line breaks, or that lacks its final U+000A, is malformed.
A note parsed into JSON has `format`, `origin`, `size`, `root` as hex, `signatures` as `{name, key_hash, value}` and the `note` text itself; the schema is `checkpoint.schema.json`.
`checkpoint.jsonl` gives a checkpoint over the example paper's receipts and its verification.