summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRalph Amissah <ralph.amissah@gmail.com>2026-10-13 16:54:02 -0400
committerRalph Amissah <ralph.amissah@gmail.com>2026-10-13 16:54:02 -0400
commit3f34ec6afde21801eff0b655949a6d219e47943c (patch)
tree6e95a210663bcc7f41d0791de1769a2535988180
parentformat 2.1: the pipeline reads with ocda-read (diff)
release 2.1.0: versions, the library locked, the pipelineHEADmain
The writer's version follows the format's: 2.1.0 in dub.json, gleam.toml and both flakes (it was 2.0.0), and manifest.toml locks the library at 2.1.0 to match. A release is numbered major.minor.patch, major.minor being the format and shared with the specification and the library, the patch the writer's own. flake.lock, in dlang/ and gleam/, pins the library at its 2.1.0 release and nixpkgs as that release locks it, so the writer builds with what the library was built and checked with. The READMEs say plain nix build, and how to build against a working copy of the library instead. The pipeline no longer builds or runs sisudoc-ssp-reader and sisudoc-ocda-db-reader, which are frozen: ocda-read, the library's reader, covers both, and read.sh already ran it from both forms and in both languages. Gone from build.sh, config.sh, one.sh and read.sh, and from pipeline/README.md, which with config.sh now names spine's --show-abstraction as the README does. build.sh still gives the writer the library beside it, so that the library run and the library built in are the same one. README, to what was decided for these writers: the outputs must be identical from every form and the D and Gleam writers must agree byte for byte, but they are not held to spine's bytes; each format has its own judge, and a difference from spine is there to read better. The introduction said "identical to each other and to spine's", and the example compared --text with spine's text file, which fails by design; the example now compares the .ssp and the .ocda.db. The documents the checks run over are the markup document samples, named with their repository and the spine flags that build the artefacts, and the counts read "all" or "every document" rather than a number, here and in dlang/, gleam/ and pipeline/README.md. The format is 2.1, and the license is stated. Checked: D and Gleam build from the lock; over the markup document samples, D == Gleam in text, markdown, html, epub and typst for every document-language, and the .ssp and the .ocda.db give the same output. (assisted by Claude-Code)
-rw-r--r--README.md108
-rw-r--r--dlang/README.md16
-rw-r--r--dlang/dub.json2
-rw-r--r--dlang/flake.lock16
-rw-r--r--dlang/flake.nix2
-rw-r--r--gleam/README.md19
-rw-r--r--gleam/flake.lock16
-rw-r--r--gleam/flake.nix2
-rw-r--r--gleam/gleam.toml2
-rw-r--r--gleam/manifest.toml2
-rw-r--r--pipeline/README.md16
-rwxr-xr-xpipeline/build.sh13
-rw-r--r--pipeline/config.sh5
-rwxr-xr-xpipeline/one.sh6
-rwxr-xr-xpipeline/read.sh10
15 files changed, 118 insertions, 117 deletions
diff --git a/README.md b/README.md
index 7ba2841..eaedaac 100644
--- a/README.md
+++ b/README.md
@@ -22,9 +22,9 @@ Five formats: `--text`, `--md`, `--html`, `--epub`, `--typst`.
They are **samples**, and they are **checked**. Spine is the output
pipeline; nothing here replaces it. What these demonstrate is that the
-abstraction is sufficient: given a `.ssp` or a `.ocda.db` and nothing else,
-a program of a few hundred lines reproduces spine's own output for that
-format.
+abstraction is sufficient: given a `.ssp`, a `.ocda.db` or a `.sisupod` and
+nothing else, a program of a few hundred lines makes a complete document in
+that format, in the spirit of spine's own.
```
.ssp ─┐
@@ -33,9 +33,11 @@ format.
```
**A writer is never told which serialisation it was given.** That is the
-claim, and every writer here is run twice against every document to check
-it: once from the `.ssp`, once from the `.ocda.db`, and the two outputs must
-be identical to each other and to spine's.
+claim, and every writer here is run against every form of every document to
+check it: the outputs must be identical from every form, and the D and Gleam
+writers must produce the same bytes. They are not held to spine's bytes.
+Each format has its own judge (below), and where the output differs from
+spine's it does so to read better, and the code says why at that point.
## The oracle comes first
@@ -54,17 +56,20 @@ and from every input form the library accepts, not only the two it started
with: a document renders identically from its `.ssp`, its `.ocda.db` and its
`.sisupod`.
-**As at 2026-09-26**, over the 36 document-languages of the reference
-collection:
+The checks are run over the markup document samples
+([sisudoc-spine-samples](https://git.sisudoc.org/sisudoc-spine-samples)),
+built by spine with `--show-abstraction --ocda-db --pod2`, which writes each
+document's `.ssp`, its `.ocda.db` and its pod. **As at 2026-09-26**, over
+every document-language of them:
`--text`, which is **no longer spine's bytes**, by decision (2026-09-27):
| | |
|---|---|
-| the same bytes from every input form | **36 of 36** |
-| **D == Gleam, byte for byte** | **36 of 36** |
-| the words == the html writer's objects, as a multiset | **36 of 36** |
-| every object number once, and no other | **36 of 36** |
+| the same bytes from every input form | **all** |
+| **D == Gleam, byte for byte** | **all** |
+| the words == the html writer's objects, as a multiset | **all** |
+| every object number once, and no other | **all** |
| lines differing from `spine --text` | 131,474, **reported and not required** |
Byte identity was the first oracle and earned its place while there was
@@ -83,11 +88,11 @@ contents indents by ranked level rather than by spine's `indent_hang`.
| | |
|---|---|
-| the same bytes from every input form | **36 of 36** |
-| **D == Gleam, byte for byte** | **36 of 36** |
-| every `(#x)` resolves to an `<a id=x>`, and no id is defined twice | **36 of 36** |
-| the words == the html writer's objects | **36 of 36** |
-| every object number anchored, and no other | **36 of 36** |
+| the same bytes from every input form | **all** |
+| **D == Gleam, byte for byte** | **all** |
+| every `(#x)` resolves to an `<a id=x>`, and no id is defined twice | **all** |
+| the words == the html writer's objects | **all** |
+| every object number anchored, and no other | **all** |
The third is the markdown one: markdown has no anchor syntax, so the anchors
are the two pieces of raw html the writer emits, and a mistake in them is
@@ -100,16 +105,16 @@ writer emits a private-use marker for the directory and substitutes it once, at
the end, so nothing carries the constant through the call graph. spine, whose
markdown goes to `<lang>/markdown/` and shares the images with its html, passes
`../../image`; and **spine's `.md` is byte identical to what this produces with
-that prefix, on all 36 document-languages.**
+that prefix, on every document-language.**
`--epub`:
| | |
|----------------------------------------|--------------------|
-| epubcheck clean | **36 of 36** |
-| from a `.ocda.db` == from a `.sisupod` | **35 of 35 pairs** |
-| from a `.ssp` == from a `.ocda.db` | **36 of 36** |
-| **D == Gleam, byte for byte** | **36 of 36** |
+| epubcheck clean | **all** |
+| from a `.ocda.db` == from a `.sisupod` | **every pair** |
+| from a `.ssp` == from a `.ocda.db` | **all** |
+| **D == Gleam, byte for byte** | **all** |
The third is the interesting one: a `.ssp` carries no images and a `.ocda.db`
and a `.sisupod` do, yet the epub is the same either way. It is the same
@@ -118,7 +123,7 @@ before it emits one, and a `.ssp` inside a pod can: the images are beside it,
at `media/image/`. So the three input forms are three ways to the same
publication rather than three publications.
-(Thirty-five pairs rather than thirty-six, because spine names a `.sisupod`
+(One pair fewer than there are documents, because spine names a `.sisupod`
after the pod directory and a `.ocda.db` after the document uid, and for one
document those differ, so it has no pair to compare.)
@@ -126,10 +131,10 @@ document those differ, so it has no pair to compare.)
| | |
|--------------------------------------------------------------------|--------------|
-| parses (`xmllint --html`) | **36 of 36** |
-| every `href="#x"` resolves, no id twice, no heading outside h1..h6 | **36 of 36** |
-| the objects' text == spine's scroll html | **36 of 36** |
-| **D == Gleam, byte for byte** | **36 of 36** |
+| parses (`xmllint --html`) | **all** |
+| every `href="#x"` resolves, no id twice, no heading outside h1..h6 | **all** |
+| the objects' text == spine's scroll html | **all** |
+| **D == Gleam, byte for byte** | **all** |
and so the two writers agree with each other, in two languages, without
either having been written from the other. That is the agreement that says
@@ -139,12 +144,12 @@ the model is enough.
| | |
|----------------------------------------------------|--------------|
-| `typst compile`, silently | **36 of 36** |
-| from a `.ssp` == from a `.ocda.db` | **36 of 36** |
-| the `.typ`'s text == the html writer's object text | **36 of 36** |
-| every OCN on a page of the pdf | **36 of 36** |
-| the same pdf twice, byte for byte | **36 of 36** |
-| **D == Gleam, byte for byte** | **36 of 36** |
+| `typst compile`, silently | **all** |
+| from a `.ssp` == from a `.ocda.db` | **all** |
+| the `.typ`'s text == the html writer's object text | **all** |
+| every OCN on a page of the pdf | **all** |
+| the same pdf twice, byte for byte | **all** |
+| **D == Gleam, byte for byte** | **all** |
4,870 pages typeset. The first row is the strong one: **a link to a label
that does not exist is a typst compile error**, so a silent compile means
@@ -183,7 +188,7 @@ and the *direction* of the allowance is the finding.
```sh
cd dlang
-nix build --override-input ocda-lib path:../../sisudoc-ocda-lib
+nix build
./result/bin/ocda-write --text <doc>.ssp
./result/bin/ocda-write --text <doc>.ocda.db en
./result/bin/ocda-write --typst <doc>.ocda.db en --out <dir>/<doc>.typ
@@ -194,24 +199,32 @@ typst compile --root <dir> <dir>/<doc>.typ <dir>/<doc>.pdf
the epub is a zip, and a `.typ` names its images by path, so `--out` also
writes the `image/` directory the `.typ` refers to.
-Output goes to stdout, so the comparison is a pipeline:
+Output goes to stdout, so the check that a writer cannot tell the forms
+apart is a comparison:
```sh
-./result/bin/ocda-write --text <doc>.ssp | cmp - <spine's .txt for that doc>
+./result/bin/ocda-write --text <doc>.ssp > a
+./result/bin/ocda-write --text <doc>.ocda.db en > b
+cmp a b
```
-### the library, before it is published
+### the library
-`sisudoc-ocda-lib` is not yet at a public URL, so the flake declares the
-URL it will have and the local copy is supplied on the command line with
-`--override-input`. Nix accepts this without ever fetching the declared
-url. When the library is published the override goes away.
+Each flake takes `sisudoc-ocda-lib` from
+`git://git.sisudoc.org/tools/sisudoc-ocda-lib`, and `flake.lock` pins the
+commit the writer was built and checked against. To build against a working
+copy of the library instead:
+
+```sh
+nix build --override-input ocda-lib path:../../sisudoc-ocda-lib
+```
## The pipeline
-`pipeline/` holds fixed shell scripts that build every reader, library and
-writer in both languages, run all of them over a directory of abstraction
-artefacts, and put the output where it can be read.
+`pipeline/` holds fixed shell scripts that build the library (whose
+`ocda-read` is the reader) and the writer in both languages, run all of them
+over a directory of abstraction artefacts, and put the output where it can
+be read.
```sh
ARTEFACTS=<dir of .ssp and .ocda.db> OUT=<dir> sh pipeline/run.sh
@@ -356,4 +369,9 @@ the comparison is of the writer and not of the signature.
## The format
Specified in **sisudoc-abstraction-format**: `ocda-model.md` for the model,
-and the two format specifications for the serialisations. At format **2.x**.
+and the two format specifications for the serialisations. At format **2.1**;
+the writer's version follows the format's major and minor parts.
+
+## Licence
+
+AGPL-3.0-or-later. See [`COPYRIGHT`](COPYRIGHT).
diff --git a/dlang/README.md b/dlang/README.md
index e3a41b6..add15f1 100644
--- a/dlang/README.md
+++ b/dlang/README.md
@@ -27,7 +27,7 @@ and everything it needs is in the model.
## Build and run
```sh
-nix build --override-input ocda-lib path:../../sisudoc-ocda-lib
+nix build
./result/bin/ocda-write --text <doc>.ssp
./result/bin/ocda-write --html <doc>.ocda.db de
./result/bin/ocda-write --html <doc>.sisupod
@@ -49,19 +49,19 @@ separate product; for five modules a second build step buys nothing.
## The checks
`--text` and `--md` are checked against the html writer's objects, word for
-word, and against each other language's writer, byte for byte: **36 of 36 on
-every count.** Byte identity with `spine --text` was the first oracle and is
-no longer the target; see the repository README.
+word, and against each other language's writer, byte for byte: **every
+document on every count.** Byte identity with `spine --text` was the first
+oracle and is no longer the target; see the repository README.
-`--html` is checked harder still: it parses, every `href="#x"`
-resolves, no id appears twice, no heading falls outside `h1`..`h6`, and the
-objects' visible text equals spine's scroll html exactly. **36 of 36 on each,
+`--html` is checked harder still: it parses, every `href="#x"` resolves, no
+id appears twice, no heading falls outside `h1`..`h6`, and the objects'
+visible text equals spine's scroll html exactly. **Every document, on each,
and byte identical to the Gleam writer.** See the repository README for what
it does differently from spine and why.
`--epub` is judged by `epubcheck`, and `--typst` by typst: a link to a label
that does not exist is a compile error, so a silent compile means every
-internal link in the document resolves. **36 of 36 on each, and byte
+internal link in the document resolves. **Every document, on each, and byte
identical to the Gleam writer.**
## Where it is faithful rather than sensible
diff --git a/dlang/dub.json b/dlang/dub.json
index dcc891c..901b02e 100644
--- a/dlang/dub.json
+++ b/dlang/dub.json
@@ -2,7 +2,7 @@
"authors": [ "Ralph Amissah" ],
"copyright": "Copyright (C) 2026 Ralph Amissah",
"name": "ocda-write",
- "version": "2.0.0",
+ "version": "2.1.0",
"description": "sample writers over the object-centric document abstraction",
"homepage": "https://sisudoc.org",
"license": "AGPL-3.0+",
diff --git a/dlang/flake.lock b/dlang/flake.lock
index 13a94c9..a83226a 100644
--- a/dlang/flake.lock
+++ b/dlang/flake.lock
@@ -2,11 +2,11 @@
"nodes": {
"nixpkgs": {
"locked": {
- "lastModified": 1790652569,
- "narHash": "sha256-k8Fu4c9Z+4Nh7mUr0cfw++ITQiyEhlWxoJBOkI3tOcQ=",
- "rev": "b6c8664de9b6cc07fe5666a29f91884ba81197c4",
+ "lastModified": 1792506237,
+ "narHash": "sha256-hVMDyAXU0kxRuG3GygbZkzf5x+aBNEC0NYEJ6KwHtD4=",
+ "rev": "5adc50831c259f87faeb09ddf930d43597197473",
"type": "tarball",
- "url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.11pre1082290.b6c8664de9b6/nixexprs.tar.zst"
+ "url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.11pre1097770.5adc50831c25/nixexprs.tar.zst"
},
"original": {
"type": "tarball",
@@ -16,11 +16,11 @@
"ocda-lib": {
"flake": false,
"locked": {
- "lastModified": 1791851051,
- "narHash": "sha256-mVI3uGQ1z7S5OMMFjl5UoWShE3p0ucXlr6cVU1iAsgI=",
+ "lastModified": 1791924842,
+ "narHash": "sha256-C79k2X32NxKPqrE7nJVegYThtA6Dm2pg/B/yb9RiObE=",
"ref": "refs/heads/main",
- "rev": "4e4f2f8c2b2c043077390cb4ccf7ce97ffe4ac6b",
- "revCount": 3,
+ "rev": "79a7a0cf09c9d6b5d9974376dcb7a98bd5bdbcba",
+ "revCount": 4,
"type": "git",
"url": "git://git.sisudoc.org/tools/sisudoc-ocda-lib"
},
diff --git a/dlang/flake.nix b/dlang/flake.nix
index d3923f0..c7ed73b 100644
--- a/dlang/flake.nix
+++ b/dlang/flake.nix
@@ -25,7 +25,7 @@
mkWrite = { compiler, compilerBin }: pkgs.stdenv.mkDerivation {
pname = "ocda-write";
- version = "2.0.0";
+ version = "2.1.0";
src = self;
nativeBuildInputs = [ compiler ];
buildInputs = [ pkgs.sqlite pkgs.zstd ];
diff --git a/gleam/README.md b/gleam/README.md
index 8a2bea9..046dc0f 100644
--- a/gleam/README.md
+++ b/gleam/README.md
@@ -27,7 +27,7 @@ model to bytes.
## Build and run
```sh
-nix build --override-input ocda-lib path:../../sisudoc-ocda-lib
+nix build
./result/bin/ocda-write --text <doc>.ssp
./result/bin/ocda-write --text <doc>.ocda.db de
./result/bin/ocda-write --md <doc>.ssp
@@ -35,10 +35,11 @@ nix build --override-input ocda-lib path:../../sisudoc-ocda-lib
./result/bin/ocda-write --typst <doc>.ocda.db en --out out/<doc>.typ
```
-The override applies to `nix develop` too, until the library is published:
+`flake.lock` pins the library at the commit this was checked against. In a
+development shell `gleam` reads it through the `./ocda-lib` symlink (below):
```sh
-nix develop --override-input ocda-lib path:../../sisudoc-ocda-lib -c gleam build
+nix develop -c gleam build
```
## The check
@@ -47,16 +48,16 @@ nix develop --override-input ocda-lib path:../../sisudoc-ocda-lib -c gleam build
./result/bin/ocda-write --text <doc>.ssp | cmp - <the D writer's>
```
-**36 of 36 document-languages, from both serialisations, byte identical to the
+**Every document-language, from both serialisations, byte identical to the
D writer** - which is the check that matters now, since byte identity with
`spine --text` is no longer the target.
And for `--md`, `--html`, `--epub` and `--typst`, **byte identical to the D
-writer on all 36**, which is the agreement that says the model is enough. None
-of them is held to spine's bytes: the epub's judge is epubcheck, which read the
-specification so that the writer need not be trusted to have, and the pdf's is
-typst, where a link to a label that does not exist is a compile error. See the
-repository README for what they do differently and why.
+writer on every document**, which is the agreement that says the model is
+enough. None of them is held to spine's bytes: the epub's judge is epubcheck,
+which read the specification so that the writer need not be trusted to have,
+and the pdf's is typst, where a link to a label that does not exist is a
+compile error. See the repository README for what they do differently and why.
## The library, as a path dependency inside the package
diff --git a/gleam/flake.lock b/gleam/flake.lock
index 13a94c9..a83226a 100644
--- a/gleam/flake.lock
+++ b/gleam/flake.lock
@@ -2,11 +2,11 @@
"nodes": {
"nixpkgs": {
"locked": {
- "lastModified": 1790652569,
- "narHash": "sha256-k8Fu4c9Z+4Nh7mUr0cfw++ITQiyEhlWxoJBOkI3tOcQ=",
- "rev": "b6c8664de9b6cc07fe5666a29f91884ba81197c4",
+ "lastModified": 1792506237,
+ "narHash": "sha256-hVMDyAXU0kxRuG3GygbZkzf5x+aBNEC0NYEJ6KwHtD4=",
+ "rev": "5adc50831c259f87faeb09ddf930d43597197473",
"type": "tarball",
- "url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.11pre1082290.b6c8664de9b6/nixexprs.tar.zst"
+ "url": "https://releases.nixos.org/nixpkgs/nixpkgs-26.11pre1097770.5adc50831c25/nixexprs.tar.zst"
},
"original": {
"type": "tarball",
@@ -16,11 +16,11 @@
"ocda-lib": {
"flake": false,
"locked": {
- "lastModified": 1791851051,
- "narHash": "sha256-mVI3uGQ1z7S5OMMFjl5UoWShE3p0ucXlr6cVU1iAsgI=",
+ "lastModified": 1791924842,
+ "narHash": "sha256-C79k2X32NxKPqrE7nJVegYThtA6Dm2pg/B/yb9RiObE=",
"ref": "refs/heads/main",
- "rev": "4e4f2f8c2b2c043077390cb4ccf7ce97ffe4ac6b",
- "revCount": 3,
+ "rev": "79a7a0cf09c9d6b5d9974376dcb7a98bd5bdbcba",
+ "revCount": 4,
"type": "git",
"url": "git://git.sisudoc.org/tools/sisudoc-ocda-lib"
},
diff --git a/gleam/flake.nix b/gleam/flake.nix
index c70f739..8f2d13c 100644
--- a/gleam/flake.nix
+++ b/gleam/flake.nix
@@ -57,7 +57,7 @@
*/
${name} = buildGleamApplication {
pname = "ocda-write";
- version = "2.0.0";
+ version = "2.1.0";
src = ./.;
localPackages = [ "${ocda-lib}/gleam" ];
rebar3Package = rebar3-pc;
diff --git a/gleam/gleam.toml b/gleam/gleam.toml
index 93880ca..bdbbac0 100644
--- a/gleam/gleam.toml
+++ b/gleam/gleam.toml
@@ -1,5 +1,5 @@
name = "ocda_write"
-version = "2.0.0"
+version = "2.1.0"
description = "sample writers over the object-centric document abstraction"
licences = ["AGPL-3.0-or-later"]
diff --git a/gleam/manifest.toml b/gleam/manifest.toml
index 8f22b12..5ad4848 100644
--- a/gleam/manifest.toml
+++ b/gleam/manifest.toml
@@ -14,7 +14,7 @@ packages = [
{ name = "gleam_regexp", version = "1.1.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_regexp", source = "hex", outer_checksum = "9C215C6CA84A5B35BB934A9B61A9A306EC743153BE2B0425A0D032E477B062A9" },
{ name = "gleam_stdlib", version = "1.0.5", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "CEE5B6C076A85B45F60C585F4316C63EC8B7127C119D5738C3958A9C4D50404E" },
{ name = "gleeunit", version = "1.11.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "EC31ABA74256AEA531EDF8169931D775BBB384FED0A8A1BDC4DD9354E3E21826" },
- { name = "ocda_lib", version = "2.0.0", build_tools = ["gleam"], requirements = ["argv", "gleam_json", "gleam_stdlib", "simplifile", "sqlight"], source = "local", path = "./ocda-lib" },
+ { name = "ocda_lib", version = "2.1.0", build_tools = ["gleam"], requirements = ["argv", "gleam_json", "gleam_stdlib", "simplifile", "sqlight"], source = "local", path = "./ocda-lib" },
{ name = "simplifile", version = "2.7.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "A2727627B063E87351934C7F7F008F2D1FDB16F6DE0B8C79F9E46459CFC9C164" },
{ name = "sqlight", version = "1.2.0", build_tools = ["gleam"], requirements = ["esqlite", "gleam_stdlib"], otp_app = "sqlight", source = "hex", outer_checksum = "841768D0A81107EE2DB46B949354F284A68B2E8098315C28A1FE3C07D206C17A" },
]
diff --git a/pipeline/README.md b/pipeline/README.md
index c5920f7..b5adc84 100644
--- a/pipeline/README.md
+++ b/pipeline/README.md
@@ -1,13 +1,13 @@
-# The pipeline: how to run the readers, the library and the writers
+# The pipeline: how to run the library, its reader and the writers
Fixed scripts rather than a test suite. They produce output that is meant to
be **looked at**, and they double as the answer to "what do I type?".
```
config.sh where everything is, and where the output goes
-build.sh build every reader, library and writer, in both languages
+build.sh build the library and the writer, in both languages
one.sh one tool, one document - the answer to "how do I run this?"
-read.sh every reader and both libraries, over every document
+read.sh the library and its reader, over every document
write.sh every writer, in both languages, over every document
pdf.sh compile the .typ files that write.sh produced
run.sh all of the above, in order
@@ -20,7 +20,7 @@ document-language and a `.ocda.db` for each document, and, where there is
one, a `.sisupod` beside it. That is what spine writes:
```sh
-spine --abstraction --ocda-db --pod2 --output=<dir> <pod>...
+spine --show-abstraction --ocda-db --pod2 --output=<dir> <pod>...
```
Everything downstream reads those files and nothing else. **No tool here
@@ -44,8 +44,6 @@ at something.
## Where the output goes
```
-$OUT/read/ssp-d/ ssp-g/ the .ssp readers' summaries
-$OUT/read/db-d/ db-g/ the .ocda.db readers' summaries
$OUT/read/dump-d/ dump-g/ the library's dump, from each serialisation
$OUT/write/text/{d,g}/ <doc>.txt
$OUT/write/md/{d,g}/ <doc>.md
@@ -70,8 +68,8 @@ sh pipeline/one.sh read-d <doc>.sisupod en --tree
The tool names are `<format>-<language>`: `text`, `md`, `html`, `epub`,
`typst` for the writers, `read` for the library's reader (ocda-read, which
-reads every form and takes its modes after the file), and `ssp`, `db`, `dump`,
-`agree` for the older readers and the library; `-d` for D and `-g` for Gleam.
+reads every form and takes its modes after the file), and `dump`, `agree` for
+the library; `-d` for D and `-g` for Gleam.
Output goes to stdout, so a comparison is a pipeline. The epub and the typst
name a file instead, because an epub is a zip and a `.typ` names its images by
@@ -86,7 +84,7 @@ typst compile --root d d/x.typ d/x.pdf
## What the counts at the end mean
Each stage prints a few numbers. They are not a pass, they are a way to see a
-regression without reading 36 documents.
+regression without reading every document.
| `all four dumps identical` | the library's whole claim: two serialisations, two languages, one model |
|---|---|
diff --git a/pipeline/build.sh b/pipeline/build.sh
index 72c9b11..6e1ef10 100755
--- a/pipeline/build.sh
+++ b/pipeline/build.sh
@@ -1,9 +1,10 @@
#!/usr/bin/env sh
-# Build every reader, every library and every writer, in both languages.
+# Build the library (with its reader, ocda-read) and the writer, in both languages.
#
-# Each project is its own flake and builds on its own. The library has no
-# public url yet, so the three that depend on it are given the local copy with
-# --override-input; that argument goes away when it is published.
+# Each project is its own flake and builds on its own. The writer's flakes lock
+# the published library; here they are given the copy at $OCDA_LIB with
+# --override-input, so that the library run and the library built into the
+# writer are the same one. Where that fails, the build falls back to the lock.
set -e
. "$(dirname "$0")/config.sh"
@@ -24,10 +25,6 @@ failed=0
# first, and the dump this pipeline reads was not there.
build "$OCDA_LIB/dlang"
build "$OCDA_LIB/gleam"
-build "$SSP_READER/dlang"
-build "$SSP_READER/gleam"
-build "$DB_READER/dlang"
-build "$DB_READER/gleam"
build "$WRITERS/dlang"
build "$WRITERS/gleam"
exit $failed
diff --git a/pipeline/config.sh b/pipeline/config.sh
index 04c4bfd..ef81ee9 100644
--- a/pipeline/config.sh
+++ b/pipeline/config.sh
@@ -18,12 +18,11 @@ WRITERS=${WRITERS:-$(cd "$(dirname "$0")/.." && pwd)}
# short name; where they sit relative to each other is the only local fact.
SIBLINGS=${SIBLINGS:-$(cd "$WRITERS/.." && pwd)}
OCDA_LIB=${OCDA_LIB:-$SIBLINGS/sisudoc-ocda-lib}
-SSP_READER=${SSP_READER:-$SIBLINGS/sisudoc-ssp-reader}
-DB_READER=${DB_READER:-$SIBLINGS/sisudoc-ocda-db-reader}
# the abstraction artefacts to read: a directory holding .ssp files, and for
# each of them a .ocda.db and, where there is one, a .sisupod beside it. This
-# is what spine writes with --abstraction --ocda-db --pod2; see pipeline/README.
+# is what spine writes with --show-abstraction --ocda-db --pod2; see
+# pipeline/README.
ARTEFACTS=${ARTEFACTS:-}
# where the output goes. One directory per stage, so a run can be looked at.
diff --git a/pipeline/one.sh b/pipeline/one.sh
index 55e9ca6..a018fec 100755
--- a/pipeline/one.sh
+++ b/pipeline/one.sh
@@ -7,8 +7,6 @@
#
# read-d read-g ocda-read, the library's reader of every form; takes its
# modes after the file: one.sh read-d <file> en --tree
-# ssp-d ssp-g the .ssp readers, D and Gleam
-# db-d db-g the .ocda.db readers
# dump-d dump-g the library's canonical dump of the whole model
# agree-d agree-g the library's two loaders against each other
# text-d text-g the writers. Each takes a .ssp, a .ocda.db or a
@@ -28,10 +26,6 @@ lang=${3:-}
case $tool in
read-d) shift; exec "$OCDA_LIB/dlang/result/bin/ocda-read" "$@" ;;
read-g) shift; exec "$OCDA_LIB/gleam/result/bin/ocda-read" "$@" ;;
- ssp-d) exec "$SSP_READER/dlang/result/bin/ssp-reader" "$file" ;;
- ssp-g) exec "$SSP_READER/gleam/result/bin/ssp_reader" "$file" ;;
- db-d) exec "$DB_READER/dlang/result/bin/ocda-db-reader" "$file" ;;
- db-g) exec "$DB_READER/gleam/result/bin/ocda-db-reader" "$file" ;;
dump-d) exec "$OCDA_LIB/dlang/result/bin/ocda-dump" "$file" $lang ;;
dump-g) exec "$OCDA_LIB/gleam/result/bin/ocda-lib" dump "$file" $lang ;;
agree-d) exec "$OCDA_LIB/dlang/result/bin/ocda-agree" "$file" $lang ;;
diff --git a/pipeline/read.sh b/pipeline/read.sh
index ddbebe4..451f725 100755
--- a/pipeline/read.sh
+++ b/pipeline/read.sh
@@ -1,10 +1,8 @@
#!/usr/bin/env sh
-# Every reader and both libraries, over every document, into $OUT/read/.
+# The library and its reader, over every document, into $OUT/read/.
#
# What each produces:
#
-# read/ssp-{d,g}/<doc>.txt the .ssp readers' summary
-# read/db-{d,g}/<doc>.txt the .ocda.db readers' summary
# read/dump-{d,g}/<doc>.ssp the library's dump, loaded from the .ssp
# read/dump-{d,g}/<doc>.db the same, loaded from the .ocda.db
# read/read-{d,g}/<doc>.ssp ocda-read --tree, reading the .ssp
@@ -17,7 +15,7 @@ set -e
. "$(dirname "$0")/config.sh"
: "${ARTEFACTS:?set ARTEFACTS to a directory of .ssp and .ocda.db files}"
mkdir -p "$OUT/read"
-for d in ssp-d ssp-g db-d db-g dump-d dump-g read-d read-g; do mkdir -p "$OUT/read/$d"; done
+for d in dump-d dump-g read-d read-g; do mkdir -p "$OUT/read/$d"; done
list=$(find "$ARTEFACTS" -name '*.ssp' | sort)
[ -n "$LIMIT" ] && list=$(echo "$list" | head -n "$LIMIT")
@@ -27,13 +25,9 @@ for ssp in $list; do
stem=$(basename "$ssp" .ssp); lang=${stem##*.}; uid=${stem%.*}
db=$(find "$ARTEFACTS" -name "$uid.ocda.db" | head -1)
n=$((n+1))
- sh "$(dirname "$0")/one.sh" ssp-d "$ssp" > "$OUT/read/ssp-d/$stem.txt"
- sh "$(dirname "$0")/one.sh" ssp-g "$ssp" > "$OUT/read/ssp-g/$stem.txt"
sh "$(dirname "$0")/one.sh" dump-d "$ssp" > "$OUT/read/dump-d/$stem.ssp"
sh "$(dirname "$0")/one.sh" dump-g "$ssp" > "$OUT/read/dump-g/$stem.ssp"
[ -n "$db" ] || continue
- sh "$(dirname "$0")/one.sh" db-d "$db" > "$OUT/read/db-d/$stem.txt"
- sh "$(dirname "$0")/one.sh" db-g "$db" > "$OUT/read/db-g/$stem.txt"
sh "$(dirname "$0")/one.sh" dump-d "$db" "$lang" > "$OUT/read/dump-d/$stem.db"
sh "$(dirname "$0")/one.sh" dump-g "$db" "$lang" > "$OUT/read/dump-g/$stem.db"
# the four-way agreement, which is the library's whole claim