docs: a page for every tool and every library, with real output

This commit is contained in:
funkpower
2026-09-19 13:09:20 -04:00
parent b0743d5bf7
commit 2e2988b1b1
20 changed files with 2162 additions and 66 deletions
+78
View File
@@ -0,0 +1,78 @@
# The contract
Every program here obeys all of this, or it does not ship. It is worth reading
once, because it is what lets these be used together without reading any of
them.
Back to [the index](README.md).
## One job
A tool that needs a `--mode` flag to change what it *is* is two tools.
## stdin to stdout
Input on stdin or a path argument, result on stdout, diagnostics on stderr
only — never content and chatter on the same stream. A tool that takes a path
instead of a stream says why in its `--help`; [`pdftriage`](pdftriage.md) does,
because it reads two specific page ranges rather than the whole file.
## Streams, not documents
Anything list-shaped is NDJSON: one [record](records.md) per line, flushed as
it is produced, so a slow stage never blocks the pipe behind it.
The reader is strict on purpose. It refuses a record whose version it does not
know, it stops at the first bad line rather than reading past a disagreement
about the format, and it bounds how much one line may cost — a filter pointed
at a binary file should fail, not allocate the file.
## Predicates answer with exit codes
| Code | Meaning |
|---|---|
| `0` | Yes, or done |
| `1` | No |
| `2` | Could not tell |
| `64` | The command line was wrong |
| `65` | The input was not what the tool can work on |
| `69` | A program it needs is not installed |
| `70` | The tool's own fault |
| `74` | Reading or writing failed |
The failure codes start where `sysexits.h` puts them so that "no" and "broke"
are never the same number. That is what makes this work:
```sh
for f in *.pdf; do pdftriage --quiet "$f" && ocrmypdf "$f" "ocr/$f"; done
```
A consumer closing the pipe is not a failure. `… | head -1` exits `0`, like
every other filter.
## No network, no database, no config file, no state
Two exceptions, both declared in `--help`:
- [`emb`](emb.md), whose whole job is an HTTP call.
- [`pdftriage`](pdftriage.md), which shells out to `pdftotext` and `pdfinfo`
and exits `69` when either is missing.
## No ambient knowledge
No hostnames, no local paths, no private vocabularies compiled in. General
scheme data — ISBN check digits, the HTML character references — may be;
anything local is a `--rules` file.
## Deterministic
Same bytes in, same bytes out, across runs and machines. No hash-order
dependence, no clock, no locale reads. Floats that JSON cannot carry are
refused where they are produced rather than written as `null` and lost.
## `--json` everywhere
The human-readable default is for a person at a terminal; `--json` is the
contract, and it does not change shape without a major version. Tools whose
only sensible output is a stream of records write that stream and have no
`--json` to add.