01 — Baseline (measured, 2026-09-14, HEAD 782f231)
1. What exists and is proven
| Measure | Value |
|---|---|
Crates on Kellnr (each .crate re-downloaded and byte-compared) |
16: apdf 0.1.0 (façade), apdf-cli 0.1.0, apdf-object 0.2.0, apdf-parse 0.2.0, apdf-filter 0.1.1, apdf-crypt 0.2.0, apdf-font/-write/-layout/-doc/-content/-conform/-render/-sign 0.1.0, apdf-fonts-std14 0.1.1, apdf-icc-profiles 0.1.1 |
ISO 32000-2 coverage ledger (docs/COUVERTURE-ISO32000.toml) |
293 rows: 252 implemented, 30 partial, 11 out-of-scope; no row left verified = false — every clause re-read in the sponsored ISO 32000-2:2020 EC3 text, 21 clause numbers corrected |
| Proof gate | cargo xtask prove all --include-ignored: 1 295 tests, 1 295 proven, 0 SKIPPED, no environment variable (corpus defaults to tests/corpus), from a clean worktree, ≈3 h at opt-level 3 |
| Consumption proof | fresh project ~/apdf-smoke on big-1: apdf = { registry = "kellnr" } only, zero path, 172 packages resolved from Kellnr; opens, extracts (= pdftotext), renders, validates PDF/A (rules = veraPDF) |
Reference texts registered (docs/REFERENCES.toml, 124 entries, 0 defects) |
ISO 32000-1:2008, ISO 32000-2:2020 + Errata Collection 3, ISO/TS 32001–32005, ISO 14289-1/-2, ISO/IEC 14496-22:2019, XFA 3.3, ITU-T T.4/T.6/T.81/T.88/T.800, ICC.1:2022, RFC 1951/7932, Adobe TN 5014/5099/5176/5177/5411, Adobe Supplements ExtLevel 3/5, PDF 2.0 AN 001–003, PDF/A TechNotes 0001–0010, Matterhorn 1.1, WTPDF 1.0, PDF Declarations, EA-PDF 1.0, Brotli extension, PRC WD (SC2 N570), ECMA-363, XFDF 3.0 + XSD, FDF, OGC GeoPDF, Arlington PDF Model, veraPDF profiles + sources, iTeh previews of 19005-1..4, 15930-1..9, 16612-2/3, 24517-1, 19444-1, 16684-1/2/4, 14739-1, IEC 61966-2-1, 12647-2 |
| Test corpora (outside the repo, never shipped) | pinned 1 949 (qpdf, pdfium, pdf.js, mutool) + PDFBox 193 + pdfcpu 511 + veraPDF 2 908 + Isartor 205 + Ghent Output Suite 98 + Cal Poly PDF/VT 12 + PDF/UA Reference Suite 16 + OpenJPEG conformance + UBC JBIG2 + ITU T.88 vectors + PngSuite + zlib infcover + UCD BidiTest |
| Independent oracles wired | qpdf 12.4, mutool 1.28, poppler 26.08 (pdftotext/pdftoppm/pdfimages/pdfinfo/pdffonts/pdfsig/pdfdetach), pdf.js 6.3 (pinned pdfjs-dist), veraPDF 1.30.2, Ghostscript 10.08, LittleCMS transicc, OpenJPEG 2.5, libjpeg-turbo, jbig2dec, libtiff, fontTools/ttx, CPython (zlib, stringprep, xml), OpenSSL 3.6 (cms/ts/pkcs12), pyHanko 0.37, pypdfium2 5.13, Arlington TestGrammar, fribidi, brotli(1), pdftk 3.3.3, xmllint |
| Upstream fixed by this program (Kellnr) | russl-codec-jpeg2000 0.9.3 (23/23 ISO/IEC 15444-4), russl-codec-jbig2 0.9.3 (96/96 pdf.js fixtures, UBC 65/65), russl-entropy-mq 0.9.1, russl-pkcs12 0.1.3 (RC2-40/3DES read), russl-rsa 0.1.7 (*_allow_legacy), russl-pades 0.1.2 (FieldMDP, xref-stream updates), russl-pdf 0.1.1, russl-cades 0.1.4 (unsigned attributes), russl-brotli 0.9.0 consumed |
2. Where we already beat a reference (measured, named)
- JBIG2: poppler wrong on 10 of the 96 pdf.js
bitmap-*fixtures, jbig2dec wrong on 1; we 96/96 (author's PBM as ground truth, pdf.jsjbig2.wasmas second witness). - CCITT G4
testfax4: poppler and mupdf fail on the same line; we bit-exact (libtiff agrees). - JPEG 2000: 23/23 ISO/IEC 15444-4 conformance codestreams (15 bit-exact, 8 within Tables C.6/C.7); no viewer claims this.
- Brotli: the pdf.js prototype whose xref and object streams are themselves Brotli opens with us; qpdf, poppler and mutool refuse it.
- Bidi: UAX #9 BidiCharacterTest 91 707/91 707, BidiTest 770 241/770 241 (UCD 17.0); fribidi 442/442 on corpus lines. No competing text extractor has this proof.
- PDF/UA glyph level: 8 rules veraPDF cannot trigger (e.g. 8.10.3.5-1 — its parser never builds semantic items for annotation appearances) are checked with negative controls.
- ISO/TS 32005: Table 5 generated from the text (1 190 pairs, pdf-issues #440/#336 applied); 59 pairs where veraPDF diverges from the text, listed.
- Huge pages: 12 608×16 806 pt page rendered in 936 MB / 30 s (pdftoppm 5.0 GB, mutool 6.9 GB).
- Prepress: PDF/X-5g, X-5pg, PDF/VT-2 written and verified; Cal Poly PDF/VT suite 12/12; reference XObjects (§8.10.4) rendered with substitution (poppler and mupdf ignore
/Ref). - Encryption: R2–R6, AES-GCM (TS 32003), public-key with RC2-40/3DES PKCS#12 keystores read and downgrade named (
KeyStrength::Legacy{bits}) where other readers stay silent; TS 32004/AttachedToSigverified (pyHanko agrees). - Colour:
/Default*spaces and output intents applied (poppler never applies the intent; gs-dUsePDFX3Profileagrees with us to the pixel); DeviceCMYK→RGB per §10.4.2.5 (1−min(1,c+k)) where the ported code had(1−c)(1−k); 67 free ICC profiles shipped, 804 conversions at max Δ1 vs LittleCMS.
3. What is missing (honest)
- Ledger rows
absent:fdf,xfdf,pdf-declarations,pdfraster,ea-pdf;partial(30): pdfa-2/3/4, pdfx-1a/3/4/5/6, pdfvt-1-2/3, crypt-public-key (ECDH, 3DES/RC2 content), filter-brotli (RFC 9841 large window), associated-files, transparency-colour-issues, ts-32001/32002/32004 (write side, blocked on russl-pades), conformance-processors, damaged-file-recovery, filter-predictors, layout-hyphenation, xfa-forms. - No binding outside Rust. No published performance figures (lane interrupted). No coverage-guided fuzzing yet (lane interrupted). CJK without embedded font not drawn (Noto/Source Han decision pending). Truncated DCT not painted (poppler/mupdf paint the prefix). No OCR. No Office conversion. No smartcard/token signing path exposed in
apdf-sign(RUSSL/libcps-rs exist upstream; nothing generic here). - Paid ISO texts not acquired (≈18 documents, ~150–260 € each): 19005-1/2/3/4, 15930-1/3/4/6/7/8/9, 16612-2/3, 24517-1, 19444-1, 16684-1/2, 14739-1, IEC 61966-2-1, 12647-2 — see
06-decisions.mdD-2. - Upstream branches not merged (shared trees are held by other sessions): RUSSL
fix/cms-interop-and-crl-signing(lane G),lane-r-pkcs12-rsa(lane R); CODECSlaneM-jbig2-2026-09-13,laneY-jpx-2026-09-13, jpeg2000 commits of lane F onargon-full-corpus-2026-08-16. - Shared checkout on big-1: normalised 2026-09-14 (stale index reset to HEAD, 59 stale files restored, 9 rustfmt-churn files restored); 34 files of uncommitted work mixed with old bases remain — the lane worktrees are the source of truth (see
05-battle-order.mdPhase 0), not the shared tree. - The tree is not rustfmt-clean at HEAD (3 774 blocks): to be formatted in one commit when no lane is active.