First implementation (#1)
check.yml (push) Invalid workflow file

Reviewed-on: #1
This commit is contained in:
alexm committed 2026-10-15 09:50:22 -04:00
1 parent fd4b21eeca
commit 2fd3307147
57 files changed
+11446

No files matched your search

+79
View File
@@ -35,6 +35,7 @@ A conforming reader accepts each one and recomputes every hash it contains.
## Records
`records/` holds a valid example of every other format that is a JSON file of its own.
<<<<<<< HEAD
Three formats have their example elsewhere: the stage requirements (`scienting-stages/1`) and the stamp rules (`scienting-stamps/1`) are in [registry/](../registry/README.md), and a bundle (`scienting-bundle/1`) is a SQLite file that `paperspec load --bundle` builds from the packages.
Each record is a single file, or a folder where a format needs several files.
@@ -110,3 +111,81 @@ Use them for nothing else.
`src/` holds the hand-written descriptions of the three main documents, as first read; see [src/README.md](src/README.md).
Everything else here is generated by `paperspec build`, so change the sources or the builder, never the generated files.
||||||| parent of 4fa326d (First implementation (#1))
=======
Three formats have their example elsewhere: the stage requirements (`scienting-stages/1`) and the stamp rules (`scienting-stamps/1`) are in [registry/](../registry/README.md), and a bundle (`scienting-bundle/1`) is a SQLite file that `tools/load.py --bundle` builds from the packages.
Each record is a single file, or a folder where a format needs several files.
| Files | What they are for |
| --- | --- |
| `anchor-span.json`, `anchor-leaf.json`, `anchor-cell.json`, `anchor-paragraph.json` | An anchor is an address pinned to a hash, with a quotation and context, so it can be found again after the text changes. These four anchors point at a span of a sentence, a sentence, a table cell and a paragraph of the main example. |
| `anchor-keyed.json` | An anchor that leaves the team, as in a public layer: its table context is stored as keyed hashes, so the labels cannot be read from it ([spec/06 section 6.3](../spec/06-anchors.md#63-keyed-anchors)). |
| `rights-open.json`, `rights-subscription.json`, `rights-collective.json` | A witness's license and what uses it allows, under an open license, a subscription and a collective license. |
| `policy.json` | A signed team decision that settles a use the rights record leaves unknown. |
| `backend-docling.json`, `backend-examplevendor.json` | The code and weight licenses of a conversion tool and the conditions attached to them. |
| `profile-acme.json`, `profile-smithlab.json` | What those conditions ask about a team: its purpose, its funding and whom it competes with. |
| `roster.json` | The keys that may sign, the role of each key's holder in the team, and what each key may sign. Ana is the owner, so she may revoke anyone's receipt. |
| `layer/` | A layer of annotations on the main example (`layer.json`, `annotations.jsonl`) and the receipt that confirms them (`receipt.json`). |
| `submissions/`, `grades/` | A student's answers to exercises in the layer, and the grader's result for each. |
| `suspect.json` | A doubtful reading raised for review: the converter's reading of an exponent in the main example, before the first correction answered it. |
| `qa-report.json` | Reviewer error bounds for a delivery that covers two of the main example's receipts, signed by the team's owner key. |
| `checklist/` | A conformance checklist (`checklist.json`) for an accessible HTML export of the main example, checked against WCAG 2.1 AA criterion by criterion, and the receipt that covers it at its hash (`receipt.json`). The format is `provisional`. |
| `proof-inclusion.json`, `proof-consistency.json` | Two RFC 9162 proofs: that one node was covered by the main example's first receipt without showing the rest, and that revision 12 of its correction history extends revision 8 rather than rewriting it. |
| `checkpoint.json` | A signed checkpoint of the team's transparency log over the main example's receipts, revocations and roster, as the parsed form of its signed note, cosigned by a witness. The format is `provisional`. |
| `log/` | The same log as the static files a server would publish: `checkpoint` and the hash and entries tiles ([spec/23 §23.4](../spec/23-log.md#234-serving-a-log)). |
| `receipt-ml-dsa.json` | A receipt signed with ML-DSA-65 (FIPS 204) by `dana`, whose roster key is post-quantum. |
| `project.json`, `digitization.json`, `digitization-confirmation.json`, `datasets/`, `view.vl.json`, `snapshot.json`, `draft-ids.jsonl` | A team project; values read off the main example's figure by hand, the receipt that confirms them, and the dataset they yield; a Vega-Lite chart pinned to that dataset; what the draft cites, pinned; and the sentence IDs of the draft's Typst project. These formats are `provisional`. |
## Broken packages
Each folder in `invalid/` holds a `package/` folder, or a `package.sct.zip` archive, that breaks exactly one rule, built from `packages/tiny2026example/` by one edit, and an `expect.json` that names the rule.
A conforming implementation refuses every one of them and should report that rule.
`registry/rules.json` lists every rule ID with its meaning, and a validator reports each failure as `path:line: rule: message` ([spec/22 section 22.2](../spec/22-conformance.md#222-validating-a-package)).
| Case | What is wrong | Rule |
| --- | --- | --- |
| `alias-dangling/` | An alias whose node does not exist. | `doc.id.successor` |
| `bad-id/` | An ID that uses a letter Crockford base32 lacks (i, l, o or u). | `package.schema` |
| `checks-only-plain/` | A checks-only package that still carries text and plain hashes. | `doc.policy.withheld` |
| `cite-not-reference/` | A cite run names a node that is not a reference. | `doc.run.cite` |
| `counts-wrong/` | document.json's counts are not the number of nodes and leaves. | `doc.counts` |
| `crlf/` | A file whose lines end in CR LF, which is not the canonical form. | `package.file.canonical` |
| `empty-optional-file/` | An optional JSONL file with no records. | `package.file.empty` |
| `hash-mismatch/` | A node_hash that does not recompute. | `doc.hash.node-hash` |
| `heading-not-first/` | A heading must be a section's first child. | `doc.tree.child` |
| `history-wrong/` | document.json's history is not the root over the corrections. | `doc.history` |
| `key-suffix/` | A work key whose hash part is not the hash of the work's DOI. | `doc.key.suffix` |
| `key-work/` | A document key whose suffix is not the version's. | `doc.key.work` |
| `location-unknown-page/` | A location on a page no witness has. | `doc.location.page` |
| `manifest-hash/` | A file changed after the manifest was written. | `package.manifest.hash` |
| `manifest-key/` | The manifest names another key than document.json. | `package.manifest.key` |
| `missing-required-file/` | A required file is missing. | `package.file.required` |
| `not-canonical/` | A line that is valid JSON but not canonical JSON (the fixed form of RFC 8785, which gives equal data identical bytes). | `package.file.canonical` |
| `receipt-root/` | A receipt whose Merkle root (one hash that summarizes a list of hashes) does not recompute. | `doc.receipt.root` |
| `receipt-signature/` | A receipt changed after it was signed. | `doc.receipt.signature` |
| `receipt-unsorted-nodes/` | A receipt whose nodes are not sorted by ID. | `doc.receipt.nodes` |
| `retired-live/` | An ID that is both live and retired. | `doc.id.retired-live` |
| `rev-without-corrections/` | document.json's rev is not the number of corrections. | `doc.correction.rev` |
| `root-mismatch/` | document.json's root is not the root node's node_hash. | `doc.hash.root` |
| `signer-mismatch/` | A receipt whose signature was made with another key than the signer it names. | `doc.receipt.signature` |
| `style-sup-sub/` | A run cannot be both a subscript and a superscript. | `doc.run.style` |
| `text-edited/` | Text changed without its hashes. | `doc.hash.text-hash` |
| `unknown-kind/` | Kinds outside the list are refused. | `package.schema` |
| `unlisted-file/` | A file the manifest does not list. | `package.manifest.unlisted` |
| `unsafe-path/` | The manifest lists a path that leaves the package. | `package.path.unsafe` |
| `zip-symlink/` | A zipped package with an entry that is a symbolic link. | `package.zip.entry` |
| `zip-traversal/` | A zipped package with an entry whose path leaves the package folder. | `package.zip.entry` |
## Keys
`keys/` holds the Ed25519 secret keys (`ana`, `ben`, `cara`, `wit`, the witness, and `ben-spot`, whose VRF proof picks the nodes of a spot-check), the seed of `dana`'s ML-DSA-65 key, which signed the fixtures' receipts, and the team secret of the checks-only package.
Ed25519 is a signature scheme: the secret key makes a signature, and the public key in a roster verifies it.
These are published test keys.
Anyone can reproduce the signatures, so a signature made with these keys proves nothing about who made it.
Use them for nothing else.
## Sources
`src/` holds the hand-written descriptions of the three main documents, as first read; see [src/README.md](src/README.md).
Everything else here is generated by `python3 tools/build.py`, so change the sources or the builder, never the generated files.
>>>>>>> 4fa326d (First implementation (#1))