ASKLERA PDF — Roadmap

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.js jbig2.wasm as 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 /AttachedToSig verified (pyHanko agrees).
  • Colour: /Default* spaces and output intents applied (poppler never applies the intent; gs -dUsePDFX3Profile agrees 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.md D-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); CODECS laneM-jbig2-2026-09-13, laneY-jpx-2026-09-13, jpeg2000 commits of lane F on argon-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.md Phase 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.
Source: docs/roadmap/01-baseline.md · big-1 · 2026-09-14 18:00 UTC